/callcenter/* on https://api.lokutor.com. The routes exist only on a server with telephony configured; where it is not, they are not registered at all and answer 404. api.lokutor.com has telephony configured. For a step-by-step setup, see the Phone agent quickstart.
Authentication: every endpoint takes an API key or wst_ ticket as Authorization: Bearer, X-API-Key or ?api_key= (Authentication). The key must belong to an account (401 otherwise).
Billing: calls and numbers are paid from the account’s prepaid balance (Pricing and billing). Buying a number and placing calls need a first top-up: before it, those endpoints answer 402 with {"code": "billing.topup_required", "error": "…"}. With less than $0.25 of balance they answer 402 billing.insufficient_balance, and while a payment is disputed, billing.account_disputed.
Account scope: every endpoint acts only on the account that owns the key. The agents and numbers you list are your own. Assign, release, dial and bulk-dial work only with numbers you own and agents you own. A number or agent that belongs to another account answers 404 (403 for a from number you don’t own), whether or not it exists. The API needs a key that belongs to an account (401 otherwise).
GET /callcenter/status — Provisioning Status
Whether calling is enabled, and through which carrier.
Response
GET /callcenter/agents — List Agents
Returns every agent on the account, for populating a “route to agent” picker.
Response
GET /callcenter/numbers/search — Search Available Numbers
Search the inventory of purchasable numbers, before committing to buy one. Only local numbers are offered, in the US, Spain, the UK, Germany, France, Italy and Portugal; any other country_code returns 400.
monthly_cost and upfront_cost in the results are the carrier’s own figures, not what you pay: every Lokutor number is $5 a month from your balance (phone.number_per_month in the rate card).
Query Parameters
Response
cURL
GET /callcenter/numbers — List Owned Numbers
Returns every number on the account, merged with its agent binding (if any).
Response
POST /callcenter/numbers — Buy a Number
Purchases a number you have already found via search — phone_number must be an exact result from /callcenter/numbers/search, not an arbitrary string. There’s no “buy a random number for this country” shortcut; searching first is required.
If the balance cannot pay a month, the number is kept for 30 days, still answering calls while the balance allows; after that it is released, and a released number cannot be recovered.
A call on a number is billed like any agent session (platform time per second and the language model per token) plus the phone line per started minute, by direction and country: a call your agent receives is priced by the country of your number, one it makes (dial, bulk dial) by the destination, landline or mobile. For example, a received call on a Spanish number is 0.105 a minute of line, about 15.7¢ in all. Every country’s rate is in Pricing and billing and in the rate card. A call to your number while the balance is under $0.25 is not answered.
Request
Response (200)
The number was purchased and is already showing as owned.Response (202)
The order was placed, but Telnyx hasn’t finished activating it yet (the API polls briefly, then gives up and returns this instead of blocking indefinitely). It’ll show up inGET /callcenter/numbers shortly after.
cURL
POST /callcenter/numbers/{id}/assign — Assign a Number to an Agent
Rebinds an already-owned number to route inbound calls to a different agent (or, with agent_id: "", no agent).
Request
Response
DELETE /callcenter/numbers/{id} — Release a Number
Releases the number back to Telnyx and removes its agent binding. {id} is the Telnyx number ID from GET /callcenter/numbers (n.id), not the phone number itself.
Response
POST /callcenter/dial — Place One Outbound Call
Request
There is no
connection_id field: calls always go out through Lokutor’s outbound profile, which carries the destination-rate limits below. A connection_id in the body is ignored.
An outbound call is billed as agent time and tokens plus the line per started minute at the destination’s rate (Pricing and billing); a call nobody answers costs nothing. Placing calls needs a first top-up (402 billing.topup_required before it). You can call landlines in every supported country, and mobiles in Spain, France, Germany, Austria, the UK, Ireland, the US and Canada. Mobiles in Portugal, Italy, the Netherlands, Belgium, Luxembourg and Switzerland are above the carrier rate Lokutor allows: dialling one returns 400 with that reason, and nothing is billed.
Response
cURL
call_id to follow the call or hang it up with POST /callcenter/hangup/{id}.
GET /callcenter/call-monitor — Follow a Call
GET /callcenter/call-monitor?call_id={call_id} returns the current state of a call your account placed:
status is dialing, ringing, connected or ended. A call that is not yours, or that the server does not know, reads as {"status": "ended", "transcript": [], "duration": 0}.
Live updates (Server-Sent Events)
GET /callcenter/sse/call-monitor?call_id={call_id} streams the same information. The first event is a snapshot (status, transcript, duration); then status, transcript (one new line in text), transcript_sync (the whole transcript) and ended (with end_reason) events follow as the call progresses. Each arrives as a data: line holding a JSON object with a type field. A : heartbeat comment is sent every 15 seconds.
A browser EventSource cannot send headers, so pass a short-lived ticket (minted on your backend, see Authentication) as api_key:
Hang Up a Call
POST /callcenter/hangup/{id} hangs up a call your account placed. {id} is the call_id from /callcenter/dial.
POST /callcenter/bulk-dial — Create a Bulk Dial Batch
Queues up to 500 calls at once. Each row dials independently, at its own scheduled time (or immediately) — this runs server-side on a background scheduler, so it keeps going even if you close the tab, and even the “dial now” rows go through the same pacing as scheduled ones.
Request
Response
GET /callcenter/bulk-dial — List Batches
Returns every batch created by the authenticated account, most recent first, each with a live status breakdown.
Response
GET /callcenter/bulk-dial/{id} — Batch Detail
Returns one batch with every row, each annotated with its conversation summary once the call has happened.
Response
status is one of pending, dialing, sent, failed.
Related Pages
- Phone agent quickstart: buy a number and take a call
- Errors: error codes, including the billing
402s - REST API: synthesis, transcription and discovery endpoints
- My First Agent: build an agent to route these calls to