Geo routing sends a call to a destination chosen from the caller's geographic zone. See 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.
| 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
{
"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
{
"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
{
"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
{
"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
{
"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
{ "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
[
{
"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
{ "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
{
"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