> 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.

# Update a phone number

PATCH https://api.jelliu.co/api/phone-numbers/{id}
Content-Type: application/json

Binds or unbinds the agent, renames the number, activates or deactivates it, and configures the IVR menu. Every field is optional but at least one known field must be present (`No fields to update`; unknown fields are ignored). `null` clears a nullable field, an omitted field is left untouched, and `ivrOptions: []` clears the menu. Changes apply to the next inbound call.

Rules checked against the stored state:

* the bound agent must exist (404), be provisioned (409) and serve every channel the number answers on (400);
* every IVR option's `agentId` must belong to this workspace (404);
* IVR cannot be enabled without at least one option (400), and cannot be switched on for a SIP-trunk number or a WhatsApp line (400): the menu only runs on numbers bought through Jelliu;
* a number currently answered by an agent configured directly in the voice engine that no Jelliu workspace manages cannot be re-bound (409); clear the agent first with `agentId: null`.

An inactive number (`isActive: false`) is not used as outbound caller ID, is refused by `GET /api/phone-numbers/{id}/forwarding-instructions`, and does not count toward the plan's number cap. Deactivating does not release a carrier number or stop its rent.

**Side effects.** Binding an agent registers the number with the voice engine if needed and points it at the agent; `agentId: null` unbinds it there too (best effort). Toggling IVR re-points the carrier number's inbound routing between Jelliu's menu and the voice provider. Writes an audit entry.

**Idempotency.** Safe to retry: sending the same values again converges on the same state.

**Access**

* **Required scope:** `write`. Signed-in users need the admin or member role (viewers are refused).
* **Rate limit:** General API — per plan: 120 to 600 requests/min per workspace. See [Rate limits](/rate-limits).
* **Plan:** Available on every plan.

Reference: https://developer.jelliu.co/api-reference/phone-numbers/patch-phone-number-by-id

## 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

### Path parameters

- `id` (string, required) — The phone number's id (not the E.164 number). Must be a UUID (400 otherwise).

### Body (application/json)

This endpoint expects an object.

