Phone Numbers
Verified against backend/internal/publicapi/builder_dto.go, phonenumbers_handler.go, phonenumbers_acquire.go, and routes.go.
| Method | Path | Scope |
|---|---|---|
| GET | /phone-numbers | phone_numbers:read |
| POST | /phone-numbers | phone_numbers:write |
| POST | /agents/:id/phone-number | phone_numbers:write |
| DELETE | /agents/:id/phone-number | phone_numbers:write |
Acquiring a number
curl -X POST https://api.voicematrix.ai/api/v1/ext/phone-numbers \
-H "X-API-Key: vm_live_..." \
-H "Idempotency-Key: acquire-number-1"Acquisition is bounded on purpose, not open-ended: numbers are drawn from a pool first, one number per organization, under a hard platform-wide cap, guarded by an advisory lock around both the cap check and the purchase itself, plus a kill switch. Concretely: if you retry this endpoint after a success, the org cap is what stops the second call from also succeeding — not your Twilio account balance. Send the Idempotency-Key anyway; it's the difference between "the retry returns my first number" and "the retry fails cleanly at the org cap," and the former is a much less confusing integration experience.
Binding a number to an agent
curl -X POST https://api.voicematrix.ai/api/v1/ext/agents/<agent-id>/phone-number \
-H "X-API-Key: vm_live_..." \
-H "Content-Type: application/json" \
-d '{ "phone_number_id": "550e8400-e29b-41d4-a716-446655440000" }'{ "agent_id": "...", "phone_number": "+97233822555", "routing_live": true }routing_live is the field worth reading, not just the 200 status. Binding writes the database row and then updates a LiveKit SIP dispatch rule — internally, that second step can fail silently (logged, not surfaced) on some code paths. This endpoint performs it synchronously and reports the true outcome: if routing_live is false (accompanied by a warning), the database says bound but calls will not actually reach the agent yet. Don't treat a bare 200 as "the line is live" — check the field.
Unbind
DELETE /agents/:id/phone-numberList numbers
GET /phone-numbers{ "data": [ { "id": "...", "phone_number": "+97233822555", "inbound_agent_id": "...", "bound": true } ] }Next
- Agents — publish status does not gate inbound routing; the binding does
- Call Control