Buy a phone number

View as Markdown
Buys a dedicated voice number from the telephony carrier, registers it with the voice engine and binds `agentId` to it, so the agent answers inbound calls on it and uses it as caller ID. Browse inventory first with `GET /api/phone-numbers/available` and pass the exact `phoneNumber`, or let the search pick one by `country` / `areaCode` / `type`. **This spends real money.** The purchase creates a carrier number with a recurring monthly rent. The number included in a plan is US/Canada only: any other `country` is refused with 402 (numbers in other countries are paid add-ons purchased under Settings → Plan, priced by region). The workspace's entitlement is also enforced (402): the plan includes one number, each further one must be a purchased add-on, up to the plan cap (Starter 1, Growth 3, Business 10); Enterprise may hold up to its cap without add-ons. **Side effects.** Purchases the number (exactly once; the purchase is never retried automatically), registers it with the voice engine, binds the agent, stores it, and writes an audit entry. If any step after the purchase fails, the voice-engine registration is deleted and the carrier number released before the error is returned. **Idempotency.** Idempotent per agent: when the agent already has an active number, that number is returned (still 201) and nothing is bought. Concurrent requests for the same agent are serialized by a 2-minute lock; the loser gets 409. A retry after a timeout is therefore safe for the same `agentId`. **Access** - **Required scope:** `full`. Signed-in users need the admin or owner role. - **Rate limit:** General API — per plan: 120 to 600 requests/min per workspace. See [Rate limits](/rate-limits). - **Plan:** Requires an active plan; bounded by the plan's phone-number entitlement.

Authentication

AuthorizationBearer
Workspace API key: `jl_` followed by 64 lowercase hex characters, created by the workspace owner in the dashboard (**Settings → API Keys**) and sent as `Authorization: Bearer jl_...`. The plaintext is shown once, at creation; Jelliu stores only a SHA-256 hash. A workspace can hold up to 25 active keys. | Scope | GET / HEAD | POST / PUT / PATCH / DELETE | Admin-only routes | | --- | --- | --- | --- | | `read` | Yes | No | No | | `write` | Yes | Yes | No | | `full` | Yes | Yes | Yes | Operations restricted to admins or owners reject keys without the `full` scope with `403`, and say so in their description. No key, whatever its scope, can mint or revoke API keys or rotate a webhook secret — that requires a signed-in owner session. A revoked key stops authenticating within about 10 seconds. See [Authentication](/authentication).

Request

This endpoint expects an object.
agentIdstringRequiredformat: "uuid"

The agent that answers on the number. Must belong to this workspace (404) and be provisioned with the voice provider (409 while it is not).

countryenumOptionalDefaults to US

ISO-3166 alpha-2 code, case-insensitive; defaults to US. Must be a serviceable market (400 We can't provision numbers in <code> yet. Available: ...), and must be US or CA for this endpoint (402).

areaCodestringOptionalformat: "^\d{3}$"

3-digit area code (NPA) to prefer when searching. Only used for US and CA. Ignored when phoneNumber is given.

phoneNumberstringOptionalformat: "^\+[1-9]\d{1,14}$"

Exact E.164 number to buy, picked from GET /api/phone-numbers/available. Without it the first available number of the requested type is bought.

typeenumOptional

Preferred inventory type. Without it local is tried, then mobile. local = geographic number; mobile = mobile range; tollfree = toll-free number.

Allowed values:
labelstringOptional1-120 characters

Display name for the number. Defaults to Jelliu <phoneNumber>.

Response

The purchased number, or the agent's existing active number.
dataobject

One number the workspace holds. channels says what it answers on; provider says where it lives. Field names are camelCase. Returned by every /api/phone-numbers endpoint.

Errors

400
Bad Request Error
401
Unauthorized Error
402
Payment Required Error
403
Forbidden Error
404
Not Found Error
409
Conflict Error
429
Too Many Requests Error
502
Bad Gateway Error
503
Service Unavailable Error