> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://developer.jelliu.co/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developer.jelliu.co/_mcp/server.

# Buy a phone number

POST https://api.jelliu.co/api/phone-numbers/provision
Content-Type: application/json

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.


Reference: https://developer.jelliu.co/api-reference/phone-numbers/post-phone-numbers-provision

## Authentication

- `Authorization` header (bearer token, required) — 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

### Body (application/json)

This endpoint expects an object.

- `agentId` (string, required) — 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).
- `country` (enum, optional, default: 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).
  - Allowed values: `US`, `CA`, `GB`, `FR`, `DE`, `AU`, `PR`, `BR`, `MX`, `CL`, `AR`, `PA`, `CO`
- `areaCode` (string, optional) — 3-digit area code (NPA) to prefer when searching. Only used for US and CA. Ignored when `phoneNumber` is given.
- `phoneNumber` (string, optional) — 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.
- `type` (enum, optional) — Preferred inventory type. Without it local is tried, then mobile. `local` = geographic number; `mobile` = mobile range; `tollfree` = toll-free number.
  - Allowed values: `local`, `mobile`, `tollfree`
- `label` (string, optional) — Display name for the number. Defaults to `Jelliu <phoneNumber>`.

## Response

### 201

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

- `data` (object, required) — 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.
  - `id` (string, required) — Unique identifier of the number entry. Use it in `/api/phone-numbers/{id}`.
  - `phoneNumber` (string, required) — The number in E.164 format. Cannot be changed.
  - `label` (string, required, nullable) — Display name. Defaults to `Jelliu <number>` for purchased numbers and `<number> (own number)` for SIP-trunk numbers.
  - `isActive` (boolean, required) — `false` when the number was switched off: it is not used as caller ID, does not accept forwarding and does not count toward the plan cap.
  - `agentId` (string, required, nullable) — The agent that answers calls (and WhatsApp messages, for a WhatsApp line) on this number. Null when unbound.
  - `agentName` (string, required, nullable) — The bound agent's name. Null when unbound.
  - `agentProvisioned` (boolean, required, nullable) — False while the bound agent is still being set up in the voice provider (inbound calls do not route to it yet); null when no agent is bound.
  - `ivrEnabled` (boolean, required) — Whether callers hear the IVR menu before reaching an agent. Only effective on numbers bought through Jelliu.
  - `ivrGreeting` (string, required, nullable) — What the IVR menu says before the options.
  - `ivrOptions` (list of object, required) — The IVR menu, in the order configured. Empty when there is no menu.
    - `digit` (string, required) — Key the caller presses (`0`-`9`, `*` or `#`).
    - `label` (string, required) — Name of the option.
    - `agentId` (string, required, nullable) — Agent the option routes to, when routed to an agent.
    - `department` (string, required, nullable) — Department the option routes to, resolved to an agent at call time.
  - `channels` (list of enum, required) — What the number answers on: `voice`, `whatsapp`, or both. `['whatsapp']` for a WhatsApp-only line; a voice number that is also the WhatsApp line carries both.
    - Allowed values: `voice`, `whatsapp`
  - `whatsappStatus` (string, required, nullable) — The WhatsApp sender's status when the number is a WhatsApp line (e.g. `ONLINE`, `VERIFYING`, `OFFLINE`), else null.
  - `provider` (enum, required) — Where the number lives. `twilio` = bought through Jelliu. `sip_trunk` = the business's own number, reached over its SIP trunk.
    - Allowed values: `twilio`, `sip_trunk`
  - `sipHost` (string, required, nullable) — The outbound trunk address a `sip_trunk` number is reached through. Null for numbers bought through Jelliu and for trunks connected for inbound only.
  - `createdAt` (datetime, required) — When the number was added to the workspace.
  - `updatedAt` (datetime, required) — Last change to the number's configuration.

## Errors

### 400 Bad Request Error

Invalid body. Message `Invalid provisioning request`; `details` = zod `flatten()` output.

