Response shape
The shapes every Dairo response uses: a single object, a list under data, one-time secrets on create, and predictable delete responses.
Every Dairo response comes back in one of a few predictable shapes. Learn them once and you can read an endpoint you have never called before, with no surprise wrapper keys to special-case.
A single object
When you fetch one thing, you get that thing back with an object field naming its
type:
The object field is always present, and it always names the type: message, thread,
domain, inbox, webhook, api_key, template, audience, audience_member,
contact, contact_handle, agent, event, and so on. Branch on object whenever you
handle a value whose type you do not already know.
The type name is channel-neutral. An inbound reply, an outbound send, and an internal
agent-to-agent hop are all object: "message"; the channel field
says how each one traveled.
A list
Every collection uses one shape: object: "list", the items under data, and a
pagination block. This holds for a full collection, a filtered result, a single item,
or an empty result.
Each item in data is a full object with its own object field. The pagination block
carries nextCursor (a string, or null on the last page) and hasMore (a boolean).
Smaller collections that fit in one response return nextCursor: null and
hasMore: false. To walk a large list, see Pagination.
Objects that carry a nested collection
A few detail endpoints return the base object plus a related collection, inlined as a
field. It is still one object with one object field:
- A thread detail carries its
messages. - A template detail carries the resolved
version. - An audience detail (
GET /v1/audiences/{id}) carries itsmembers, each anobject: "audience_member". - A contact detail carries its
handles, each anobject: "contact_handle". - An outbound message carries its delivery
events, newest first; the same timeline is also a list atGET /v1/messages/{id}/events.
Create responses and one-time secrets
A create returns the new object flat, with its object discriminator, at 201. When the
create mints a secret, the secret rides on the object as a field, alongside
secretShownOnce: true:
The field name depends on the resource: a webhook returns its signingSecret
(whsec_…), an API key returns its secret (dairo_live_… or dairo_test_…). The value
is shown once, at creation, and never returned again. Capture it immediately.
Status codes and deletes
The response shape pairs with predictable HTTP status codes:
| Operation | Status | Body |
|---|---|---|
Create a resource (POST /v1/inboxes, /domains, /webhooks, /api-keys, /audiences, /templates, /agents, /buckets, a bucket's share links and bundles, /phone/calls, /phone/numbers) | 201 | the created object |
Read or update (GET, PATCH, PUT) | 200 | the object, or a list |
Send or action POST (send a message, broadcast to an audience, start an upload, replay events, enqueue an erasure job, verify, cancel) | 200 or 202 | the resulting object |
Delete (DELETE /v1/{resource}/{id}) | 204, or 200 | empty, or the object it changed |
A message send returns 200, whether it goes out immediately or is scheduled;
broadcasting to an audience returns 202, since Dairo expands and delivers it in the
background. Deletes return 204 with no body. Three report what they changed and
return 200 instead: deleting an agent passport returns the passport with
deleted: true, clearing an agent's reputation returns the reset state, and releasing
a phone number returns the number with status: "released".
Errors
Errors use their own shape, { "error": { "type", "code", "message", "param" } },
covered in full on the Errors page.