Install the package
Add the SDK to your Go module with go get.
go get github.com/lix-url/go-sdk/lix
Official Go SDK for the Lix.li URL shortening and link analytics API. Zero external dependencies. Create short links, manage groups, and track clicks with idiomatic Go using structs, errors, and optional pointer types.
package main import ( "fmt" "log" "github.com/lix-url/go-sdk/lix" ) func main() { client := lix.NewClient("lix_live_xxx") result, err := client.Links().Create("https://example.com", nil) if err != nil { log.Fatal(err) } fmt.Println(result.Link.ShortURL) // https://lix.li/a3b7k2 fmt.Println(result.Usage.Remaining) // 42 }
Built with standard library only, zero external dependencies. Idiomatic Go with structs, errors, and optional pointer types.
Create, get, update, delete, and list short links. Full CRUD with typed structs. Optional pointer types for nil-able fields.
Organize links into groups. Create rotating groups for A/B testing landing pages. Full CRUD with struct responses.
Fetch account profile, plan details, and real-time usage limits for links, API links, and mass links.
Standard library only. No external dependencies. Small footprint, zero supply chain risk.
6 dedicated error types wrapping a base LixError. Use errors.As() for precise error matching with validation data.
Inject any net/http-compatible client via the HTTPClient interface. Set timeouts, proxies, or mock for testing.
Pure Go with no external dependencies. Works with the standard library from Go 1.22+.
Add the SDK to your Go module with go get.
go get github.com/lix-url/go-sdk/lix
Pass your API key. Optionally inject a custom HTTPClient for timeouts, proxies, or testing.
import "github.com/lix-url/go-sdk/lix" client := lix.NewClient("lix_live_xxx") // With custom HTTPClient httpClient := &http.Client{Timeout: 10 * time.Second} client := lix.NewClient("lix_live_xxx", httpClient)
Shorten a URL and get back a typed LinkShortenResult with the short URL and usage info.
Create short links with custom aliases, UTM parameters, tracking pixels, password protection, and expiration dates. Every operation returns a typed struct.
// Create a basic link result, err := client.Links().Create("https://example.com", nil) fmt.Println(result.Link.ShortURL) // With custom alias and UTM opts := lix.NewCreateLinkOptions() opts.Alias = strPtr("my-link") opts.Title = strPtr("My Page Title") opts.Tags = []string{"sale", "promo"} opts.UTM = map[string]string{ "utm_source": "google", "utm_medium": "email", "utm_campaign": "summer", } opts.TrackingPixelIDs = []int{1001, 1002} opts.IsPublic = true result, err := client.Links().Create("https://example.com", opts) // Password protection + expiration opts := lix.NewCreateLinkOptions() opts.Password = strPtr("secret123") opts.ActiveBeforeDatetime = strPtr("2026-12-31T23:59:59+00:00") result, err := client.Links().Create("https://example.com", opts) func strPtr(s string) *string { return &s }
Pagination example:
client.Links().List(&limit, &fromID)
returns the next batch with ResponseMeta containing total count and next URL. Pass nil for API defaults.
Groups help you categorize links by campaign, team, or project. Rotating groups enable A/B testing by distributing traffic across multiple links.
// Create a regular group group, err := client.Groups().Create("Marketing", nil, false) fmt.Println(group.Name, group.URL) // Create a rotating group for A/B testing group, err := client.Groups().Create( "Landing Pages", strPtr("Rotating pages"), true, ) // Update group group, err := client.Groups().Update( 10, nil, strPtr("Updated description"), false, ) // List with pagination limit := 10 page, err := client.Groups().List(&limit, nil) for _, g := range page.Groups { fmt.Println(g.Name, g.URL) } fmt.Println(page.Meta.Total)
Fetch your profile, plan, and real-time usage limits — all returned as nested structs with full JSON tag mapping.
profile, err := client.Profile().Me() if err != nil { log.Fatal(err) } // Account info fmt.Println(profile.Client.Name, profile.Client.Email) fmt.Println(profile.User.Email) // Plan details fmt.Println(profile.Plan.Name, profile.Plan.EndDatetime) // Usage limits if profile.Usages.Links.Remaining != nil { fmt.Println(*profile.Usages.Links.Remaining) } fmt.Println(profile.Usages.APILinks.Used) fmt.Println(profile.Usages.MassLinks.Limit)
Organization and account metadata.
Authenticated user information and account details.
Current subscription and billing period.
Links, APILinks, MassLinks — each with Limit (*int), Used (int), Remaining (*int)
Catch exactly what you need with errors.As(). All errors wrap LixError. ValidationError includes the full field-level error data in Data.
import "errors" result, err := client.Links().Create("invalid-url", nil) if err != nil { var ve *lix.ValidationError var notFound *lix.NotFoundException var unauth *lix.UnauthorizedError var rateLimit *lix.RateLimitError var server *lix.ServerError switch { case errors.As(err, &ve): // Field-level validation errors fmt.Println("Validation:", ve.Data) case errors.As(err, ¬Found): fmt.Println("Not found") case errors.As(err, &unauth): // Invalid API key case errors.As(err, &rateLimit): // Too many requests case errors.As(err, &server): // 5xx server error default: // Generic Lix or network error log.Fatal(err) } }
400 — Invalid input. Access Data for field errors.
401 — Invalid API key or missing auth.
404 — Link or group not found.
429 — Rate limit exceeded.
500 — Unexpected Server-side error.
Network / transport failure.
All errors wrap LixError, which implements error. Use errors.As() for type-safe matching. Catch the base LixError for any SDK error, or target specific types for granular handling.
The same clean API, idiomatically implemented in your language of choice.
Install the SDK, get your API key, and start creating short links in under a minute.