- `error` (object, required) — The error object. Always has `code` and `message`.
  - `code` (string, required) — Stable machine-readable error code (for example `VALIDATION_FAILED`, `UNAUTHORIZED`, `FORBIDDEN`, `NOT_FOUND`, `BILLING_ERROR`, `COMPLIANCE_BLOCKED`, `RATE_LIMIT_EXCEEDED`, `INTERNAL_ERROR`). Switch on this, not on `message`. See [Errors](/errors).
  - `message` (string, required) — Human-readable explanation. English or Spanish depending on the route; may change without notice.
  - `details` (object or list of object, optional) — Present on `VALIDATION_FAILED` only. Its shape depends on how the route validates: * a field map, either Zod's `flatten()` output (`{ "formErrors": [], "fieldErrors": { "name": ["..."] } }`) or just its `fieldErrors` part (`{ "name": ["..."] }`); * an issue list, where each issue has at least `path`, `message` and `code`. `path` is a dot-separated string on routes that let the schema throw, and an array of keys on routes that forward Zod's raw issues (those also carry Zod's extra issue fields).
    - Field map
      - `formErrors` (list of string, optional)
      - `fieldErrors` (map from string to list of string, optional)
  - `metadata` (map from string to any, optional) — Structured detail exposed for a small allowlist of codes only — for example `BILLING_ERROR` carries `limit`, `current` and `tier` (resource caps) or `tier` and `feature` (feature gates).

### 401 Unauthorized Error

No usable credential. Either the `Authorization` header is missing or is not a well-formed `Bearer jl_…` key, or the key is unknown, revoked or expired. Do not retry with the same key. See [Authentication](/authentication#401-unauthorized).

- `error` (object, required) — The error object. Always has `code` and `message`.
  - `code` (string, required) — Stable machine-readable error code (for example `VALIDATION_FAILED`, `UNAUTHORIZED`, `FORBIDDEN`, `NOT_FOUND`, `BILLING_ERROR`, `COMPLIANCE_BLOCKED`, `RATE_LIMIT_EXCEEDED`, `INTERNAL_ERROR`). Switch on this, not on `message`. See [Errors](/errors).
  - `message` (string, required) — Human-readable explanation. English or Spanish depending on the route; may change without notice.
  - `details` (object or list of object, optional) — Present on `VALIDATION_FAILED` only. Its shape depends on how the route validates: * a field map, either Zod's `flatten()` output (`{ "formErrors": [], "fieldErrors": { "name": ["..."] } }`) or just its `fieldErrors` part (`{ "name": ["..."] }`); * an issue list, where each issue has at least `path`, `message` and `code`. `path` is a dot-separated string on routes that let the schema throw, and an array of keys on routes that forward Zod's raw issues (those also carry Zod's extra issue fields).
    - Field map
      - `formErrors` (list of string, optional)
      - `fieldErrors` (map from string to list of string, optional)
  - `metadata` (map from string to any, optional) — Structured detail exposed for a small allowlist of codes only — for example `BILLING_ERROR` carries `limit`, `current` and `tier` (resource caps) or `tier` and `feature` (feature gates).

### 402 Payment Required Error

`country` is not US/CA, or the workspace's number entitlement is used up (`BILLING_ERROR`, with `metadata` such as `tier`, `activeNumbers`, `entitled`, `maxPhoneNumbers`, `paidAddons`).

- `error` (object, required) — The error object. Always has `code` and `message`.
  - `code` (string, required) — Stable machine-readable error code (for example `VALIDATION_FAILED`, `UNAUTHORIZED`, `FORBIDDEN`, `NOT_FOUND`, `BILLING_ERROR`, `COMPLIANCE_BLOCKED`, `RATE_LIMIT_EXCEEDED`, `INTERNAL_ERROR`). Switch on this, not on `message`. See [Errors](/errors).
  - `message` (string, required) — Human-readable explanation. English or Spanish depending on the route; may change without notice.
  - `details` (object or list of object, optional) — Present on `VALIDATION_FAILED` only. Its shape depends on how the route validates: * a field map, either Zod's `flatten()` output (`{ "formErrors": [], "fieldErrors": { "name": ["..."] } }`) or just its `fieldErrors` part (`{ "name": ["..."] }`); * an issue list, where each issue has at least `path`, `message` and `code`. `path` is a dot-separated string on routes that let the schema throw, and an array of keys on routes that forward Zod's raw issues (those also carry Zod's extra issue fields).
    - Field map
      - `formErrors` (list of string, optional)
      - `fieldErrors` (map from string to list of string, optional)
  - `metadata` (map from string to any, optional) — Structured detail exposed for a small allowlist of codes only — for example `BILLING_ERROR` carries `limit`, `current` and `tier` (resource caps) or `tier` and `feature` (feature gates).

### 403 Forbidden Error

The API key lacks the `full` scope, or the signed-in user is not an admin or owner.

- `error` (object, required) — The error object. Always has `code` and `message`.
  - `code` (string, required) — Stable machine-readable error code (for example `VALIDATION_FAILED`, `UNAUTHORIZED`, `FORBIDDEN`, `NOT_FOUND`, `BILLING_ERROR`, `COMPLIANCE_BLOCKED`, `RATE_LIMIT_EXCEEDED`, `INTERNAL_ERROR`). Switch on this, not on `message`. See [Errors](/errors).
  - `message` (string, required) — Human-readable explanation. English or Spanish depending on the route; may change without notice.
  - `details` (object or list of object, optional) — Present on `VALIDATION_FAILED` only. Its shape depends on how the route validates: * a field map, either Zod's `flatten()` output (`{ "formErrors": [], "fieldErrors": { "name": ["..."] } }`) or just its `fieldErrors` part (`{ "name": ["..."] }`); * an issue list, where each issue has at least `path`, `message` and `code`. `path` is a dot-separated string on routes that let the schema throw, and an array of keys on routes that forward Zod's raw issues (those also carry Zod's extra issue fields).
    - Field map
      - `formErrors` (list of string, optional)
      - `fieldErrors` (map from string to list of string, optional)
  - `metadata` (map from string to any, optional) — Structured detail exposed for a small allowlist of codes only — for example `BILLING_ERROR` carries `limit`, `current` and `tier` (resource caps) or `tier` and `feature` (feature gates).

### 404 Not Found Error

The agent does not exist in this workspace.

- `error` (object, required) — The error object. Always has `code` and `message`.
  - `code` (string, required) — Stable machine-readable error code (for example `VALIDATION_FAILED`, `UNAUTHORIZED`, `FORBIDDEN`, `NOT_FOUND`, `BILLING_ERROR`, `COMPLIANCE_BLOCKED`, `RATE_LIMIT_EXCEEDED`, `INTERNAL_ERROR`). Switch on this, not on `message`. See [Errors](/errors).
  - `message` (string, required) — Human-readable explanation. English or Spanish depending on the route; may change without notice.
  - `details` (object or list of object, optional) — Present on `VALIDATION_FAILED` only. Its shape depends on how the route validates: * a field map, either Zod's `flatten()` output (`{ "formErrors": [], "fieldErrors": { "name": ["..."] } }`) or just its `fieldErrors` part (`{ "name": ["..."] }`); * an issue list, where each issue has at least `path`, `message` and `code`. `path` is a dot-separated string on routes that let the schema throw, and an array of keys on routes that forward Zod's raw issues (those also carry Zod's extra issue fields).
    - Field map
      - `formErrors` (list of string, optional)
      - `fieldErrors` (map from string to list of string, optional)
  - `metadata` (map from string to any, optional) — Structured detail exposed for a small allowlist of codes only — for example `BILLING_ERROR` carries `limit`, `current` and `tier` (resource caps) or `tier` and `feature` (feature gates).

### 409 Conflict Error

The agent is still being provisioned with the voice provider (`AGENT_PROVISIONING`, with `Retry-After: 5`), or a number is already being provisioned for it (`CALL_ALREADY_IN_PROGRESS`).

- `error` (object, required) — The error object. Always has `code` and `message`.
  - `code` (string, required) — Stable machine-readable error code (for example `VALIDATION_FAILED`, `UNAUTHORIZED`, `FORBIDDEN`, `NOT_FOUND`, `BILLING_ERROR`, `COMPLIANCE_BLOCKED`, `RATE_LIMIT_EXCEEDED`, `INTERNAL_ERROR`). Switch on this, not on `message`. See [Errors](/errors).
  - `message` (string, required) — Human-readable explanation. English or Spanish depending on the route; may change without notice.
  - `details` (object or list of object, optional) — Present on `VALIDATION_FAILED` only. Its shape depends on how the route validates: * a field map, either Zod's `flatten()` output (`{ "formErrors": [], "fieldErrors": { "name": ["..."] } }`) or just its `fieldErrors` part (`{ "name": ["..."] }`); * an issue list, where each issue has at least `path`, `message` and `code`. `path` is a dot-separated string on routes that let the schema throw, and an array of keys on routes that forward Zod's raw issues (those also carry Zod's extra issue fields).
    - Field map
      - `formErrors` (list of string, optional)
      - `fieldErrors` (map from string to list of string, optional)
  - `metadata` (map from string to any, optional) — Structured detail exposed for a small allowlist of codes only — for example `BILLING_ERROR` carries `limit`, `current` and `tier` (resource caps) or `tier` and `feature` (feature gates).

### 429 Too Many Requests Error

Rate limit exceeded for the current 60-second window (`RATE_LIMIT_EXCEEDED`). Wait `Retry-After` seconds, then retry. The `message` differs per limiter; the code does not. See [Rate limits](/rate-limits).

- `error` (object, required) — The error object. Always has `code` and `message`.
  - `code` (string, required) — Stable machine-readable error code (for example `VALIDATION_FAILED`, `UNAUTHORIZED`, `FORBIDDEN`, `NOT_FOUND`, `BILLING_ERROR`, `COMPLIANCE_BLOCKED`, `RATE_LIMIT_EXCEEDED`, `INTERNAL_ERROR`). Switch on this, not on `message`. See [Errors](/errors).
  - `message` (string, required) — Human-readable explanation. English or Spanish depending on the route; may change without notice.
  - `details` (object or list of object, optional) — Present on `VALIDATION_FAILED` only. Its shape depends on how the route validates: * a field map, either Zod's `flatten()` output (`{ "formErrors": [], "fieldErrors": { "name": ["..."] } }`) or just its `fieldErrors` part (`{ "name": ["..."] }`); * an issue list, where each issue has at least `path`, `message` and `code`. `path` is a dot-separated string on routes that let the schema throw, and an array of keys on routes that forward Zod's raw issues (those also carry Zod's extra issue fields).
    - Field map
      - `formErrors` (list of string, optional)
      - `fieldErrors` (map from string to list of string, optional)
  - `metadata` (map from string to any, optional) — Structured detail exposed for a small allowlist of codes only — for example `BILLING_ERROR` carries `limit`, `current` and `tier` (resource caps) or `tier` and `feature` (feature gates).

### 502 Bad Gateway Error

The telephony carrier (`TELEPHONY_ERROR`, e.g. no inventory, a country requiring a regulatory bundle) or the voice provider (`VOICE_AI_ERROR`) failed (message replaced by `Internal server error`). Any partial purchase is rolled back.

- `error` (object, required) — The error object. Always has `code` and `message`.
  - `code` (string, required) — Stable machine-readable error code (for example `VALIDATION_FAILED`, `UNAUTHORIZED`, `FORBIDDEN`, `NOT_FOUND`, `BILLING_ERROR`, `COMPLIANCE_BLOCKED`, `RATE_LIMIT_EXCEEDED`, `INTERNAL_ERROR`). Switch on this, not on `message`. See [Errors](/errors).
  - `message` (string, required) — Human-readable explanation. English or Spanish depending on the route; may change without notice.
  - `details` (object or list of object, optional) — Present on `VALIDATION_FAILED` only. Its shape depends on how the route validates: * a field map, either Zod's `flatten()` output (`{ "formErrors": [], "fieldErrors": { "name": ["..."] } }`) or just its `fieldErrors` part (`{ "name": ["..."] }`); * an issue list, where each issue has at least `path`, `message` and `code`. `path` is a dot-separated string on routes that let the schema throw, and an array of keys on routes that forward Zod's raw issues (those also carry Zod's extra issue fields).
    - Field map
      - `formErrors` (list of string, optional)
      - `fieldErrors` (map from string to list of string, optional)
  - `metadata` (map from string to any, optional) — Structured detail exposed for a small allowlist of codes only — for example `BILLING_ERROR` carries `limit`, `current` and `tier` (resource caps) or `tier` and `feature` (feature gates).

### 503 Service Unavailable Error

Provisioning is temporarily unavailable because the lock service is down (fails closed so no double purchase can happen; message replaced by `Internal server error`). Retry.

- `error` (object, required) — The error object. Always has `code` and `message`.
  - `code` (string, required) — Stable machine-readable error code (for example `VALIDATION_FAILED`, `UNAUTHORIZED`, `FORBIDDEN`, `NOT_FOUND`, `BILLING_ERROR`, `COMPLIANCE_BLOCKED`, `RATE_LIMIT_EXCEEDED`, `INTERNAL_ERROR`). Switch on this, not on `message`. See [Errors](/errors).
  - `message` (string, required) — Human-readable explanation. English or Spanish depending on the route; may change without notice.
  - `details` (object or list of object, optional) — Present on `VALIDATION_FAILED` only. Its shape depends on how the route validates: * a field map, either Zod's `flatten()` output (`{ "formErrors": [], "fieldErrors": { "name": ["..."] } }`) or just its `fieldErrors` part (`{ "name": ["..."] }`); * an issue list, where each issue has at least `path`, `message` and `code`. `path` is a dot-separated string on routes that let the schema throw, and an array of keys on routes that forward Zod's raw issues (those also carry Zod's extra issue fields).
    - Field map
      - `formErrors` (list of string, optional)
      - `fieldErrors` (map from string to list of string, optional)
  - `metadata` (map from string to any, optional) — Structured detail exposed for a small allowlist of codes only — for example `BILLING_ERROR` carries `limit`, `current` and `tier` (resource caps) or `tier` and `feature` (feature gates).

## Examples

### Phone Numbers_postPhoneNumbersProvision_example

**Request**

```json
undefined
```

**Response**

```json
{
  "data": {
    "id": "7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e",
    "phoneNumber": "+13055550142",
    "label": "Línea de ventas Miami",
    "isActive": true,
    "agentId": "2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11",
    "agentName": "Sofía - Agendamiento",
    "agentProvisioned": true,
    "ivrEnabled": false,
    "ivrGreeting": null,
    "ivrOptions": [],
    "channels": [
      "voice"
    ],
    "whatsappStatus": null,
    "provider": "twilio",
    "sipHost": null,
    "createdAt": "2026-09-14T15:20:00.000Z",
    "updatedAt": "2026-09-14T15:20:00.000Z"
  }
}
```

**SDK Code**

```python Phone Numbers_postPhoneNumbersProvision_example
import requests

url = "https://api.jelliu.co/api/phone-numbers/provision"

headers = {"Authorization": "Bearer <token>"}

response = requests.post(url, headers=headers)

print(response.json())
```

```javascript Phone Numbers_postPhoneNumbersProvision_example
const url = 'https://api.jelliu.co/api/phone-numbers/provision';
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Phone Numbers_postPhoneNumbersProvision_example
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.jelliu.co/api/phone-numbers/provision"

	req, _ := http.NewRequest("POST", url, nil)

	req.Header.Add("Authorization", "Bearer <token>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Phone Numbers_postPhoneNumbersProvision_example
require 'uri'
require 'net/http'

url = URI("https://api.jelliu.co/api/phone-numbers/provision")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'

response = http.request(request)
puts response.read_body
```

```java Phone Numbers_postPhoneNumbersProvision_example
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.jelliu.co/api/phone-numbers/provision")
  .header("Authorization", "Bearer <token>")
  .asString();
```

```php Phone Numbers_postPhoneNumbersProvision_example
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.jelliu.co/api/phone-numbers/provision', [
  'headers' => [
    'Authorization' => 'Bearer <token>',
  ],
]);

echo $response->getBody();
```

```csharp Phone Numbers_postPhoneNumbersProvision_example
using RestSharp;

var client = new RestClient("https://api.jelliu.co/api/phone-numbers/provision");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
IRestResponse response = client.Execute(request);
```

```swift Phone Numbers_postPhoneNumbersProvision_example
import Foundation

let headers = ["Authorization": "Bearer <token>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://api.jelliu.co/api/phone-numbers/provision")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### Any local number in an area code

**Request**

```json
{
  "agentId": "2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11",
  "country": "US",
  "areaCode": "305"
}
```

**Response**

```json
{
  "data": {
    "id": "7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e",
    "phoneNumber": "+13055550142",
    "label": "Línea de ventas Miami",
    "isActive": true,
    "agentId": "2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11",
    "agentName": "Sofía - Agendamiento",
    "agentProvisioned": true,
    "ivrEnabled": false,
    "ivrGreeting": null,
    "ivrOptions": [],
    "channels": [
      "voice"
    ],
    "whatsappStatus": null,
    "provider": "twilio",
    "sipHost": null,
    "createdAt": "2026-09-14T15:20:00.000Z",
    "updatedAt": "2026-09-14T15:20:00.000Z"
  }
}
```

**SDK Code**

```python Any local number in an area code
import requests

url = "https://api.jelliu.co/api/phone-numbers/provision"

payload = {
    "agentId": "2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11",
    "country": "US",
    "areaCode": "305"
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript Any local number in an area code
const url = 'https://api.jelliu.co/api/phone-numbers/provision';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"agentId":"2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11","country":"US","areaCode":"305"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Any local number in an area code
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.jelliu.co/api/phone-numbers/provision"

	payload := strings.NewReader("{\n  \"agentId\": \"2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11\",\n  \"country\": \"US\",\n  \"areaCode\": \"305\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Any local number in an area code
require 'uri'
require 'net/http'

url = URI("https://api.jelliu.co/api/phone-numbers/provision")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"agentId\": \"2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11\",\n  \"country\": \"US\",\n  \"areaCode\": \"305\"\n}"

response = http.request(request)
puts response.read_body
```

```java Any local number in an area code
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.jelliu.co/api/phone-numbers/provision")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"agentId\": \"2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11\",\n  \"country\": \"US\",\n  \"areaCode\": \"305\"\n}")
  .asString();
```

```php Any local number in an area code
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.jelliu.co/api/phone-numbers/provision', [
  'body' => '{
  "agentId": "2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11",
  "country": "US",
  "areaCode": "305"
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp Any local number in an area code
using RestSharp;

var client = new RestClient("https://api.jelliu.co/api/phone-numbers/provision");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"agentId\": \"2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11\",\n  \"country\": \"US\",\n  \"areaCode\": \"305\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Any local number in an area code
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "agentId": "2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11",
  "country": "US",
  "areaCode": "305"
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.jelliu.co/api/phone-numbers/provision")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### A number picked from the inventory

**Request**

```json
{
  "agentId": "2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11",
  "country": "US",
  "phoneNumber": "+13055550142",
  "label": "Línea de ventas Miami"
}
```

**Response**

```json
{
  "data": {
    "id": "7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e",
    "phoneNumber": "+13055550142",
    "label": "Línea de ventas Miami",
    "isActive": true,
    "agentId": "2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11",
    "agentName": "Sofía - Agendamiento",
    "agentProvisioned": true,
    "ivrEnabled": false,
    "ivrGreeting": null,
    "ivrOptions": [],
    "channels": [
      "voice"
    ],
    "whatsappStatus": null,
    "provider": "twilio",
    "sipHost": null,
    "createdAt": "2026-09-14T15:20:00.000Z",
    "updatedAt": "2026-09-14T15:20:00.000Z"
  }
}
```

**SDK Code**

```python A number picked from the inventory
import requests

url = "https://api.jelliu.co/api/phone-numbers/provision"

payload = {
    "agentId": "2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11",
    "country": "US",
    "phoneNumber": "+13055550142",
    "label": "Línea de ventas Miami"
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript A number picked from the inventory
const url = 'https://api.jelliu.co/api/phone-numbers/provision';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"agentId":"2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11","country":"US","phoneNumber":"+13055550142","label":"Línea de ventas Miami"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go A number picked from the inventory
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.jelliu.co/api/phone-numbers/provision"

	payload := strings.NewReader("{\n  \"agentId\": \"2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11\",\n  \"country\": \"US\",\n  \"phoneNumber\": \"+13055550142\",\n  \"label\": \"Línea de ventas Miami\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby A number picked from the inventory
require 'uri'
require 'net/http'

url = URI("https://api.jelliu.co/api/phone-numbers/provision")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"agentId\": \"2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11\",\n  \"country\": \"US\",\n  \"phoneNumber\": \"+13055550142\",\n  \"label\": \"Línea de ventas Miami\"\n}"

response = http.request(request)
puts response.read_body
```

```java A number picked from the inventory
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.jelliu.co/api/phone-numbers/provision")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"agentId\": \"2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11\",\n  \"country\": \"US\",\n  \"phoneNumber\": \"+13055550142\",\n  \"label\": \"Línea de ventas Miami\"\n}")
  .asString();
```

```php A number picked from the inventory
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.jelliu.co/api/phone-numbers/provision', [
  'body' => '{
  "agentId": "2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11",
  "country": "US",
  "phoneNumber": "+13055550142",
  "label": "Línea de ventas Miami"
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp A number picked from the inventory
using RestSharp;

var client = new RestClient("https://api.jelliu.co/api/phone-numbers/provision");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"agentId\": \"2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11\",\n  \"country\": \"US\",\n  \"phoneNumber\": \"+13055550142\",\n  \"label\": \"Línea de ventas Miami\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift A number picked from the inventory
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "agentId": "2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11",
  "country": "US",
  "phoneNumber": "+13055550142",
  "label": "Línea de ventas Miami"
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.jelliu.co/api/phone-numbers/provision")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```