---
title: Smart Routings — Geo Routing
excerpt: Manage geographic routing lists and their destinations, browse geographic models, and look up the destination for a caller's zone or number.
order: 12
---

Geo routing sends a call to a destination chosen from the caller's geographic zone. 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. 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 |
|---|---|
| `geo-routing-list.view` | Reading lists, destinations and models |
| `geo-routing-list.create` | Creating lists |
| `geo-routing-list.edit` | Updating lists and creating, updating or deleting destinations |
| `geo-routing-list.delete` | Deleting lists |
| `geo-routing-list.lookup` | Looking up a destination |

---

## Geographic Models

A geographic model defines the set of zones a list can route on, and how a phone number is matched to a zone. Models are shared by every customer in the workspace and are read-only through the API. Built-in models include French districts (zones `01` to `98`), international prefixes (ISO 3166-1 alpha-2 codes) and European Union states.

### GET /api/smart-routings/geo/models

Returns a paginated list of geographic models.

**Query parameters**

| Parameter | Description |
|---|---|
| `per_page` | Results per page (default: 20) |
| `page` | Page number |

**Response `200`** — paginated response

```json
{
  "data": [
    {
      "id": 1,
      "name": "French Districts",
      "created_at": "2024-01-15T09:30:00.000000Z",
      "updated_at": "2024-01-15T09:30:00.000000Z"
    }
  ],
  "current_page": 1,
  "last_page": 1,
  "per_page": 20,
  "total": 3
}
```

---

### GET /api/smart-routings/geo/models/{id}

Returns a single geographic model, including the list of zones it defines.

**Response `200`**

```json
{
  "id": 1,
  "name": "French Districts",
  "zones": ["01", "02", "03", "...", "98"],
  "created_at": "2024-01-15T09:30:00.000000Z",
  "updated_at": "2024-01-15T09:30:00.000000Z"
}
```

---

## Geo Routing Lists

A list ties a geographic model to a set of destinations. Each list has a numeric `list_id`, unique per customer, and up to four fallback destinations used when no destination matches the caller's zone.

### GET /api/smart-routings/geo/lists

Returns a paginated list of the customer's geo routing lists. Each list includes its model's `id` and `name`.

**Query parameters**

| Parameter | Description |
|---|---|
| `filter[list_id]` | Filter by list ID |
| `filter[list_name]` | Filter by list name |
| `filter[geo_routing_model_id]` | Filter by geographic model ID (exact match) |
| `sort` | Sort field: `id`, `list_id`, `list_name`, `created_at`. Prefix with `-` for descending. Default: `list_id`, then `list_name` |
| `per_page` | Results per page (default: 20) |
| `page` | Page number |

**Response `200`** — paginated response

```json
{
  "data": [
    {
      "id": 4,
      "customer_id": 12,
      "geo_routing_model_id": 1,
      "list_id": 1,
      "list_name": "Sales France",
      "fallback_destination_1": "100",
      "fallback_destination_2": null,
      "fallback_destination_3": null,
      "fallback_destination_4": null,
      "created_at": "2024-03-02T10:00:00.000000Z",
      "updated_at": "2024-03-02T10:00:00.000000Z",
      "model": { "id": 1, "name": "French Districts" }
    }
  ],
  "current_page": 1,
  "last_page": 1,
  "per_page": 20,
  "total": 1
}
```

---

### GET /api/smart-routings/geo/lists/{id}

Returns a single list with its full geographic model and `orphan_zones`: the model's zones that no destination of this list covers yet.

**Response `200`**

```json
{
  "id": 4,
  "customer_id": 12,
  "geo_routing_model_id": 1,
  "list_id": 1,
  "list_name": "Sales France",
  "fallback_destination_1": "100",
  "fallback_destination_2": null,
  "fallback_destination_3": null,
  "fallback_destination_4": null,
  "created_at": "2024-03-02T10:00:00.000000Z",
  "updated_at": "2024-03-02T10:00:00.000000Z",
  "orphan_zones": ["01", "02", "04"],
  "model": {
    "id": 1,
    "name": "French Districts",
    "zones": ["01", "02", "03", "...", "98"],
    "created_at": "2024-01-15T09:30:00.000000Z",
    "updated_at": "2024-01-15T09:30:00.000000Z"
  }
}
```

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

---

### POST /api/smart-routings/geo/lists

Creates a geo routing list for the customer.

**Request body**

