API Conventions
One section captures the rules that apply across every Throttle endpoint: naming, error shapes, pagination, idempotency, and workspace environments. When in doubt, this page wins over the per-endpoint docs.
Field naming: camelCase, single shape
Every request and response field on the wire is camelCase. One name per concept — no aliases, no alternate forms. Type generation from the OpenAPI spec is the intended workflow.
// POST /api/v1/carts request body
{
"applicationId": "e7efb0a6-892e-46b2-97ab-296bb04c5b29",
"currency": "USD"
}// POST /api/v1/carts response
{
"data": {
"id": "9f6e...",
"workspaceId": "6659b411-9cd7-40ac-9a73-1e7801d89f55",
"applicationId": "e7efb0a6-892e-46b2-97ab-296bb04c5b29",
"currency": "USD",
"netN": null,
"lineItems": []
},
"meta": {
"requestId": "..."
}
}applicationId, customerId, lineItems, unitPrice, and externalId; stale snake_case or store aliases are rejected with a validation error. Generated api-client@1.3.0+ already uses the current shape.Historical store terminology may still appear in dashboard labels or internal database migrations, but it is not exposed on the public wire.
Errors
Every non-2xx response follows the same envelope:
{
"error": {
"code": "missing_application_id", // stable, machine-readable
"message": "applicationId is required", // human-readable
"details": [ // optional, field-level
{ "field": "applicationId", "code": "required", "message": "Required" }
]
}
}error.code is the contract — use it for programmatic handling. Reach for error.message only for surfacing a human-readable string in your UI. Field-level details identify unrecognized keys and may include a suggestion when the server can identify the intended canonical camelCase field:
{
"error": {
"code": "validation_error",
"message": "Request body validation failed",
"details": [{
"path": "",
"code": "unrecognized_keys",
"message": "Unsupported field(s): unexpectedField",
"received": ["unexpectedField"]
}]
}
}Pagination
List endpoints accept ?limit + ?cursor and return:
{
"data": [...],
"meta": {
"pagination": {
"cursor": "<opaque>", // pass back as ?cursor= to fetch next page
"hasMore": true,
"limit": 25
}
}
}When hasMore is false, cursor is null. You can use if (cursor) as a "more pages?" check without re-reading hasMore.
Identifier prefixes
Resource ids are UUID v7 strings. API keys, embed tokens, and session ids carry a short prefix that encodes their type and, for keys, the workspace environment slug:
sk_<environment-slug>_*— secret key for one workspace environment.pk_<environment-slug>_*— publishable key for one workspace environment.sk_production_*andpk_production_*— production environment keys.whsec_*— webhook signing secret.