---
title: Smart Routings — Routing Contacts
excerpt: Manage the routing contacts used by Smart Routings, their custom fields, and import or export them in bulk.
order: 11
---

Routing contacts are the directory Smart Routings uses to recognise a caller and route them to a dedicated 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.

**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 |
|---|---|
| `routing-contact.view` | Reading and exporting contacts |
| `routing-contact.create` | Creating, importing and bulk-deleting contacts |
| `routing-contact.edit` | Updating contacts |
| `routing-contact.delete` | Deleting a contact |
| `routing-contact-field-definition.view` | Reading field definitions and their options |
| `routing-contact-field-definition.create` | Creating field definitions |
| `routing-contact-field-definition.edit` | Updating field definitions and managing their options |

---

## Routing Contacts

### The contact object

| Field | Type | Description |
|---|---|---|
| `id` | integer | Contact ID |
| `customer_id` | integer | Customer the contact belongs to |
| `id_code` | string\|null | Your own identifier for the contact |
| `language_code` | string\|null | Contact language code |
| `company` | string\|null | Company name |
| `first_name` | string\|null | First name |
| `last_name` | string\|null | Last name |
| `emails` | string\|null | Email address(es) used to recognise the contact |
| `telecoms` | string\|null | Phone number(s) used to recognise the contact |
| `email_destination` | string\|null | Email destination for this contact |
| `telecom_destination` | string\|null | Phone destination for this contact |
| `fields` | array | Custom field values (see below) |
| `created_at` | string | Creation date (ISO 8601) |
| `updated_at` | string | Last update date (ISO 8601) |

Each entry of `fields` carries its value together with its definition, so no second request is needed to resolve labels:

| Field | Type | Description |
|---|---|---|
| `code` | string | Field definition code |
| `label` | string\|null | Field definition label |
| `type` | string | `telecom`, `email`, `boolean` or `select` |
| `value` | string | Stored value |
| `options` | array\|null | For `select` fields, the available options as `{ "name", "value" }` pairs; `null` otherwise |

---

### GET /api/smart-routings/contacts

Returns a paginated list of the customer's routing contacts, newest first.

**Query parameters**

| Parameter | Description |
|---|---|
| `filter[id_code]` | Filter by ID code (partial match) |
| `filter[company]` | Filter by company (partial match) |
| `filter[first_name]` | Filter by first name (partial match) |
| `filter[last_name]` | Filter by last name (partial match) |
| `filter[emails]` | Filter by emails (partial match) |
| `filter[telecoms]` | Filter by phone numbers (partial match) |
| `filter[telecom_destination]` | Filter by phone destination (exact match) |
| `filter[language_code]` | Filter by language code (exact match) |
| `filter[search]` | Search in company, first name, last name, phone numbers, phone destination and email destination |
| `sort` | Sort field: `id`, `company`, `first_name`, `last_name`, `created_at`. Prefix with `-` for descending. Default: `-created_at` |
| `per_page` | Results per page (default: 20) |
| `page` | Page number |

**Response `200`** — paginated response

```json
{
  "data": [
    {
      "id": 57,
      "customer_id": 12,
      "id_code": "CUST-0042",
      "language_code": "fr",
      "company": "Acme Corp",
      "first_name": "Alice",
      "last_name": "Martin",
      "emails": "alice.martin@acme.com",
      "telecoms": "+33612345678",
      "email_destination": null,
      "telecom_destination": "201",
      "created_at": "2024-05-02T14:20:00.000000Z",
      "updated_at": "2024-05-02T14:20:00.000000Z",
      "fields": [
        {
          "code": "vip",
          "label": "VIP",
          "type": "boolean",
          "value": "1",
          "options": null
        },
        {
          "code": "segment",
          "label": "Segment",
          "type": "select",
          "value": "gold",
          "options": [
            { "name": "Gold", "value": "gold" },
            { "name": "Silver", "value": "silver" }
          ]
        }
      ]
    }
  ],
  "current_page": 1,
  "last_page": 1,
  "per_page": 20,
  "total": 1
}
```

---

### GET /api/smart-routings/contacts/{contact}

Returns a single routing contact, with its `fields`.

**Response `200`** — contact object

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

---

### POST /api/smart-routings/contacts

Creates a routing contact.

**Request body**

