---
title: Smart Routings — CTI
excerpt: Manage CTI tables that map an incoming number to a destination, import and export their entries, and look up the destination for a caller.
order: 10
---

A CTI is a lookup table that maps an origin (typically the caller's number) to a destination. See [Smart Routings](/en/docs/cx-api/smart-routings) for the concepts shared by every Smart Routings endpoint.

All endpoints in this section are **workspace-scoped** and require the `client` OAuth scope, unless stated otherwise. The lookup endpoint also accepts the `cfd` scope.

**Headers:** `Authorization: Bearer {workspace-token}`

**Required query parameter:** `customer_account` — the customer account to act on. See [Selecting the customer account](/en/docs/cx-api/smart-routings#selecting-the-customer-account).

| Permission | Required for |
|---|---|
| `cti.view` | Reading CTIs and their destinations |
| `cti.create` | Creating CTIs, importing destinations, bulk-deleting destinations |
| `cti.edit` | Updating a CTI, regenerating its token, creating, updating or deleting its destinations |
| `cti.delete` | Deleting a CTI |
| `cti.lookup` | Looking up a destination |

---

## CTIs

### The CTI object

| Field | Type | Description |
|---|---|---|
| `id` | integer | CTI ID |
| `customer_id` | integer | Customer the CTI belongs to |
| `name` | string | CTI name |
| `token` | string | 80-character token used by the token lookup endpoint (see [Lookup](#lookup)). Generated by CX-Engine, cannot be set |
| `token_lookup_url` | string | Ready-to-use token lookup URL, ending with the `%CallerNumber%` placeholder |
| `created_at` | string | Creation date (ISO 8601) |
| `updated_at` | string | Last update date (ISO 8601) |

> [!WARNING]
> Anyone who knows a CTI's `token` can read its destinations without authentication. Treat it as a secret and regenerate it if it leaks.

---

### GET /api/smart-routings/ctis

Returns a paginated list of the customer's CTIs, most recently updated first. Each CTI includes a `destinations_count` field.

**Query parameters**

| Parameter | Description |
|---|---|
| `filter[name]` | Filter by name (partial match) |
| `filter[token]` | Filter by token (partial match) |
| `include` | Comma-separated relationships to sideload: `customer`, `destinations` |
| `sort` | Sort field: `id`, `name`, `created_at`, `updated_at`. Prefix with `-` for descending. Default: `-updated_at` |
| `per_page` | Results per page (default: 20) |
| `page` | Page number |

**Response `200`** — paginated response

```json
{
  "data": [
    {
      "id": 4,
      "customer_id": 12,
      "name": "VIP callers",
      "token": "q8Zb3kV0yR1mN7tXwP2sL5cH9dF4gJ6aE0uI3oK8vB1nM5zQ7xC2yT4rW6eS9pD0hG3jL8fA1kU5iO7mN2b",
      "created_at": "2024-03-04T10:12:00.000000Z",
      "updated_at": "2024-06-18T08:45:00.000000Z",
      "destinations_count": 42,
      "token_lookup_url": "https://acme.cx-engine.app/api/smart-routings/ctis/t/q8Zb3kV0yR1m.../%CallerNumber%"
    }
  ],
  "current_page": 1,
  "last_page": 1,
  "per_page": 20,
  "total": 1
}
```

---

### GET /api/smart-routings/ctis/{cti}

Returns a single CTI with its `customer` and `destinations` loaded.

**Response `200`**

```json
{
  "id": 4,
  "customer_id": 12,
  "name": "VIP callers",
  "token": "q8Zb3kV0yR1m...",
  "created_at": "2024-03-04T10:12:00.000000Z",
  "updated_at": "2024-06-18T08:45:00.000000Z",
  "token_lookup_url": "https://acme.cx-engine.app/api/smart-routings/ctis/t/q8Zb3kV0yR1m.../%CallerNumber%",
  "customer": { ... },
  "destinations": [
    {
      "id": 101,
      "cti_id": 4,
      "origin": "+33612345678",
      "destination": "201",
      "created_at": "2024-03-04T10:15:00.000000Z",
      "updated_at": "2024-03-04T10:15:00.000000Z"
    }
  ]
}
```

**Response `403`** — the CTI belongs to another customer or the permission is missing

---

### POST /api/smart-routings/ctis

Creates a CTI. Its `token` is generated automatically.

**Request body**

| Field | Type | Required | Description |
|---|---|---|---|
| `name` | string | yes | CTI name (max 50 characters) |

**Response `201`** — the created CTI object

---

### PUT /api/smart-routings/ctis/{cti}

Updates a CTI. `PATCH` is also accepted. The `token` cannot be changed here: use the regenerate endpoint below.

**Request body**

| Field | Type | Required | Description |
|---|---|---|---|
| `name` | string | no | CTI name (max 50 characters) |

**Response `201`** — the updated CTI object

---

### POST /api/smart-routings/ctis/{cti}/regenerate-token

Replaces the CTI's token with a new random 80-character token. The previous token and its lookup URL stop working immediately.

**Response `200`** — the updated CTI object, including the new `token` and `token_lookup_url`

---

### DELETE /api/smart-routings/ctis/{cti}

Deletes a CTI and all of its destinations.

**Response `200`**

```json
{ "response": "element deleted" }
```

---

## Destinations

A destination maps one `origin` to one `destination` inside a CTI.

| Field | Type | Description |
|---|---|---|
| `id` | integer | Destination ID |
| `cti_id` | integer | Parent CTI |
| `origin` | string | Value matched during lookup, e.g. the caller's number |
| `destination` | string | Value returned when the origin matches, e.g. an extension or a number |
| `created_at` | string | Creation date (ISO 8601) |
| `updated_at` | string | Last update date (ISO 8601) |

---

### GET /api/smart-routings/ctis/{cti}/destinations

Returns every destination of the CTI. This list is not paginated.

**Response `200`**

```json
[
  {
    "id": 101,
    "cti_id": 4,
    "origin": "+33612345678",
    "destination": "201",
    "created_at": "2024-03-04T10:15:00.000000Z",
    "updated_at": "2024-03-04T10:15:00.000000Z"
  }
]
```

---

### GET /api/smart-routings/ctis/{cti}/destinations/{destination}

Returns a single destination.

**Response `200`** — destination object

**Response `404`** — the destination does not belong to this CTI

---

### POST /api/smart-routings/ctis/{cti}/destinations

Adds a destination to the CTI.

**Request body**

| Field | Type | Required | Description |
|---|---|---|---|
| `origin` | string | yes | Origin to match (max 50 characters) |
| `destination` | string | yes | Destination to return (max 50 characters) |

**Response `201`** — the created destination object

---

### PUT /api/smart-routings/ctis/{cti}/destinations/{destination}

Updates a destination. `PATCH` is also accepted.

**Request body**

| Field | Type | Required | Description |
|---|---|---|---|
| `origin` | string | no | Origin to match (max 50 characters) |
| `destination` | string | no | Destination to return (max 50 characters) |

**Response `201`** — the updated destination object

---

### DELETE /api/smart-routings/ctis/{cti}/destinations/{destination}

Deletes a destination.

**Response `200`**

```json
{ "response": "element deleted" }
```

---

## Bulk operations

### GET /api/smart-routings/ctis/export

Downloads the customer's CTI destinations as an Excel file (`cti_destinations.xlsx`).

**Query parameters**

| Parameter | Type | Required | Description |
|---|---|---|---|
| `cti_id` | integer | no | Export only the destinations of this CTI |

The file contains the columns `id`, `cti_id`, `origin` and `destination`.

---

### POST /api/smart-routings/ctis/import

Imports CTI destinations from a spreadsheet. Send the request as `multipart/form-data`.

**Request body**

| Field | Type | Required | Description |
|---|---|---|---|
| `customer_id` | integer | yes | Customer ID. Must match the selected customer account |
| `document` | file | yes | Spreadsheet (Excel, or CSV with `;` as delimiter) with a heading row |

The heading row uses the same columns as the export: `id`, `cti_id`, `origin`, `destination`.

- A row with an existing `id` updates that destination; a row without `id` creates a new one.
- Rows whose CTI belongs to another customer, or with an empty `origin` or `destination`, are skipped.

**Response `200`**

```json
{ "response": "Import successful." }
```

---

### DELETE /api/smart-routings/ctis/bulk

Deletes CTI destinations in bulk. The CTIs themselves are kept.

**Query parameters**

| Parameter | Type | Required | Description |
|---|---|---|---|
| `cti_id` | integer | no | Delete only the destinations of this CTI |

> [!WARNING]
> Without `cti_id`, this deletes the destinations of **every** CTI of the customer.

**Response `200`**

```json
{ "response": "elements deleted" }
```

---

## Lookup

### GET /api/smart-routings/ctis/lookup

Returns the destination matching an origin in a CTI. Accepts the `client` or `cfd` OAuth scope. Requires the `cti.lookup` permission.

**Query parameters**

| Parameter | Type | Required | Description |
|---|---|---|---|
| `customer_account` | string | yes* | Customer account |
| `customer_id` | integer | yes* | Customer ID |
| `cti_id` | integer | yes** | CTI ID |
| `cti_name` | string | yes** | CTI name |
| `cti_token` | string | yes** | CTI token |
| `origin` | string | yes | Origin to look up, e.g. the caller's number |

*One of `customer_account` or `customer_id` is required.  
**One of `cti_id`, `cti_name` or `cti_token` is required. When several are sent, `cti_id` wins, then `cti_token`, then `cti_name`.

**Response `200`** — destination object

```json
{
  "id": 101,
  "cti_id": 4,
  "origin": "+33612345678",
  "destination": "201",
  "created_at": "2024-03-04T10:15:00.000000Z",
  "updated_at": "2024-03-04T10:15:00.000000Z"
}
```

**Response `404`** — no customer, CTI or destination matches the parameters

```json
{ "message": "No destination found matching given parameters." }
```

---

### GET /api/smart-routings/ctis/t/{token}/{origin}

Token-based lookup, designed for PBX or CTI tools that can only call a plain URL. **No `Authorization` header is required**: the CTI's `token` authenticates the request and identifies the customer, so `customer_account` is not needed either. Use the CTI's `token_lookup_url` and replace `%CallerNumber%` with the caller's number.

```
GET /api/smart-routings/ctis/t/q8Zb3kV0yR1m.../+33612345678
```

**Response `200`**

```json
{
  "id": 101,
  "origin": "+33612345678",
  "destination": "201"
}
```

**Response `404`** — unknown token, or no destination for this origin
