Skip to content

Resources

FAQ

Short answers to the questions developers ask in their first week, each pointing at the page that carries the detail.

These are the questions that come up in the first week of building against the Core API. Each one gets the short answer here, plus the page that treats it properly. Where the docs leave a question open, this page says so instead of filling the gap.

Keys and access#

Is there an SDK?#

No. There are no official client libraries in the current public developer surface. The API is plain REST over HTTPS with JSON, so fetch, requests, or curl is all you need, and the public OpenAPI document can generate a typed client. The maintained boundary is in Capabilities and availability.

How do I authenticate a request?#

Send your key in the Authorization header using the ApiKey scheme (Authorization: ApiKey YOUR_API_KEY). Not Bearer, not the bare key, not X-Api-Key; the wrong scheme is the single most common cause of a 401. See Authentication.

What is the difference between a tenant key and an organization key?#

A tenant key is scoped to one tenant and knows which one, so it needs no extra headers. An organization key can act on any tenant the organization owns but cannot infer which you mean, so every tenant-scoped request must name it with X-Tenant-Id. The exceptions are the endpoints that act on the organization itself: the org-level audits, transcriber testing, and reads of the transcriber catalogue. See Authentication and Organization-level access.

Where do keys come from, and what happens when I rotate one?#

They are viewed, generated and rotated on the API Keys page of your dashboard. Rotation invalidates the previous key immediately and there is no rollback, so update your integration in the same breath. See API keys.

Is the client server secret an API key?#

No, and it will never authenticate a request. It is the inbound credential you check webhook deliveries against; it just happens to live on the same page as your API keys. See Webhooks overview.

Building an assistant#

How do I get a phone number?#

Search the provider inventory with GET /phone-numbers/available, purchase one with POST /phone-numbers, then set phoneNumberId on the assistant that should answer it. Numbers are billed from purchase until you release them. See Phone numbers, or the Quickstart for the whole sequence end to end.

Can one assistant handle both voice and text?#

Yes. The assistant assigned to a number answers dialled calls, browser calls, web chat on your site, and (once the channel is enabled) inbound SMS. One configuration, every channel. Two things to know: enabling the SMS channel requires a linked Twilio number, and WhatsApp support is calling rather than typed chat.

How do I make the assistant answer from my own content?#

Upload the text once to your document library, then attach it to whichever assistants should answer from it. The document and the attachment are separate resources, and each attachment has its own enabled flag, so you can switch one assistant off without touching the others. See Knowledge base.

The assistant ignores an instruction I just changed. Why?#

Two likely reasons, and neither is the model. Configuration is read when a call starts, so a call already in progress keeps what it began with. Place a new call to test a change. And several surfaces reach the same conversation and compose rather than replace: developerPrompt, a shared prompt, up to six custom instructions, and linked task groups. List all of them before editing any. See Calls and assistant behavior.

Can I place an outbound call from the API?#

No. The calls API is read-only: a call record appears when someone dials a number you own, and these endpoints only read the results. See Calls.

Results and webhooks#

Where do I see what happened on a call?#

Two routes to the same record. GET /calls and GET /calls/{id} carry the transcript, summary, analysis and recording link; the end-of-call report pushes them to your server the moment the call ends. Take the webhook. If you are polling the calls list to find out when a call finished, that is the single biggest saving available to most integrations. See Calls.

How do I test webhooks locally?#

Tunnel your local port to a public HTTPS address, point one assistant's serverUrl at it, and place a call. From there you can read each delivery byte for byte and replay it instead of calling again. Put the assistant back when you are done, because an override left pointing at a dead tunnel loses deliveries that are never retried. See Receive webhooks on localhost.

How do I know a delivery really came from OnCore?#

There are two models. Voice, messaging and tool events carry your client server secret verbatim in the x-sadie-core-secret header and are delivered once, with no retries. WhatsApp onboarding events are HMAC-signed over the raw request body and retried up to five times, so verify them before parsing and dedupe on the delivery id. See Webhooks overview.

What happens when a transfer is not answered?#

It depends on the mode. After a cold or warm transfer the call has already left OnCore, so a ring-out is your telephony system's behavior and nothing OnCore can recover. Warm-return is the mode with the safety net: the caller comes back to the assistant, hears wording you set, and the conversation continues. That includes when an answering machine picks up, which warm-return detects and treats as a miss. Be careful with the reporting though: supervisor_answered records whether the call connected, and voicemail connects, so it reads true even when the caller was returned. See Transfers.

Where do text conversations show up?#

Not in the calls API. Web chat, SMS and WhatsApp threads are conversations, read through GET /conversations, and each finished thread delivers an end-of-conversation report. See Conversations.

Limits and change#

What are the rate limits?#

OnCore does not publish numeric limits for the Core API today. The only documented 429s are two WhatsApp onboarding endpoints, each carrying its own cooldown field. Write the client that survives a limit anyway: exponential backoff with jitter, and no blind retry of a POST. See Rate limits for the exact public contract and retry guidance.

Is there an idempotency key?#

Not currently. PATCH and PUT converge on the same state when replayed and DELETE is idempotent in effect, but POST is not. A retry after a timeout can create a duplicate, so reconcile with a filtered GET before retrying. See API conventions.

Will my client break when the API changes?#

Not if you write it to tolerate growth: ignore fields you do not recognize, branch on error.code rather than error.message, treat IDs as opaque, and do not depend on ordering an endpoint has not promised. OnCore does not currently publish a guaranteed deprecation window, so monitor What's new and follow the compatibility rules in Versioning & stability.

Why does a resource I can see in the dashboard return 404?#

RESOURCE_NOT_FOUND is returned both when a resource does not exist and when it belongs to another tenant. That is deliberate, so the API cannot be used to probe other tenants' data. In practice it means you are authenticated as the wrong tenant. See Authentication failures.

Next steps#