# AI receptionist API: set it up from code

> An AI receptionist API is plain HTTP: create the business, store the brief, have a person pay, then order the number. Curl is enough.

Published 2026-11-14 · by RingKit · tags: ai receptionist, setup. Canonical: https://www.ringkit.com/blog/ai-receptionist-api

An AI receptionist API is a list of HTTP calls, not a library. You create a business, store what the receptionist may say, name which of the owner's phones get a transfer, have a person pay, and then order a US local number. Do the steps in that order. A number against an empty brief is a line that can only apologize. RingKit's API is at `https://api.ringkit.com/v1`. There are no SDKs yet. Use curl or fetch. The same routes are described in an OpenAPI 3.1 document at `https://api.ringkit.com/openapi.json`. The format of that document is the [OpenAPI 3.1 specification](https://spec.openapis.org/oas/v3.1.0.html). If you wanted the tool list an agent calls inside a chat app, that is the [MCP phone receptionist](https://www.ringkit.com/blog/mcp-phone-receptionist). This page is the HTTP underneath it.

The full sequence, with every field, is the [quickstart in the docs](https://www.ringkit.com/docs#quickstart). What follows is the order that matters, the two places a person has to act, and the mistakes that create a second number or an empty brief.

## Create the business, and keep the key

`POST /v1/businesses` is the only call that needs no API key. Send a name, an IANA timezone, and the owner's email. Leave `ownerPhone` off. The API refuses it on create with `403 destination_unverified`, because a business that does not exist yet cannot have proved it controls a phone. You add the owner's mobile later, after a verification call. The response is `201` with the business id and the API key. The key is shown once. Store it before you do anything else.

Send an `Idempotency-Key` on that POST. Retrying the same key within 24 hours returns the stored response and the header `Idempotent-Replayed: true`, instead of creating a second business. A retry that arrives while the first request is still running gets `409 idempotency_in_progress`. A new key means you meant a new business. Use a new key only when you mean that.

```
curl https://api.ringkit.com/v1/businesses \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: create-northside-1" \
  -d '{"name":"Northside Example","timezone":"America/Phoenix","ownerEmail":"owner@example.com"}'
```

That body is a sample, not a real company. Put the key on every later call as `Authorization: Bearer rk_…`. A key acts as the owner. Scope `manage` is the default. Scope `read` can only GET, and anything else returns `403 insufficient_scope`. Give a reporting script a read key. Do not give it the key that can order numbers.

## Teach the line before you buy the number

The receptionist will say what you store, and it will not invent a policy that is not there. You can import a website in the background with `POST /v1/businesses/$BIZ/knowledge/imports` and a URL, then poll `GET /v1/businesses/$BIZ/onboarding` until `latestImport.status` is `done` or `failed`. The import fills only fields that are still empty. It does not replace a price someone already typed, and it does not touch an uploaded document. Read the result before you trust it. A homepage price can be a sale that ended.

Or replace the profile yourself with `PUT /v1/businesses/$BIZ/knowledge`, or merge with `PATCH`. Hours, services, prices you will stand behind, FAQs, and policies are the fields callers hear. Or upload a PDF, DOCX, TXT, Markdown, or HTML file, up to 10 MB, as base64. Or start a setup chat and answer in sentences. All of those land in the same profile.

The receptionist does not book a calendar. A caller who asks for a time becomes a message in the summary. Do not write a prompt that says the appointment is confirmed.

## Transfers are the owner's phones

`PUT /v1/businesses/$BIZ/routing` replaces the whole policy. Fields you leave out go back to their defaults, so send the full rule, not a fragment. Set `mode` to `ai_only`. The receptionist answers every call. `transferTargets` is a list of the business's own numbers, each with an id, a label, the number, and a `whenToUse` the model can follow. "The caller asks for the owner" is a usable rule. "Emergencies" is not, unless you also wrote what you mean by one. If nobody is free, or no rule matches, it takes a message. RingKit does not staff the call. Modes that used to bring in a RingKit live rep are not offered, and they run as `ai_only`.

Voice is optional. `GET /v1/voices` lists them. `PATCH` the business with a voice id, or leave the default. Do this before you judge a simulation. A test of the wrong voice wastes a billed call and tells you nothing about the brief.

## Two steps a person still has to do

There is no free trial, and there is no sandbox. `POST /v1/businesses/$BIZ/simulate` runs the real receptionist on typed lines. An empty `callerText` returns the greeting. Send the `callId` back with the next line. That test is billed from the wallet at the AI rate, $0.20 a minute. Do not tell anyone the simulation is free. If the wallet is empty, fund it before you rely on the test.

A top-up is `POST /v1/businesses/$BIZ/wallet/top-ups` with `amountCents` of at least 1000, which is $10. The response is a checkout URL. A person opens it and pays. The API does not charge a card by itself. Send an idempotency key, and reuse it only for that same top-up. After they pay, `GET` the wallet and confirm the paid balance. Ordering a number needs $2 of paid credit. Without it, the order returns `402 funding_required`.

## Order the number, then prove the phone

Search `GET /v1/numbers/search?areaCode=602` and order with `POST /v1/businesses/$BIZ/numbers` and the number you picked. The number is $1.99 a month from the wallet. Nobody has to sign in first. Use an idempotency key on the order. A new key is a new attempt, not a replay. The business can publish that number, or keep the one customers already know and forward it. RingKit does not port numbers. The details of a live number, after it exists, are in [AI agent phone number](https://www.ringkit.com/blog/ai-agent-phone-number).

A real test call only rings a number the business configured and verified. `POST …/destinations/verify` places a call that reads a 6-digit code. That code is the person's consent to be called. `POST …/destinations/confirm` sends the code back. `POST …/test-call` then rings that number from the RingKit number, on the AI, billed at the AI rate. The docs cap test calls at 5 per business per day, and outbound calls at 3 per number per day. Your code cannot hear the code. Ask the person.

## When the call is over

`GET /v1/businesses/$BIZ/calls` is cursor-paginated. One call includes the transcript and a summary: who called, what they needed, and the next step. You can also register a webhook with `POST /v1/businesses/$BIZ/webhooks` and a list of events. The secret comes back once. RingKit then POSTs `call.completed`, `message.taken`, or `balance.low` to your URL. `balance.low` fires when a call takes the wallet under $2.

Every delivery has `X-RingKit-Signature: t=<unix seconds>,v1=<hex>`. The hex is an HMAC-SHA256 of the timestamp, a period, and the raw body, keyed with that secret. Reject a delivery older than five minutes, and verify against the raw bytes, not a re-serialized JSON object. The check itself is in the docs. Respond `2xx` within 5 seconds. Other responses are retried with backoff, up to 10 attempts, except a `4xx` other than `408` or `429`, which is treated as permanent.

Calls are recorded and transcribed to make the summary, and a consent notice plays on every call. The receptionist always says it is an AI. That is not a flag you turn off.

## What you should not build on top

Do not look for a client library, a CRM connector, or a calendar booking route. They are not in this API. Do not send `ownerPhone` on create and then retry with a fresh idempotency key when it fails. Fix the body and keep the story straight: verify the phone, then patch it on. Do not order the number before the brief is something the owner has read. The [pricing page](https://www.ringkit.com/pricing) is the rate card: $1.99 a month for the number, $0.20 a minute on the call, first 10 seconds free, then 6-second increments. A month with no calls is $1.99.

The owner invite is optional. `POST …/owners/invite` emails a sign-in link. The line can run before they open it. When they do, they can rotate the key. You can keep operating either way. The API's job is the setup. The receptionist's job starts when a stranger dials the number.

---

Try Ringkit: $0.20/min, $1.99/mo per number, no plan. Get started at https://app.ringkit.com/onboard
