Getting Started
API conventions
Pagination, identifiers, timestamps, idempotency, and the response envelope — the rules every endpoint follows.
Every endpoint in the OnCore Core API follows the same handful of rules. Learn them once here and the rest of the reference reads as a list of shapes.
The response envelope#
Every JSON response — success or failure — has the same three top-level keys.
{
"success": true,
"data": { "…": "…" },
"metadata": {
"timestamp": "2026-07-30T12:00:00.000Z",
"version": "1.0",
"path": "/assistants"
}
}data carries the payload, metadata carries request context, and success tells you which branch you are on. On failure, error replaces data — see Errors.
Two deliberate exceptions
The embed-facing endpoints — POST /webrtc-call/connect and the /web-chat/* routes — return bare JSON with no envelope, and a fixed { "error": "not_found" } body on 404. That is intentional anti-enumeration behavior, explained in Errors.
Pagination#
List endpoints take limit and offset query parameters.
| Parameter | Type | Description |
|---|---|---|
limit | integer | Page size. Default 50, maximum 500. |
offset | integer | Number of items to skip. Default 0. |
curl "https://core-api.heysadie.ai/assistants?limit=25&offset=50" \
-H "Authorization: ApiKey YOUR_API_KEY"List responses carry the page in a named array plus a total count, so you can tell when you have reached the end:
{
"success": true,
"data": {
"assistants": [{ "…": "…" }],
"total": 128
}
}Walk a full collection by advancing offset until you have seen total items:
const base = "https://core-api.heysadie.ai";
const headers = { Authorization: `ApiKey ${process.env.ONCORE_API_KEY}` };
const all = [];
let offset = 0;
while (true) {
const res = await fetch(`${base}/assistants?limit=500&offset=${offset}`, { headers });
const { data } = await res.json();
all.push(...data.assistants);
offset += data.assistants.length;
if (all.length >= data.total || data.assistants.length === 0) break;
}Offset pagination is not a stable snapshot
Items created or deleted while you page will shift the window, so a long walk can miss or repeat rows. For a consistent view, page quickly and reconcile by id rather than assuming each page is disjoint.
Identifiers#
Every resource is identified by a UUID, and IDs are stable for the lifetime of the resource.
0195f1e2-1111-7000-8000-000000000000IDs are opaque: do not parse them, derive meaning from them, or assume ordering. Placeholders in these docs use the 0195f1e2-… prefix so they are obviously not real.
Timestamps#
All timestamps are ISO 8601 in UTC, with milliseconds:
2026-07-30T12:00:00.000ZSend timestamps in the same format. Parse them with a real date library rather than string slicing — the API may add offsets in future.
Phone numbers#
Phone numbers are always E.164: a leading +, country code, no spaces or punctuation.
+15555550123A number in any other format is rejected with VALIDATION_ERROR.
Content type#
Send Content-Type: application/json on every request with a body. The one exception is document upload, which also accepts multipart/form-data — see the Documents API.
Idempotency#
The API does not currently expose an idempotency-key header. Design your integration accordingly:
PATCHandPUTare naturally idempotent — replaying them converges on the same state.DELETEis idempotent in effect; deleting an already-deleted resource returnsRESOURCE_NOT_FOUNDrather than failing destructively.POSTis not. Retrying a create after a timeout can produce a duplicate. Guard it by recording your own request key before the call and reconciling with aGETlist filtered bysearchbefore you retry.
TODO — verify
Confirm with the API team whether an Idempotency-Key header is planned. If one ships, this section and the retry guidance in Rate limits should be rewritten around it.
Unknown fields#
Treat responses as open: the API may add fields to any object without a breaking change. Deserialize permissively and ignore keys you do not recognize rather than failing on them. See Versioning for what does and does not count as breaking.
Next#
- Rate limits — what to expect under load, and how to back off.
- Versioning — how the API changes, and what is guaranteed.
- Errors — the error envelope and every code it returns.