Synkra Chat API Reference
The Synkra Chat API lets you build integrations on top of your customer support inbox. Create contacts, send messages, manage conversations, subscribe to real time events, and route work into external systems.
Overview
Section titled “Overview”- Base URL:
https://chat.synkra.co.za/api/v1/accounts/{account_id} - Format: REST, JSON in, JSON out
- Authentication: Personal access token in the
api_access_tokenheader - Rate limit: 300 requests per minute per account
Every endpoint is scoped to a single account. Your account_id is the number in your Synkra Chat URL. For example, /app/accounts/3/ means your account ID is 3.
Authentication
Section titled “Authentication”Synkra Chat uses personal access tokens. To get yours:
- Log in to Synkra Chat.
- Click your avatar (bottom left) and go to Profile Settings.
- Scroll to Access Token and copy it.
Include the token on every request:
api_access_token: YOUR_ACCESS_TOKENTreat this token as a password. Anyone who has it can act as you on your account. If it leaks, reset it immediately from the same page.
Tokens inherit your user’s permissions. An agent token can only do what an agent can do.
Quick start
Section titled “Quick start”List your contacts:
curl -X GET "https://chat.synkra.co.za/api/v1/accounts/3/contacts" \ -H "api_access_token: YOUR_ACCESS_TOKEN"Create a contact:
curl -X POST "https://chat.synkra.co.za/api/v1/accounts/3/contacts" \ -H "api_access_token: YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name": "Jane Smith", "email": "jane@example.com", "phone_number": "+27123456789"}'Send a message:
curl -X POST "https://chat.synkra.co.za/api/v1/accounts/3/conversations/42/messages" \ -H "api_access_token: YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{"content": "Thanks for reaching out.", "message_type": "outgoing"}'Core concepts
Section titled “Core concepts”| Entity | Description |
|---|---|
| Contact | A customer or lead. Has name, email, phone, and custom attributes. |
| Conversation | A thread between one contact and one inbox. |
| Message | An individual message inside a conversation. |
| Inbox | A channel through which conversations arrive. |
| Agent | A Synkra Chat user with access to the account. |
| Team | A group of agents. |
| Label | A tag applied to a contact or conversation. |
| Webhook | An HTTP endpoint you register to receive events. |
Contacts
Section titled “Contacts”List contacts
Section titled “List contacts”GET /contacts
Query parameters: page (default 1), sort, include_contact_inboxes.
Get a contact
Section titled “Get a contact”GET /contacts/{id}
Create a contact
Section titled “Create a contact”POST /contacts
Body parameters:
| Field | Type | Notes |
|---|---|---|
name |
string | Display name |
email |
string | Email address (unique per account) |
phone_number |
string | E.164 format |
identifier |
string | Your own external ID (recommended) |
custom_attributes |
object | Custom fields you’ve defined |
additional_attributes |
object | Built in additional fields |
Update a contact
Section titled “Update a contact”PUT /contacts/{id}
Same body as create. Send only the fields you want to change.
Delete a contact
Section titled “Delete a contact”DELETE /contacts/{id}
Search contacts
Section titled “Search contacts”GET /contacts/search?q={query}
Searches by name, email, phone number, or identifier.
Get a contact’s conversations
Section titled “Get a contact’s conversations”GET /contacts/{id}/conversations
Tag a contact
Section titled “Tag a contact”POST /contacts/{id}/labels
Body:
{ "labels": ["vip", "enterprise"] }Conversations
Section titled “Conversations”List conversations
Section titled “List conversations”GET /conversations
Query parameters:
| Parameter | Values | Notes |
|---|---|---|
status |
open, resolved, pending, snoozed |
Filter by status |
assignee_type |
me, unassigned, all |
Filter by assignment |
inbox_id |
integer | Filter by inbox |
team_id |
integer | Filter by team |
page |
integer | Pagination |
Get a conversation
Section titled “Get a conversation”GET /conversations/{id}
Create a conversation
Section titled “Create a conversation”POST /conversations
Body:
| Field | Type | Notes |
|---|---|---|
contact_id |
integer | The contact to start the conversation with |
inbox_id |
integer | Which inbox to use |
status |
string | Optional, defaults to open |
assignee_id |
integer | Optional, which agent to assign to |
team_id |
integer | Optional, which team to assign to |
message |
object | Optional, { "content": "..." } for an opening message |
Update a conversation
Section titled “Update a conversation”PATCH /conversations/{id}
Update fields like priority, custom_attributes, snoozed_until.
Toggle status
Section titled “Toggle status”POST /conversations/{id}/toggle_status
Body:
{ "status": "resolved" }Acceptable values: open, resolved, pending, snoozed.
Assign a conversation
Section titled “Assign a conversation”POST /conversations/{id}/assignments
Body, to assign an agent:
{ "assignee_id": 5 }Body, to assign a team:
{ "team_id": 2 }Tag a conversation
Section titled “Tag a conversation”POST /conversations/{id}/labels
Body:
{ "labels": ["billing", "urgent"] }Set custom attributes
Section titled “Set custom attributes”POST /conversations/{id}/custom_attributes
Body:
{ "custom_attributes": { "order_id": "12345" } }List conversations in an inbox
Section titled “List conversations in an inbox”GET /inboxes/{inbox_id}/conversations
Messages
Section titled “Messages”List messages in a conversation
Section titled “List messages in a conversation”GET /conversations/{id}/messages
Query parameters: before (message ID), after (message ID), page.
Send a message
Section titled “Send a message”POST /conversations/{id}/messages
Body:
| Field | Type | Notes |
|---|---|---|
content |
string | The message text |
message_type |
string | outgoing (to customer) or incoming (simulated) |
private |
boolean | true for an internal note |
content_type |
string | text (default), input_select, cards, input_email |
content_attributes |
object | Additional structured data |
Delete a message
Section titled “Delete a message”DELETE /conversations/{id}/messages/{message_id}
Add an internal note
Section titled “Add an internal note”POST /conversations/{id}/messages
Body:
{ "content": "Customer is on the enterprise plan.", "private": true, "message_type": "outgoing"}Agents
Section titled “Agents”List agents
Section titled “List agents”GET /agents
Get an agent
Section titled “Get an agent”GET /agents/{id}
Create an agent
Section titled “Create an agent”POST /agents
Body: name, email, role (agent or administrator), availability_status, confirmed.
Update an agent
Section titled “Update an agent”PATCH /agents/{id}
Inboxes
Section titled “Inboxes”List inboxes
Section titled “List inboxes”GET /inboxes
Get an inbox
Section titled “Get an inbox”GET /inboxes/{id}
List inbox members
Section titled “List inbox members”GET /inboxes/{id}/members
Add a member to an inbox
Section titled “Add a member to an inbox”POST /inboxes/{id}/members
Body:
{ "user_ids": [3, 5] }Labels
Section titled “Labels”List labels
Section titled “List labels”GET /labels
Create a label
Section titled “Create a label”POST /labels
Body:
{ "title": "priority", "description": "High priority", "color": "#FF0000" }Update a label
Section titled “Update a label”PATCH /labels/{id}
Delete a label
Section titled “Delete a label”DELETE /labels/{id}
List teams
Section titled “List teams”GET /teams
Create a team
Section titled “Create a team”POST /teams
Body:
{ "name": "Support", "description": "Tier 1 support", "allow_auto_assign": true }Update a team
Section titled “Update a team”PATCH /teams/{id}
Webhooks
Section titled “Webhooks”Webhooks let you receive real time notifications when events happen in your Synkra Chat account. Register a URL, subscribe to the events you care about, and Synkra Chat will POST a JSON payload to your URL whenever one of those events fires.
Register a webhook
Section titled “Register a webhook”POST /webhooks
Body:
| Field | Type | Notes |
|---|---|---|
url |
string | Your HTTPS endpoint. Must be publicly reachable. |
name |
string | Human readable name, helps you find it later. |
subscriptions |
array | The events you want to receive. |
Example:
curl -X POST "https://chat.synkra.co.za/api/v1/accounts/3/webhooks" \ -H "api_access_token: YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "url": "https://example.com/synkra-webhook", "name": "My Integration", "subscriptions": ["message_created", "conversation_created"] }'List webhooks
Section titled “List webhooks”GET /webhooks
Update a webhook
Section titled “Update a webhook”PATCH /webhooks/{id}
Delete a webhook
Section titled “Delete a webhook”DELETE /webhooks/{id}
Available events
Section titled “Available events”| Event | Fires when |
|---|---|
conversation_created |
A new conversation starts |
conversation_updated |
A conversation’s attributes change |
conversation_status_changed |
Status changes (open, resolved, pending, snoozed) |
conversation_typing_on |
An agent starts typing |
conversation_typing_off |
An agent stops typing |
message_created |
A message is created (incoming or outgoing) |
message_updated |
A message is edited |
contact_created |
A new contact is created |
contact_updated |
A contact’s attributes change |
inbox_created |
A new inbox is created |
inbox_updated |
An inbox’s settings change |
webwidget_triggered |
A visitor opens the website widget |
Webhook payload
Section titled “Webhook payload”Every delivery is a JSON POST with an event field at the top:
{ "event": "message_created", "id": 12345, "content": "Hi, I need help with my order", "message_type": "incoming", "created_at": "2026-09-30T11:22:33Z", "sender": { "id": 101, "name": "Jane Smith", "email": "jane@example.com", "type": "contact" }, "conversation": { "id": 42, "inbox_id": 1, "status": "open" }, "account": { "id": 3, "name": "Acme Inc" }, "inbox": { "id": 1, "name": "Website Chat" }}Signature verification
Section titled “Signature verification”If your Synkra Chat instance signs webhook deliveries, the request includes:
| Header | Value |
|---|---|
X-Synkra-Timestamp |
Unix timestamp of when the request was sent |
X-Synkra-Signature |
sha256= followed by the HMAC SHA256 of {timestamp}.{raw_body} |
Verify the signature before trusting the payload. Reject requests older than 5 minutes.
If your instance does not sign deliveries, treat the webhook URL as a secret.
Error handling
Section titled “Error handling”| Code | Meaning | How to handle |
|---|---|---|
200 |
Success | None |
201 |
Created | None |
204 |
No content (success) | None |
400 |
Bad request, invalid payload | Check response body |
401 |
Unauthorized, bad or missing token | Verify your header |
403 |
Forbidden, insufficient permission | Check your role |
404 |
Not found | Confirm the ID |
422 |
Validation failed | Check response body |
429 |
Rate limited | Back off, then retry |
500 |
Server error | Retry with backoff |
Error response format
Section titled “Error response format”{ "error": "Resource could not be found", "message": "The conversation with ID 999 does not exist"}Code examples
Section titled “Code examples”JavaScript
Section titled “JavaScript”const BASE_URL = 'https://chat.synkra.co.za/api/v1';const ACCOUNT_ID = '3';const TOKEN = 'YOUR_ACCESS_TOKEN';
async function sendMessage(conversationId, content) { const response = await fetch( `${BASE_URL}/accounts/${ACCOUNT_ID}/conversations/${conversationId}/messages`, { method: 'POST', headers: { 'api_access_token': TOKEN, 'Content-Type': 'application/json', }, body: JSON.stringify({ content, message_type: 'outgoing' }), } ); if (!response.ok) throw new Error(`API error: ${response.status}`); return response.json();}Python
Section titled “Python”import requests
BASE_URL = "https://chat.synkra.co.za/api/v1"ACCOUNT_ID = "3"TOKEN = "YOUR_ACCESS_TOKEN"
def send_message(conversation_id, content): response = requests.post( f"{BASE_URL}/accounts/{ACCOUNT_ID}/conversations/{conversation_id}/messages", headers={ "api_access_token": TOKEN, "Content-Type": "application/json", }, json={"content": content, "message_type": "outgoing"}, ) response.raise_for_status() return response.json()Support
Section titled “Support”- Developer questions: hello@synkra.co.za
- Bug reports: hello@synkra.co.za
Last updated: 30 September 2026
