Clients
Manage CRM contacts — individuals or companies — in your tenant.
A client is a CRM contact. Used to attribute trips to a specific party, drive email automations, and reconcile invoices.
| Method | Path | Scope |
|---|---|---|
| GET | /api/v1/clients | clients:read |
| POST | /api/v1/clients | clients:write |
| GET | /api/v1/clients/{id} | clients:read |
The Client object:
| Field | Type | Notes |
|---|---|---|
id | string | Opaque client id. |
kind | enum | individual or company. |
displayName | string | Human-readable name. |
legalName | string | null | Used on invoices when set. |
email | string | null | |
phone | string | null | |
countryIso | string | null | ISO 3166-1 alpha-2. |
language | string | null | BCP 47-ish (e.g. en, fr). |
currency | string | null | ISO 4217. |
vatId | string | null | |
tags | string[] | Free-form, max 20 tags, each ≤ 40 chars. |
notes | string | null | Internal, never shown to the client. |
archivedAt | ISO 8601 | null | Set when the client was archived. |
createdAt | ISO 8601 | |
updatedAt | ISO 8601 |
A successful POST also emits a client.created webhook event to any active subscriptions for the tenant.
GET /api/v1/clients
List clients in the tenant. Cursor-paginated.
Required scope — clients:read
Query parameters
| Name | Type | Default | Notes |
|---|---|---|---|
limit | integer | 50 | Max 100. |
cursor | string | — | From a previous response. |
kind | enum | — | individual or company. Unknown values are ignored. |
archived | enum | — | true returns only archived; false returns only non-archived; omitted returns both. |
Response 200
{
"data": [ /* Client[] */ ],
"meta": { "cursor": "cli_a1b2c3" | null, "hasMore": true | false }
}Errors — 401 unauthorized, 403 (scope-required, or plan-required when the plan has no API access), 429 rate-limited.
/api/v1/clientsTry itRequests are proxied through this docs site so CORS doesn't block the call. Use a sandbox token if you don't want test calls hitting live data.
Query parameters
limitcursorkindarchivedGET /api/v1/clientsPOST /api/v1/clients
Create a new CRM contact. Triggers a client.created webhook on success.
Required scope — clients:write
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
kind | enum | yes | individual or company. |
displayName | string | yes | 1–200 chars. |
legalName | string | no | ≤ 200 chars. |
email | string | no | Valid email, ≤ 320 chars. |
phone | string | no | ≤ 40 chars. |
countryIso | string | no | Exactly 2 chars, ISO 3166-1 alpha-2. |
language | string | no | ≤ 20 chars. |
currency | string | no | Exactly 3 chars, ISO 4217. |
vatId | string | no | ≤ 40 chars. |
notes | string | no | ≤ 2000 chars. |
tags | string[] | no | Max 20 entries, each ≤ 40 chars. |
Response 201
{ "data": /* Client */ }Errors — 401 unauthorized, 403 (scope-required, or plan-required when the plan has no API access), 422 validation-failed, 429 rate-limited.
/api/v1/clientsTry itCreates a new CRM contact and emits a client.created webhook on success.
Requests are proxied through this docs site so CORS doesn't block the call. Use a sandbox token if you don't want test calls hitting live data.
POST /api/v1/clientsGET /api/v1/clients/{id}
Fetch a single client by id.
Required scope — clients:read
Path parameters
| Name | Type | Required | Notes |
|---|---|---|---|
id | string | yes | Client id. |
Response 200
{ "data": /* Client */ }Errors — 401, 403 scope-required, 404 not-found.
/api/v1/clients/{id}Try itRequests are proxied through this docs site so CORS doesn't block the call. Use a sandbox token if you don't want test calls hitting live data.
Path parameters
idrequiredGET /api/v1/clients/{id}
