chatrail-dev Connections API
WhatsApp numbers and their pairing lifecycle.
WhatsApp numbers and their pairing lifecycle.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/chatrail-dev:chatrail-dev-connections-api"
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: ChatRail Connections API
version: 1.0.0
description: 'Send, schedule and receive WhatsApp messages through a linked-device session.
**Two things the API is careful about, which shape every endpoint below.**
*Accepted is not delivered.* A 202 means the message is durably stored and queued. Only the `status` field ever claims WhatsApp delivered anything, and `queued`, `submitted`, `sent`, `delivered` and `read` are deliberately distinct.
*A retry must not send twice.* Send `Idempotency-Key` on every send. A replay returns the original response; a concurrent duplicate is told to retry rather than allowed to race.'
contact:
name: ChatRail
url: https://www.chatrail.dev
servers:
- url: https://www.chatrail.dev
security:
- apiKey: []
tags:
- name: Connections
description: WhatsApp numbers and their pairing lifecycle.
paths:
/v1/connections/{connection}:
patch:
summary: Change connection settings
description: Send only the settings you want to change. `reject_calls` declines incoming calls on this number automatically. It is off by default, because the caller sees the call declined. Each call is still announced as `call.received`, with `rejected` saying whether it was declined. `proxy` routes this number through its own HTTP proxy (Team plan), or removes it with `null` (any plan). A proxy is `server` (an IP address and port, not a hostname, and a public address) with an optional `username` and `password`. It is applied when the number is paired, so it can only be changed before the number is linked, or after WhatsApp has logged it out. The response shows the address and `has_credentials`; the username and password are never returned.
tags:
- Connections
operationId: patch_v1_connections__connection_
parameters:
- name: connection
in: path
required: true
schema:
type: string
description: Connection slug.
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
reject_calls:
type: boolean
proxy:
anyOf:
- type: object
properties:
server:
type: string
minLength: 9
maxLength: 64
username:
type: string
minLength: 1
maxLength: 256
allOf:
- pattern: ^[\x21-\x7e]+$
- pattern: ^[^/?#%]+$
- pattern: ^[^:]+$
password:
type: string
minLength: 1
maxLength: 256
allOf:
- pattern: ^[\x21-\x7e]+$
- pattern: ^[^/?#%]+$
required:
- server
additionalProperties: false
- type: 'null'
additionalProperties: false
example:
reject_calls: true
responses:
'200':
description: The updated connection.
'400':
description: A setting is not valid, such as a proxy that is a hostname or a private address.
'402':
description: The plan does not include proxies.
'404':
description: No such connection.
'409':
description: 'The proxy cannot be changed: the number is linked.'
'422':
description: The number's WhatsApp engine cannot use a proxy.
security:
- apiKey:
- connections:write
x-scopes:
- connections:write
get:
summary: Get a connection
tags:
- Connections
operationId: get_v1_connections__connection_
parameters:
- name: connection
in: path
required: true
schema:
type: string
description: Connection slug.
responses:
'200':
description: The connection and its state.
'404':
description: No such connection.
security:
- apiKey:
- connections:read
x-scopes:
- connections:read
delete:
summary: Delete a connection
description: Soft deletes it and queues removal of its data.
tags:
- Connections
operationId: delete_v1_connections__connection_
parameters:
- name: connection
in: path
required: true
schema:
type: string
description: Connection slug.
responses:
'204':
description: Deleted.
'404':
description: No such connection.
security:
- apiKey:
- connections:write
x-scopes:
- connections:write
/v1/connections/{connection}/groups:
get:
summary: List WhatsApp groups
description: Returns a bounded, name-sorted page for a group picker. Group ids use the same `from.group` representation delivered in message webhooks. Participant identities are never returned.
tags:
- Connections
operationId: get_v1_connections__connection__groups
parameters:
- name: connection
in: path
required: true
schema:
type: string
description: Connection slug.
- name: limit
in: query
required: false
schema:
default: 100
type: integer
minimum: 1
maximum: 200
- name: offset
in: query
required: false
schema:
default: 0
type: integer
minimum: 0
maximum: 100000
responses:
'200':
description: A page of groups.
'404':
description: No such connection.
'502':
description: The transport returned an unreadable response.
'503':
description: The transport is unavailable.
security:
- apiKey:
- connections:read
x-scopes:
- connections:read
/v1/connections:
post:
summary: Create a connection
description: 'Returns `callback_token` **exactly once**. It cannot be retrieved again; store it when you receive it. On the Team plan, add `proxy` to link this number through its own HTTP proxy instead of ChatRail''s address: `server` is an IP address and port (not a hostname, and a public address), with an optional `username` and `password` that are stored encrypted and never returned. Use a fixed address, ideally in the same country as the number.'
tags:
- Connections
operationId: post_v1_connections
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
slug:
type: string
pattern: ^[a-z0-9][a-z0-9-]{0,38}[a-z0-9]$
name:
type: string
minLength: 1
maxLength: 80
proxy:
type: object
properties:
server:
type: string
minLength: 9
maxLength: 64
username:
type: string
minLength: 1
maxLength: 256
allOf:
- pattern: ^[\x21-\x7e]+$
- pattern: ^[^/?#%]+$
- pattern: ^[^:]+$
password:
type: string
minLength: 1
maxLength: 256
allOf:
- pattern: ^[\x21-\x7e]+$
- pattern: ^[^/?#%]+$
required:
- server
additionalProperties: false
required:
- slug
additionalProperties: false
example:
slug: operations
name: Operations line
responses:
'201':
description: Created, with the one-time callback token.
'400':
description: The request is not valid, such as a proxy that is a hostname or a private address.
'402':
description: The plan has no room for another number, or does not include proxies.
'409':
description: That slug is taken.
'422':
description: The WhatsApp engine cannot use a proxy.
security:
- apiKey:
- connections:write
x-scopes:
- connections:write
get:
summary: List connections
tags:
- Connections
operationId: get_v1_connections
responses:
'200':
description: Every live connection in the workspace.
security:
- apiKey:
- connections:read
x-scopes:
- connections:read
/v1/connections/{connection}/pair:
post:
summary: Begin pairing
description: 'Issues a short-lived, single-use grant. By default it holds a QR; with `{"method": "code", "phone": "+447700900123"}` it holds a pairing code instead, which the person enters under Linked devices → Link with phone number (encoding `pairing-code`). Either is fetched once with the grant id: each is a pairing credential, so whoever uses it links *their* device to the number.'
tags:
- Connections
operationId: post_v1_connections__connection__pair
parameters:
- name: connection
in: path
required: true
schema:
type: string
description: Connection slug.
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
method:
default: qr
type: string
enum:
- qr
- code
phone:
type: string
minLength: 5
maxLength: 40
additionalProperties: false
example:
method: code
phone: '+447700900123'
responses:
'200':
description: A grant id and its expiry.
'409':
description: The connection cannot be paired from its current state.
'503':
description: No transport is configured on this deployment.
security:
- apiKey:
- connections:write
x-scopes:
- connections:write
/v1/connections/{connection}/qr/{grantId}:
get:
summary: Redeem a QR grant
description: Single use. A redeemed or expired grant is gone; ask for another.
tags:
- Connections
operationId: get_v1_connections__connection__qr__grantId_
parameters:
- name: connection
in: path
required: true
schema:
type: string
description: Connection slug.
- name: grantId
in: path
required: true
schema:
type: string
description: Grant id.
responses:
'200':
description: The pairing payload.
'404':
description: Unknown, used or expired.
security:
- apiKey:
- connections:write
x-scopes:
- connections:write
/v1/connections/{connection}/suspend:
post:
summary: Suspend a connection
tags:
- Connections
operationId: post_v1_connections__connection__suspend
parameters:
- name: connection
in: path
required: true
schema:
type: string
description: Connection slug.
responses:
'200':
description: Suspended.
'409':
description: Not in a suspendable state.
security:
- apiKey:
- connections:write
x-scopes:
- connections:write
/v1/connections/{connection}/resume:
post:
summary: Resume a suspended connection
tags:
- Connections
operationId: post_v1_connections__connection__resume
parameters:
- name: connection
in: path
required: true
schema:
type: string
description: Connection slug.
responses:
'200':
description: Resumed.
'409':
description: Not suspended.
security:
- apiKey:
- connections:write
x-scopes:
- connections:write
components:
securitySchemes:
apiKey:
type: http
scheme: bearer
description: 'A workspace API key, `cr_live_…`. Server-side only: it carries workspace authority and must never reach a browser.'
session:
type: apiKey
in: cookie
name: chatrail_session
description: Dashboard session cookie. Set by `/v1/auth/verify`.