---
title: "Give a recipient a SIP line"
method: POST
path: "/api/v1/extensions"
tags: ["Telecom"]
---

# Give a recipient a SIP line

`POST /api/v1/extensions`

## Request

- Base URL: `https://wardenpoint.com` (the document declares no server; this is the origin it was published from)
- URL: `https://wardenpoint.com/api/v1/extensions`
- Auth: API key in header `X-API-Key`

Hands a recipient an internal SIP line so voice alerts can reach them, and mirrors the line into their `internal_sip` contact in the same step — call routing reads the contact, not the line, so a line without the contact rings nowhere. Has side effects outside this system: it writes PJSIP records into the telephony switch and asks it to reload, and provisioning a brand-new line also wires an inbound number to it — a number the company already owns and has free, or failing that a fresh one from the shared pool. Idempotent per recipient: a recipient who already holds a line gets that same line back and the answer is 200 instead of 201, so a retry after a timeout never produces a second line. 201 means a line was newly provisioned; 200 means an existing one was reused or bound. Rate-limited in step with the dashboard, because every call reloads the switch.

## Request body

- ExtensionAssignRequest
  - `recipient_uuid` string, uuid, required: Who gets the line. Must belong to the same company as the key.
  - `extension_uuid` string, uuid, nullable: An existing free line of the company to hand over. Omit to have a new line provisioned instead. Three cases differ: a free operator line of this company is bound (200); a line of this company that somebody already holds, or that is not an operator line, answers 422; a UUID belonging to another company is treated as omitted and a new line is provisioned. Ignored entirely when the recipient already holds a line — that line is returned instead.

## Response `200`

The recipient already had a line, or an existing free line was bound. Same body as 201.

- object
  - `data` Extension: One internal SIP line of the company. The SIP password is never part of this object and is not obtainable through the API at all — read it in the dashboard.
    - `uuid` string, uuid: Stable identifier — every extension endpoint takes this.
    - `extension` string: The line number inside the company. This is the same string that lands in the recipient's internal_sip contact.
    - `type` 'operator' | 'notification' | 'webrtc': `operator` — a SIP line a recipient registers a phone to, and the only type this API hands out. `notification` — the company's outbound bot line, provisioned automatically, one per company. `webrtc` — a browser softphone for a team member, allocated in the dashboard.
    - `status` 'provisioning' | 'active' | 'suspended': `active` — usable. `provisioning` — being set up in the telephony switch. `suspended` — temporarily off. Deprovisioned lines are not listed at all.
    - `caller_id` string, nullable: How the company presents itself on an outbound call placed from this line.
    - `did_number` string, nullable: External number wired to this line for inbound calls, if any. Allocated from the shared pool when the line is created, not bought.
    - `recipient` object, nullable: The person this line rings. Null means the line is free and can be handed to somebody.
      - `uuid` string, uuid
      - `name` string
    - `user` object, nullable: The team member owning this browser softphone. Only ever set on `webrtc` lines.
      - `uuid` string, uuid
      - `name` string
    - `provisioned_at` string, date-time, nullable
    - `last_registered_at` string, date-time, nullable: When a SIP device last registered to this line. Null on a line nobody has ever connected a phone to — worth checking before trusting it to wake somebody.

## Other responses

- `201`: A line was provisioned and handed over.
- `401`: API key missing, invalid, revoked or expired.
- `403`: API key lacks the config.write ability.
- `404`: No recipient with this UUID in the company of the key. This code is about the recipient only — an unusable extension_uuid answers 422.
- `422`: Either the request body failed validation (recipient_uuid missing or unknown), or the line could not be given out: the plan's SIP-line quota is used up, the company's number block is full, or the named extension_uuid is already taken or not an operator line. The message says which. Note that the plan quota surfaces here as 422 and not as the 429 other endpoints use — telecom enforces its quota inside the service rather than in middleware, on both surfaces alike.
- `429`: Too many telecom changes in a short window. Each one reloads the telephony switch.
- `500`: The telephony switch or its database could not be reached, so nothing was provisioned. Unlike 422 this is worth retrying — the request itself was fine.

---

[API](https://skmtc.dev/wardenpoint/apis/wardenpoint-api.md) · [All operations](https://skmtc.dev/wardenpoint/apis/wardenpoint-api/llms.txt) · [OpenAPI document](https://skmtc.dev/wardenpoint/apis/wardenpoint-api/revisions/259ee445728e?raw)