| Field | Type | Required | Description |
|---|---|---|---|
| `id_code` | string | no | Your own identifier for the contact |
| `language_code` | string | no | Language code |
| `company` | string | no | Company name |
| `first_name` | string | no | First name |
| `last_name` | string | no | Last name |
| `emails` | string | no | Email address(es) |
| `telecoms` | string | no | Phone number(s) |
| `email_destination` | string | no | Email destination |
| `telecom_destination` | string | no | Phone destination |
| `fields` | array | no | Custom field values |
| `fields[].code` | string | yes | Field definition code (letters, digits, `-` and `_` only) |
| `fields[].value` | string | yes | Value to store |
| `fields[].type` | string | no | `telecom` or `email`. Only used when the code does not exist yet (see below) |

When a `fields` entry references a code that has no field definition yet:

- with `type` set to `telecom` or `email`, the definition is created automatically;
- otherwise the request fails with `422`. `boolean` and `select` fields must be created first with the [field definitions](#field-definitions) endpoints.

**Example**

```json
{
  "company": "Acme Corp",
  "first_name": "Alice",
  "last_name": "Martin",
  "telecoms": "+33612345678",
  "telecom_destination": "201",
  "fields": [
    { "code": "segment", "value": "gold" },
    { "code": "backup_line", "value": "+33142000000", "type": "telecom" }
  ]
}
```

**Response `201`** — the created contact object, with its `fields`

**Response `422`** — unknown `boolean` or `select` field code

```json
{
  "response": "Unknown field code \"vip\". Boolean/select fields must be created via the field-definition endpoint first.",
  "hint": null
}
```

---

### PUT /api/smart-routings/contacts/{contact}

Updates a routing contact. `PATCH` is also accepted. Accepts the same fields as creation, all optional.

Values sent in `fields` are created or replaced one by one; custom fields you do not send keep their current value.

**Response `201`** — the updated contact object, with its `fields`

---

### DELETE /api/smart-routings/contacts/{contact}

Deletes a routing contact.

**Response `200`**

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

---

## Bulk operations

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

Downloads the customer's routing contacts as an Excel file (`routing_contacts.xlsx`), sorted by company.

The file contains the columns `id`, `id_code`, `language_code`, `company`, `first_name`, `last_name`, `emails`, `telecoms`, `email_destination` and `telecom_destination`, followed by one column per [field definition](#field-definitions) of the customer (active or not), ordered by `position` and headed by the definition `code`. Each cell holds the contact's value for that field, or is empty. Every cell is written as text, so phone numbers keep their leading `+` or `0`.

| id | company | telecoms | telecom_destination | vip | segment | destination2 |
|---|---|---|---|---|---|---|
| 12 | Acme | +33612345678 | 200 | 1 | gold | +33600000000 |

A definition whose `code` is one of the base column names is not exported.

---

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

Imports routing contacts 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: start from an export to build the file.

- A row with an existing `id` updates that contact; a row without `id` creates a new one.
- Rows whose `id` belongs to another customer are skipped.
- Rows without any of `id_code`, `company`, `telecoms` or `emails` are skipped.
- A column headed with the `code` of a field definition sets that custom field. An empty cell removes the contact's value for that field. A field without a column in the file is left unchanged.
- Columns matching no field definition are ignored: create the definitions first.
- `boolean` fields accept `1`, `true`, `yes`, `oui` (stored as `1`) and `0`, `false`, `no`, `non` (stored as `0`).
- `select` fields accept an option `value`, or an option `name` which is stored as its value.

The whole file is validated before anything is written. If a row holds an invalid custom field value, nothing is imported and the API answers `422`.

**Response `200`**

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

---

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

Deletes routing contacts in bulk, along with their custom field values.

**Request body**

| Field | Type | Required | Description |
|---|---|---|---|
| `ids` | integer[] | no | IDs of the contacts to delete |

> [!WARNING]
> Without `ids`, this deletes **every** routing contact of the customer.

**Response `200`**

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

---

## Field Definitions

Field definitions describe the custom fields available on the customer's routing contacts. A definition cannot be deleted, because a call flow may still reference its `code`: set `active` to `false` to hide it instead.

### The field definition object

| Field | Type | Description |
|---|---|---|
| `id` | integer | Definition ID |
| `customer_id` | integer | Customer the definition belongs to |
| `code` | string | Unique code per customer, used in contact `fields` and call flows. Cannot be changed |
| `label` | string\|null | Display label |
| `type` | string | `telecom`, `email`, `boolean` or `select`. Cannot be changed |
| `position` | integer | Display order |
| `active` | boolean | Whether the field is shown in the contact form |
| `options` | array | Options of a `select` field (loaded on list and show) |
| `created_at` | string | Creation date (ISO 8601) |
| `updated_at` | string | Last update date (ISO 8601) |

---

### GET /api/smart-routings/contact-field-definitions

Returns a paginated list of the customer's field definitions, with their `options`, ordered by `position`.

**Query parameters**

| Parameter | Description |
|---|---|
| `filter[code]` | Filter by code (partial match) |
| `filter[label]` | Filter by label (partial match) |
| `filter[type]` | Filter by type |
| `filter[active]` | Filter by active state |
| `sort` | Sort field: `id`, `code`, `label`, `type`, `position`, `created_at`. Prefix with `-` for descending. Default: `position` |
| `per_page` | Results per page (default: 20) |
| `page` | Page number |

**Response `200`** — paginated response

```json
{
  "data": [
    {
      "id": 3,
      "customer_id": 12,
      "code": "segment",
      "label": "Segment",
      "type": "select",
      "position": 1,
      "active": true,
      "created_at": "2024-05-01T09:00:00.000000Z",
      "updated_at": "2024-05-01T09:00:00.000000Z",
      "options": [
        {
          "id": 8,
          "routing_contact_field_definition_id": 3,
          "name": "Gold",
          "value": "gold",
          "created_at": "2024-05-01T09:01:00.000000Z",
          "updated_at": "2024-05-01T09:01:00.000000Z"
        }
      ]
    }
  ],
  "current_page": 1,
  "last_page": 1,
  "per_page": 20,
  "total": 1
}
```

---

### GET /api/smart-routings/contact-field-definitions/{definition}

Returns a single field definition with its `options`.

**Response `200`** — field definition object

---

### POST /api/smart-routings/contact-field-definitions

Creates a field definition.

**Request body**

| Field | Type | Required | Description |
|---|---|---|---|
| `code` | string | yes | Unique code (max 255 characters; letters, digits, `-` and `_` only) |
| `type` | string | yes | `telecom`, `email`, `boolean` or `select` |
| `label` | string | no | Display label (max 255 characters) |
| `position` | integer | no | Display order (min 0). Defaults to after the last definition |
| `active` | boolean | no | Whether the field is shown in the contact form |

**Response `201`** — the created field definition object

---

### PUT /api/smart-routings/contact-field-definitions/{definition}

Updates a field definition. `PATCH` is also accepted. `code` and `type` cannot be changed.

**Request body**

| Field | Type | Required | Description |
|---|---|---|---|
| `label` | string | no | Display label (max 255 characters) |
| `position` | integer | no | Display order (min 0) |
| `active` | boolean | no | Whether the field is shown in the contact form |

**Response `201`** — the updated field definition object

---

## Field Options

Options are the allowed values of a `select` field definition. Calling these endpoints on a definition of another type returns `422`.

```json
{ "response": "This field cannot have options.", "hint": null }
```

### GET /api/smart-routings/contact-field-definitions/{definition}/options

Returns every option of the definition. This list is not paginated.

**Response `200`**

```json
[
  {
    "id": 8,
    "routing_contact_field_definition_id": 3,
    "name": "Gold",
    "value": "gold",
    "created_at": "2024-05-01T09:01:00.000000Z",
    "updated_at": "2024-05-01T09:01:00.000000Z"
  }
]
```

---

### GET /api/smart-routings/contact-field-definitions/{definition}/options/{option}

Returns a single option.

**Response `200`** — option object

**Response `403`** — the option does not belong to this definition

---

### POST /api/smart-routings/contact-field-definitions/{definition}/options

Adds an option to a `select` definition.

**Request body**

| Field | Type | Required | Description |
|---|---|---|---|
| `name` | string | yes | Display name (max 255 characters) |
| `value` | string | yes | Stored value (max 255 characters) |

**Response `201`** — the full, updated list of the definition's options

---

### PUT /api/smart-routings/contact-field-definitions/{definition}/options/{option}

Updates an option. `PATCH` is also accepted.

**Request body**

| Field | Type | Required | Description |
|---|---|---|---|
| `name` | string | no | Display name (max 255 characters) |
| `value` | string | no | Stored value (max 255 characters) |

**Response `201`** — the full, updated list of the definition's options

---

### DELETE /api/smart-routings/contact-field-definitions/{definition}/options/{option}

Deletes an option.

**Response `200`**

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