| Field | Type | Required | Description |
|---|---|---|---|
| `list_name` | string | yes | List name (max 50 characters) |
| `geo_routing_model_id` | integer | yes | ID of an existing geographic model |
| `list_id` | integer | no | Numeric list identifier, unique per customer. If omitted, the next available number is assigned |
| `fallback_destination_1` | string | no | First fallback destination (max 255 characters) |
| `fallback_destination_2` | string | no | Second fallback destination |
| `fallback_destination_3` | string | no | Third fallback destination |
| `fallback_destination_4` | string | no | Fourth fallback destination |

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

**Response `400`** — validation failure, or another list of the customer already uses this `list_id`

```json
{
  "response": "bad request: please check body parameters.",
  "hint": ["Another list with the same list_id exists."]
}
```

---

### PUT /api/smart-routings/geo/lists/{id}

Updates a list. All fields from the create endpoint are accepted and optional. `PATCH` is also accepted.

When `list_id` is omitted (or `null`), the list keeps its current `list_id`. Send it only to renumber the list.

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

**Response `400`** — validation failure, or another list of the customer already uses this `list_id`

---

### DELETE /api/smart-routings/geo/lists/{id}

Deletes a list together with all its destinations.

**Response `200`**

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

---

## List Destinations

A destination maps one or more zones of the list's model to up to four destinations. A zone can belong to only one destination of a list.

### GET /api/smart-routings/geo/lists/{list}/destinations

Returns every destination of the list (not paginated).

**Response `200`**

```json
[
  {
    "id": 21,
    "geo_routing_list_id": 4,
    "nickname": "Paris area",
    "zones": ["75", "77", "78", "91", "92", "93", "94", "95"],
    "destination_1": "201",
    "destination_2": "202",
    "destination_3": null,
    "destination_4": null,
    "created_at": "2024-03-02T10:05:00.000000Z",
    "updated_at": "2024-03-02T10:05:00.000000Z"
  }
]
```

---

### GET /api/smart-routings/geo/lists/{list}/destinations/{id}

Returns a single destination.

**Response `200`** — destination object

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

---

### POST /api/smart-routings/geo/lists/{list}/destinations

Adds a destination to the list.

**Request body**

| Field | Type | Required | Description |
|---|---|---|---|
| `zones` | array | yes | At least one zone. Each zone must exist in the list's geographic model and not be used by another destination of the list |
| `nickname` | string | no | Display name (max 255 characters) |
| `destination_1` | string | no | First destination (max 255 characters) |
| `destination_2` | string | no | Second destination |
| `destination_3` | string | no | Third destination |
| `destination_4` | string | no | Fourth destination |

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

**Response `400`** — validation failure, or invalid zones. The message lists the zones at fault:

- `Some selected zones are unknown to the selected model (99).`
- `Some selected zones are already used (75, 92).`

---

### PUT /api/smart-routings/geo/lists/{list}/destinations/{id}

Updates a destination. All fields from the create endpoint are accepted and optional; zones are checked the same way. `PATCH` is also accepted.

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

**Response `400`** — validation failure or invalid zones

---

### DELETE /api/smart-routings/geo/lists/{list}/destinations/{id}

Deletes a destination. Its zones become available again.

**Response `200`**

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

---

## Lookup

### GET /api/smart-routings/geo/destinations/lookup

Finds the destinations to use for a caller. Typically called from a 3CX call flow. Accepts the `client` or `cfd` scope and requires the `geo-routing-list.lookup` permission.

The customer must match the customer account selected for the request.

**Query parameters**

| Parameter | Type | Required | Description |
|---|---|---|---|
| `customer_account` | string | yes* | Customer account |
| `customer_id` | integer | yes* | Customer ID |
| `list_id` | integer | yes** | The list's numeric `list_id` |
| `list_name` | string | yes** | The list's name |
| `number` | string | yes*** | Caller's phone number. The zone is derived from it using the list's geographic model |
| `zone` | string | yes*** | Zone to look up directly (e.g. `75`) |

*One of `customer_account` or `customer_id` is required.  
**One of `list_id` or `list_name` is required.  
***One of `number` or `zone` is required. When both are sent, the zone derived from `number` takes precedence if the number can be parsed.

If a destination of the list covers the zone, its destinations are returned with `fallback: false`. Otherwise the list's fallback destinations are returned with `fallback: true`.

**Response `200`**

```json
{
  "destination1": "201",
  "destination2": "202",
  "destination3": null,
  "destination4": null,
  "fallback": false
}
```

**Response `400`** — missing parameters

**Response `404`** — no matching customer, no matching list, or no destination (and no fallback destination) configured
