Skip to main content
Every example on this page has a Go, Python, and TypeScript tab. Pick a language once and every code block on the page switches to it. For what the SDKs share and which one to pick, see the SDK overview.
The SDKs authenticate with an API key that can read and write your whole environment. Call them from server code only, even though the TypeScript SDK also runs in browsers. See Harden client-side access.

Installing the Flexprice SDK

Creating an SDK client

The server URL is the full base URL including /v1, with no trailing slash. Use https://api.cloud.flexprice.io/v1 for tenants in the India region.
  • Go: omit WithServerURL, or pass an empty string, to use the default US region. flexprice.WithServerIndex(1) picks the India region from the spec’s server list.
  • Python: the client is also a context manager. with Flexprice(server_url=..., api_key_auth=...) as client: closes the underlying HTTP connection pool on exit.

Creating a customer and sending usage events with the SDK

Ingestion answers 202 Accepted with {"event_id": "...", "message": "..."}. Go exposes it as resp.Object, and Python and TypeScript return it as a plain map. The event is metered asynchronously, so a successful call means “queued”, not “counted”. Use the Event Debugger to confirm how it aggregated.

SDK field names and optional values

  • Field names. The API uses snake_case. Go uses PascalCase fields (ExternalID) and TypeScript uses camelCase fields (externalId), and both convert on the wire. Python keeps snake_case keyword arguments.
  • Optional fields in Go. Required fields such as ExternalID and Name are plain Go values, and maps such as Metadata are plain Go maps. Optional scalar fields are pointers. The package ships flexprice.String, flexprice.Int64, flexprice.Bool, and flexprice.Pointer so you do not write &s everywhere.
  • Nil-safe getters in Go. Response structs expose getters, so resp.GetCustomerResponse().GetID() is safe even when a parent is nil.

Sending usage events in bulk with the SDK

For backfills or batching, send up to 1000 events per call. Each item takes the same fields as a single event:

Batching events with the Go async client

For services that emit many events per second, the Go SDK has an async client. It queues events in memory and sends them from a background goroutine, in batches of BatchSize or every FlushInterval:
Enqueue takes map[string]interface{} properties and converts the values to strings on the wire. EnqueueWithOptions takes a flexprice.EventOptions when you need EventID, Timestamp, or Source:
BatchSize, FlushInterval, MaxQueueSize, MaxConcurrentRequests, and Debug are fields on the config. Always call Close() before the process exits or the last batch is lost.

Async calls in the Python SDK

The Python client also works as an async context manager, and every method has an _async twin:
Use the async client inside FastAPI, aiohttp, or any event loop so ingestion does not block request handling. TypeScript methods already return promises and need no separate client.

Idempotent requests with the SDK

Idempotency lives in the request body, on the endpoints that support it. Invoices, credit notes, wallet top-ups, portal payments, and checkout sessions take an idempotency_key field. Send the same key on a retry and the API does not create a second object: invoices and credit notes return the original, and a wallet top-up answers 409 Conflict:
For other creates, rely on the natural key. A second customer with the same external ID returns 409 Conflict, so a retried create can be treated as success. Events dedupe on their event ID. The Go package also exports WithIdempotencyKey, which sets an Idempotency-Key request header. The API does not read that header, so it does not make a call safe to retry on its own.

Handling SDK errors

API errors carry the HTTP status code, so you can branch on it:
  • Go: use the errorutils helpers for a quick status check, or errors.As for the typed error.
  • Python: FlexpriceError is the base class. errors.ErrorResponse carries a parsed API error body, and errors.NoResponseError means the request never got an HTTP response.
  • TypeScript: non-2xx responses throw. FlexPriceError is the base class and carries statusCode, body, headers, and rawResponse.

Retrying failed SDK requests

Retries are off by default in every SDK. Pass a retry config to the client and it retries 429, 500, 502, 503, and 504 responses with exponential backoff, plus connection errors when that flag is set. Intervals are in milliseconds:

Paginating list endpoints with the SDK

List methods take a limit and an offset. The offset in the response’s pagination is already advanced to the next page. In Go, the list sits behind GetListCustomersResponse():

Parsing webhook payloads with the SDK

Every SDK ships a typed model for each webhook payload. Read event_type, then parse the body into the matching model. Verify the signature before parsing: see Signature verification.
In TypeScript, each payload’s fromJSON helper returns a SafeParseResult, so check .ok before reading .value.

Standalone functions in the TypeScript SDK

Every TypeScript method is also exported as a standalone function that takes a FlexpriceCore instance. Unused functions tree-shake out of the bundle, and the functions return a Result instead of throwing, which suits serverless and edge code:

TypeScript compiler settings for the SDK

Target ES2020 or newer so the SDK’s async iterables and streams compile without polyfills:

SDK troubleshooting

Go SDK source

Python SDK source

TypeScript SDK source