- `agentId` (string, optional, nullable) — Agent that answers the number. `null` unbinds it (inbound calls then follow the workspace's fallback routing).
- `label` (string, optional, nullable) — Display name, trimmed. `null` clears it.
- `isActive` (boolean, optional) — `false` stops using the number as caller ID and for forwarding; it stays in the list.
- `ivrEnabled` (boolean, optional) — Turns the phone menu on or off. The menu runs on numbers bought through Jelliu only. Enabling it on a number connected over the business's own SIP trunk, or on a WhatsApp line, is a 400: there is no menu to run there.
- `ivrGreeting` (string, optional, nullable) — What the menu says before the options. Trimmed; `null` clears it.
- `ivrOptions` (list of object, optional) — The full menu, replacing the stored one. Digits must be unique across options (`IVR option digits must be unique`); at most 20 options.
  - `digit` (string, required) — The key the caller presses, a single `0`-`9`, `*` or `#`.
  - `label` (string, required) — Name of the option, trimmed.
  - `agentId` (string, optional, nullable) — Route this option to an agent of this workspace.
  - `department` (string, optional, nullable) — Or route it to a department, resolved to an agent at call time.

## Response

### 200

The updated 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 `id` (`Invalid phone number ID`) or body (`Invalid phone number update`; `details` = zod `flatten()` output), or a routing rule was broken.

- `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).

### 403 Forbidden Error

The API key lacks the `write` scope, the signed-in user is a viewer, or the workspace is suspended.

- `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 number, the agent, or an IVR option's 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 (`AGENT_PROVISIONING`, with `Retry-After: 5`), or the line is held by an agent no Jelliu workspace manages.

- `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 voice engine (`VOICE_AI_ERROR`) or the telephony carrier (`TELEPHONY_ERROR`) rejected the registration, binding or routing change (message replaced by `Internal server error`). The number entry is not updated; 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_patchPhoneNumberById_example

**Request**

```json
undefined
```

**Response**

```json
{
  "data": {
    "id": "7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e",
    "phoneNumber": "+13055550142",
    "label": "Recepción",
    "isActive": true,
    "agentId": "2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11",
    "agentName": "Sofía - Agendamiento",
    "agentProvisioned": true,
    "ivrEnabled": true,
    "ivrGreeting": "Gracias por llamar a Clínica Dental Sonrisas. Para agendar marque 1, para soporte marque 2.",
    "ivrOptions": [
      {
        "digit": "1",
        "label": "Agendar",
        "agentId": "2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11",
        "department": null
      },
      {
        "digit": "2",
        "label": "Soporte",
        "agentId": null,
        "department": "soporte"
      }
    ],
    "channels": [
      "voice"
    ],
    "whatsappStatus": null,
    "provider": "twilio",
    "sipHost": null,
    "createdAt": "2026-09-01T14:20:00.000Z",
    "updatedAt": "2026-09-14T17:12:00.000Z"
  }
}
```

**SDK Code**

```python Phone Numbers_patchPhoneNumberById_example
import requests

url = "https://api.jelliu.co/api/phone-numbers/7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e"

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

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

print(response.json())
```

```javascript Phone Numbers_patchPhoneNumberById_example
const url = 'https://api.jelliu.co/api/phone-numbers/7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e';
const options = {method: 'PATCH', 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_patchPhoneNumberById_example
package main

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

func main() {

	url := "https://api.jelliu.co/api/phone-numbers/7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e"

	req, _ := http.NewRequest("PATCH", 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_patchPhoneNumberById_example
require 'uri'
require 'net/http'

url = URI("https://api.jelliu.co/api/phone-numbers/7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e")

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

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

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

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

HttpResponse<String> response = Unirest.patch("https://api.jelliu.co/api/phone-numbers/7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e")
  .header("Authorization", "Bearer <token>")
  .asString();
```

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

$client = new \GuzzleHttp\Client();

$response = $client->request('PATCH', 'https://api.jelliu.co/api/phone-numbers/7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e', [
  'headers' => [
    'Authorization' => 'Bearer <token>',
  ],
]);

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

```csharp Phone Numbers_patchPhoneNumberById_example
using RestSharp;

var client = new RestClient("https://api.jelliu.co/api/phone-numbers/7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e");
var request = new RestRequest(Method.PATCH);
request.AddHeader("Authorization", "Bearer <token>");
IRestResponse response = client.Execute(request);
```

```swift Phone Numbers_patchPhoneNumberById_example
import Foundation

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

let request = NSMutableURLRequest(url: NSURL(string: "https://api.jelliu.co/api/phone-numbers/7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "PATCH"
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()
```

### Bind a different agent

**Request**

```json
{
  "agentId": "9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b"
}
```

**Response**

```json
{
  "data": {
    "id": "7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e",
    "phoneNumber": "+13055550142",
    "label": "Recepción",
    "isActive": true,
    "agentId": "2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11",
    "agentName": "Sofía - Agendamiento",
    "agentProvisioned": true,
    "ivrEnabled": true,
    "ivrGreeting": "Gracias por llamar a Clínica Dental Sonrisas. Para agendar marque 1, para soporte marque 2.",
    "ivrOptions": [
      {
        "digit": "1",
        "label": "Agendar",
        "agentId": "2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11",
        "department": null
      },
      {
        "digit": "2",
        "label": "Soporte",
        "agentId": null,
        "department": "soporte"
      }
    ],
    "channels": [
      "voice"
    ],
    "whatsappStatus": null,
    "provider": "twilio",
    "sipHost": null,
    "createdAt": "2026-09-01T14:20:00.000Z",
    "updatedAt": "2026-09-14T17:12:00.000Z"
  }
}
```

**SDK Code**

```python Bind a different agent
import requests

url = "https://api.jelliu.co/api/phone-numbers/7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e"

payload = { "agentId": "9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b" }
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

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

print(response.json())
```

```javascript Bind a different agent
const url = 'https://api.jelliu.co/api/phone-numbers/7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e';
const options = {
  method: 'PATCH',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"agentId":"9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b"}'
};

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

```go Bind a different agent
package main

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

func main() {

	url := "https://api.jelliu.co/api/phone-numbers/7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e"

	payload := strings.NewReader("{\n  \"agentId\": \"9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b\"\n}")

	req, _ := http.NewRequest("PATCH", 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 Bind a different agent
require 'uri'
require 'net/http'

url = URI("https://api.jelliu.co/api/phone-numbers/7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e")

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

request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"agentId\": \"9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b\"\n}"

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

```java Bind a different agent
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.patch("https://api.jelliu.co/api/phone-numbers/7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"agentId\": \"9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b\"\n}")
  .asString();
```

```php Bind a different agent
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('PATCH', 'https://api.jelliu.co/api/phone-numbers/7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e', [
  'body' => '{
  "agentId": "9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b"
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

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

```csharp Bind a different agent
using RestSharp;

var client = new RestClient("https://api.jelliu.co/api/phone-numbers/7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e");
var request = new RestRequest(Method.PATCH);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"agentId\": \"9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Bind a different agent
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = ["agentId": "9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b"] as [String : Any]

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

let request = NSMutableURLRequest(url: NSURL(string: "https://api.jelliu.co/api/phone-numbers/7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "PATCH"
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()
```

### Configure an IVR menu

**Request**

```json
{
  "ivrEnabled": true,
  "ivrGreeting": "Gracias por llamar a Clínica Dental Sonrisas. Para agendar marque 1, para soporte marque 2.",
  "ivrOptions": [
    {
      "digit": "1",
      "label": "Agendar",
      "agentId": "2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11"
    },
    {
      "digit": "2",
      "label": "Soporte",
      "department": "soporte"
    }
  ]
}
```

**Response**

```json
{
  "data": {
    "id": "7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e",
    "phoneNumber": "+13055550142",
    "label": "Recepción",
    "isActive": true,
    "agentId": "2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11",
    "agentName": "Sofía - Agendamiento",
    "agentProvisioned": true,
    "ivrEnabled": true,
    "ivrGreeting": "Gracias por llamar a Clínica Dental Sonrisas. Para agendar marque 1, para soporte marque 2.",
    "ivrOptions": [
      {
        "digit": "1",
        "label": "Agendar",
        "agentId": "2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11",
        "department": null
      },
      {
        "digit": "2",
        "label": "Soporte",
        "agentId": null,
        "department": "soporte"
      }
    ],
    "channels": [
      "voice"
    ],
    "whatsappStatus": null,
    "provider": "twilio",
    "sipHost": null,
    "createdAt": "2026-09-01T14:20:00.000Z",
    "updatedAt": "2026-09-14T17:12:00.000Z"
  }
}
```

**SDK Code**

```python Configure an IVR menu
import requests

url = "https://api.jelliu.co/api/phone-numbers/7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e"

payload = {
    "ivrEnabled": True,
    "ivrGreeting": "Gracias por llamar a Clínica Dental Sonrisas. Para agendar marque 1, para soporte marque 2.",
    "ivrOptions": [
        {
            "digit": "1",
            "label": "Agendar",
            "agentId": "2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11"
        },
        {
            "digit": "2",
            "label": "Soporte",
            "department": "soporte"
        }
    ]
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

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

print(response.json())
```

```javascript Configure an IVR menu
const url = 'https://api.jelliu.co/api/phone-numbers/7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e';
const options = {
  method: 'PATCH',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"ivrEnabled":true,"ivrGreeting":"Gracias por llamar a Clínica Dental Sonrisas. Para agendar marque 1, para soporte marque 2.","ivrOptions":[{"digit":"1","label":"Agendar","agentId":"2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11"},{"digit":"2","label":"Soporte","department":"soporte"}]}'
};

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

```go Configure an IVR menu
package main

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

func main() {

	url := "https://api.jelliu.co/api/phone-numbers/7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e"

	payload := strings.NewReader("{\n  \"ivrEnabled\": true,\n  \"ivrGreeting\": \"Gracias por llamar a Clínica Dental Sonrisas. Para agendar marque 1, para soporte marque 2.\",\n  \"ivrOptions\": [\n    {\n      \"digit\": \"1\",\n      \"label\": \"Agendar\",\n      \"agentId\": \"2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11\"\n    },\n    {\n      \"digit\": \"2\",\n      \"label\": \"Soporte\",\n      \"department\": \"soporte\"\n    }\n  ]\n}")

	req, _ := http.NewRequest("PATCH", 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 Configure an IVR menu
require 'uri'
require 'net/http'

url = URI("https://api.jelliu.co/api/phone-numbers/7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e")

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

request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"ivrEnabled\": true,\n  \"ivrGreeting\": \"Gracias por llamar a Clínica Dental Sonrisas. Para agendar marque 1, para soporte marque 2.\",\n  \"ivrOptions\": [\n    {\n      \"digit\": \"1\",\n      \"label\": \"Agendar\",\n      \"agentId\": \"2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11\"\n    },\n    {\n      \"digit\": \"2\",\n      \"label\": \"Soporte\",\n      \"department\": \"soporte\"\n    }\n  ]\n}"

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

```java Configure an IVR menu
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.patch("https://api.jelliu.co/api/phone-numbers/7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"ivrEnabled\": true,\n  \"ivrGreeting\": \"Gracias por llamar a Clínica Dental Sonrisas. Para agendar marque 1, para soporte marque 2.\",\n  \"ivrOptions\": [\n    {\n      \"digit\": \"1\",\n      \"label\": \"Agendar\",\n      \"agentId\": \"2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11\"\n    },\n    {\n      \"digit\": \"2\",\n      \"label\": \"Soporte\",\n      \"department\": \"soporte\"\n    }\n  ]\n}")
  .asString();
```

```php Configure an IVR menu
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('PATCH', 'https://api.jelliu.co/api/phone-numbers/7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e', [
  'body' => '{
  "ivrEnabled": true,
  "ivrGreeting": "Gracias por llamar a Clínica Dental Sonrisas. Para agendar marque 1, para soporte marque 2.",
  "ivrOptions": [
    {
      "digit": "1",
      "label": "Agendar",
      "agentId": "2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11"
    },
    {
      "digit": "2",
      "label": "Soporte",
      "department": "soporte"
    }
  ]
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

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

```csharp Configure an IVR menu
using RestSharp;

var client = new RestClient("https://api.jelliu.co/api/phone-numbers/7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e");
var request = new RestRequest(Method.PATCH);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"ivrEnabled\": true,\n  \"ivrGreeting\": \"Gracias por llamar a Clínica Dental Sonrisas. Para agendar marque 1, para soporte marque 2.\",\n  \"ivrOptions\": [\n    {\n      \"digit\": \"1\",\n      \"label\": \"Agendar\",\n      \"agentId\": \"2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11\"\n    },\n    {\n      \"digit\": \"2\",\n      \"label\": \"Soporte\",\n      \"department\": \"soporte\"\n    }\n  ]\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Configure an IVR menu
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "ivrEnabled": true,
  "ivrGreeting": "Gracias por llamar a Clínica Dental Sonrisas. Para agendar marque 1, para soporte marque 2.",
  "ivrOptions": [
    [
      "digit": "1",
      "label": "Agendar",
      "agentId": "2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11"
    ],
    [
      "digit": "2",
      "label": "Soporte",
      "department": "soporte"
    ]
  ]
] as [String : Any]

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

let request = NSMutableURLRequest(url: NSURL(string: "https://api.jelliu.co/api/phone-numbers/7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "PATCH"
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()
```

### Stop using the number

**Request**

```json
{
  "isActive": false
}
```

**Response**

```json
{
  "data": {
    "id": "7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e",
    "phoneNumber": "+13055550142",
    "label": "Recepción",
    "isActive": true,
    "agentId": "2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11",
    "agentName": "Sofía - Agendamiento",
    "agentProvisioned": true,
    "ivrEnabled": true,
    "ivrGreeting": "Gracias por llamar a Clínica Dental Sonrisas. Para agendar marque 1, para soporte marque 2.",
    "ivrOptions": [
      {
        "digit": "1",
        "label": "Agendar",
        "agentId": "2f2d8b4d-aa6f-41e0-9d3e-4d61e1b07a11",
        "department": null
      },
      {
        "digit": "2",
        "label": "Soporte",
        "agentId": null,
        "department": "soporte"
      }
    ],
    "channels": [
      "voice"
    ],
    "whatsappStatus": null,
    "provider": "twilio",
    "sipHost": null,
    "createdAt": "2026-09-01T14:20:00.000Z",
    "updatedAt": "2026-09-14T17:12:00.000Z"
  }
}
```

**SDK Code**

```python Stop using the number
import requests

url = "https://api.jelliu.co/api/phone-numbers/7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e"

payload = { "isActive": False }
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

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

print(response.json())
```

```javascript Stop using the number
const url = 'https://api.jelliu.co/api/phone-numbers/7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e';
const options = {
  method: 'PATCH',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"isActive":false}'
};

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

```go Stop using the number
package main

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

func main() {

	url := "https://api.jelliu.co/api/phone-numbers/7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e"

	payload := strings.NewReader("{\n  \"isActive\": false\n}")

	req, _ := http.NewRequest("PATCH", 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 Stop using the number
require 'uri'
require 'net/http'

url = URI("https://api.jelliu.co/api/phone-numbers/7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e")

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

request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"isActive\": false\n}"

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

```java Stop using the number
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.patch("https://api.jelliu.co/api/phone-numbers/7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"isActive\": false\n}")
  .asString();
```

```php Stop using the number
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('PATCH', 'https://api.jelliu.co/api/phone-numbers/7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e', [
  'body' => '{
  "isActive": false
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

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

```csharp Stop using the number
using RestSharp;

var client = new RestClient("https://api.jelliu.co/api/phone-numbers/7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e");
var request = new RestRequest(Method.PATCH);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"isActive\": false\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Stop using the number
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = ["isActive": false] as [String : Any]

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

let request = NSMutableURLRequest(url: NSURL(string: "https://api.jelliu.co/api/phone-numbers/7b1e9a3c-2d4f-4a8b-9c6e-1f0a2b3c4d5e")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "PATCH"
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()
```