> For the complete documentation index, see [llms.txt](https://developers.tix.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers.tix.xyz/integration-guides/api-basics.md).

# API conventions

These conventions apply whether you use the TypeScript SDK or direct HTTP requests. Use the **API** sidebar for each endpoint's exact schema and required permissions.

## Pagination

The upcoming-events and active-listings endpoints return `items` and `next_cursor`.

1. Request the first page with a `limit` and any filters, without a cursor.
2. Process the returned `items`.
3. If `next_cursor` is not null, pass it as the next request's `cursor`, keeping the same filters.
4. Stop when `next_cursor` is null, not when `items` is empty; a page can be empty with more to follow.

Treat cursors as opaque strings. For direct HTTP, URL-encode the `cursor` query parameter. Active listings are not sorted by price.

With an authenticated SDK `client`:

```typescript
let cursor: string | undefined;

do {
  const page = await client.indexer.listUpcomingEvents({ limit: 10, cursor });
  for (const event of page.items) {
    // Process the event.
  }
  cursor = page.next_cursor ?? undefined;
} while (cursor !== undefined);
```

Inventory can change while you page through it; revalidate before checkout.

## Identifiers and amounts

* Keep 64-bit integer values as decimal strings. JavaScript `number` cannot represent all unsigned 64-bit integers exactly.
* Preserve API field names: a response can expose `event_id` while a request filter expects `eventId`.
* Handle nullable indexed fields explicitly. Do not turn a missing identifier into `"null"` or a made-up value.
* Keep `ask_price_minor` as an exact integer amount. Prices are USDC minor units; format them with `usdc_decimals` from the protocol config.

For arithmetic in JavaScript, use `BigInt` or a decimal library. Convert values back to decimal strings before JSON serialization; `JSON.stringify` does not serialize `BigInt`.

## Errors and retries

The SDK throws on failed requests. Direct HTTP callers should inspect the HTTP status as well as the response body.

* **401:** fix the key or environment; don't retry unchanged credentials.
* **403:** fix permissions or operation-specific authorization.
* **Other client errors:** correct the request against the endpoint schema before retrying.
* **429:** honor `Retry-After` when supplied and reduce request frequency.
* **Transient server or network errors:** retry read-only requests with bounded exponential backoff and jitter.

Do not log API keys, authentication headers, or private claim URLs.

## Idempotency and purchase status

A retry of a read is different from a retry of a purchase. A timeout does not prove that a purchase failed; the server may have accepted it before the connection was lost.

Purchases and signing requests take an `idempotency-key` header of 1 to 255 characters.

* Persist the key with your order before the first attempt, and reuse it for retries with the same payload. Don't generate a new key because a request timed out.
* Look up a purchase with the same key through `GET /claim_wallets/purchase-status`.
* Inspect the returned status before marking an order complete; HTTP 200 alone is not proof of confirmation.

See [Track the outcome](/integration-guides/secondary-resale.md#track-the-outcome) for the status values.
