Skip to content
Console

Get started

Conventions

Copy page

How every endpoint writes times, credits, durations, ids and lists, how it pages, and what null and an absent field mean.

Every endpoint — and the agent’s WebSocket — writes its values the same way. Learn these once and every response reads alike.

Every field, query parameter, enum value and error code is snake_case, in every response and in the SDKs’ types: what the reference shows is what you send and what you get back.

A quantity carries its unit in its name: duration_seconds, size_bytes, credits_micros, expires_in_seconds. A field naming a moment ends in _at. A reference to another resource is <thing>_id.

A moment is an ISO 8601 string in UTC, always with three fractional digits and a Z:

An instant
{ "created_at": "2026-10-24T09:30:00.000Z" }

It is exactly what JavaScript’s Date.prototype.toISOString() writes, so new Date(value) reads it and toISOString() gives the same text back. A calendar day is YYYY-MM-DD, in UTC.

A time you send — since and until on a listing, an expiry — needs its zone, Z or an offset such as +02:00. A time without one is ambiguous, and is refused with a 422.

An amount of credits is an integer of micro-credits: one credit is 1000000. Every such field ends in _micros:

A balance
{ "credit_balance_micros": 2500000 }

That is 2.5 credits. Integers add and compare exactly, so sum them as they come and divide by a million only to show a person. You send amounts the same way — an ephemeral key’s credit_limit_micros is an integer.

Every list answers one shape:

A page
{
"data": [{ "id": "…" }, { "id": "…" }],
"next_cursor": "eyJrIjoiZ2VuZXJhdGlvbnMi…"
}

Ask for a page size with limit, and for the next page by passing next_cursor back as cursor. On the last page next_cursor is null:

curl
curl "https://api.lumavox.ai/v1/generations?limit=50&cursor=eyJrIjoiZ2VuZXJhdGlvbnMi…" \
-H "Authorization: Bearer $API_KEY"
  • A cursor is opaque: pass it back unchanged, to the list that gave it. One it cannot read is a 422, never the first page again.
  • Lists do not count their rows: there is no total. Page until next_cursor is null.
  • A list that is small by nature — your agents, the voices, the templates — answers the same shape with next_cursor always null.
  • A list inside a resource — a session’s messages — is the same shape, as a field.

A response always has every field its schema names. null means “none”: a key that was never used has "last_used_at": null, never a missing field.

In a request, a field you leave out takes its default when you create something, and stays as it is when you update it. null clears a field that may be empty.

A request body may hold only the fields its endpoint knows: an unknown one — a typo such as voiceId for voice_id — is a 422 naming it, rather than being dropped for its default.

Every resource’s id is a string the API made: a prefixed id such as gen_a1B2c3D4e5F6g7H8 for generations, assets, folders, voices, end users, templates and requests, and a UUID for agents, sessions, knowledge entries and keys. Treat it as opaque: send it back as you got it, and do not parse it.

A field with a fixed set of values — a status, a kind, an error code — names its values in the reference. A set may grow: handle a value you do not know, rather than failing on it.