Chatwoot customer support API via curl. Use this skill to manage contacts, conversations, and messages for multi-channel customer support.
If requests fail, run zero doctor check-connector --env-name CHATWOOT_TOKEN or zero doctor check-connector --url https://app.chatwoot.com/api/v1/profile --method GET
All examples use the Application API with user access token.
Create a new contact in your account:
Write to /tmp/chatwoot_request.json:
{
"inbox_id": 1,
"name": "John Doe",
"email": "john@example.com",
"phone_number": "+1234567890",
"identifier": "customer_123",
"additional_attributes": {
"company": "Acme Inc",
"plan": "premium"
}
}
Then run:
curl -s -X POST "https://app.chatwoot.com/api/v1/accounts/$CHATWOOT_ACCOUNT_ID/contacts" -H "api_access_token: $CHATWOOT_TOKEN" -H "Content-Type: application/json" -d @/tmp/chatwoot_request.json
Search contacts by email, phone, or name:
curl -s -X GET "https://app.chatwoot.com/api/v1/accounts/$CHATWOOT_ACCOUNT_ID/contacts/search?q=john@example.com" -H "api_access_token: $CHATWOOT_TOKEN" | jq '.payload[] | {id, name, email}'
Get a specific contact by ID. Replace <contact-id> with the actual contact ID from the "Search Contacts" or "Create a Contact" response:
curl -s -X GET "https://app.chatwoot.com/api/v1/accounts/$CHATWOOT_ACCOUNT_ID/contacts/<contact-id>" -H "api_access_token: $CHATWOOT_TOKEN"
Create a new conversation with a contact:
Write to /tmp/chatwoot_request.json:
{
"source_id": "api_conversation_123",
"inbox_id": 1,
"contact_id": 123,
"status": "open",
"message": {
"content": "Hello! How can I help you today?"
}
}
Then run:
curl -s -X POST "https://app.chatwoot.com/api/v1/accounts/$CHATWOOT_ACCOUNT_ID/conversations" -H "api_access_token: $CHATWOOT_TOKEN" -H "Content-Type: application/json" -d @/tmp/chatwoot_request.json
Get all conversations with optional filters:
# List open conversations
curl -s -X GET "https://app.chatwoot.com/api/v1/accounts/$CHATWOOT_ACCOUNT_ID/conversations?status=open" -H "api_access_token: $CHATWOOT_TOKEN" | jq '.data.payload[] | {id, status, contact: .meta.sender.name}'
Get details of a specific conversation. Replace <conversation-id> with the actual conversation ID from the "List Conversations" or "Create a Conversation" response:
curl -s -X GET "https://app.chatwoot.com/api/v1/accounts/$CHATWOOT_ACCOUNT_ID/conversations/<conversation-id>" -H "api_access_token: $CHATWOOT_TOKEN"
Send a message in a conversation. Replace <conversation-id> with the actual conversation ID from the "List Conversations" response:
Write to /tmp/chatwoot_request.json:
{
"content": "Thank you for contacting us! Let me help you with that.",
"message_type": "outgoing",
"private": false
}
Then run:
curl -s -X POST "https://app.chatwoot.com/api/v1/accounts/$CHATWOOT_ACCOUNT_ID/conversations/<conversation-id>/messages" -H "api_access_token: $CHATWOOT_TOKEN" -H "Content-Type: application/json" -d @/tmp/chatwoot_request.json
Add an internal note (not visible to customer). Replace <conversation-id> with the actual conversation ID from the "List Conversations" response:
Write to /tmp/chatwoot_request.json:
{
"content": "Customer is a VIP - handle with priority",
"message_type": "outgoing",
"private": true
}
Then run:
curl -s -X POST "https://app.chatwoot.com/api/v1/accounts/$CHATWOOT_ACCOUNT_ID/conversations/<conversation-id>/messages" -H "api_access_token: $CHATWOOT_TOKEN" -H "Content-Type: application/json" -d @/tmp/chatwoot_request.json
Assign a conversation to an agent. Replace <conversation-id> with the actual conversation ID and <agent-id> with the agent ID from the "List Agents" response:
Write to /tmp/chatwoot_request.json:
{
"assignee_id": 1
}
Then run:
curl -s -X POST "https://app.chatwoot.com/api/v1/accounts/$CHATWOOT_ACCOUNT_ID/conversations/<conversation-id>/assignments" -H "api_access_token: $CHATWOOT_TOKEN" -H "Content-Type: application/json" -d @/tmp/chatwoot_request.json
Change conversation status (open, resolved, pending). Replace <conversation-id> with the actual conversation ID from the "List Conversations" response:
Write to /tmp/chatwoot_request.json:
{
"status": "resolved"
}
Then run:
curl -s -X POST "https://app.chatwoot.com/api/v1/accounts/$CHATWOOT_ACCOUNT_ID/conversations/<conversation-id>/toggle_status" -H "api_access_token: $CHATWOOT_TOKEN" -H "Content-Type: application/json" -d @/tmp/chatwoot_request.json
Get all agents in the account:
curl -s -X GET "https://app.chatwoot.com/api/v1/accounts/$CHATWOOT_ACCOUNT_ID/agents" -H "api_access_token: $CHATWOOT_TOKEN" | jq '.[] | {id, name, email, role, availability_status}'
Get all inboxes (channels) in the account:
curl -s -X GET "https://app.chatwoot.com/api/v1/accounts/$CHATWOOT_ACCOUNT_ID/inboxes" -H "api_access_token: $CHATWOOT_TOKEN" | jq '.payload[] | {id, name, channel_type}'
Get counts by status for dashboard:
curl -s -X GET "https://app.chatwoot.com/api/v1/accounts/$CHATWOOT_ACCOUNT_ID/conversations/meta" -H "api_access_token: $CHATWOOT_TOKEN" | jq '.meta.all_count, .meta.mine_count'
| Status | Description |
|---|---|
open |
Active conversation |
resolved |
Closed/completed |
pending |
Waiting for response |
snoozed |
Temporarily paused |
| Type | Value | Description |
|---|---|---|
| Outgoing | outgoing |
Agent to customer |
| Incoming | incoming |
Customer to agent |
| Private | private: true |
Internal note (not visible to customer) |
| Field | Description |
|---|---|
id |
Contact ID |
name |
Contact name |
email |
Email address |
phone_number |
Phone number |
identifier |
External system ID |
custom_attributes |
Custom fields |
| Field | Description |
|---|---|
id |
Conversation ID |
inbox_id |
Channel/inbox ID |
status |
Current status |
assignee |
Assigned agent |
contact |
Customer info |
| Field | Description |
|---|---|
id |
Message ID |
content |
Message text |
message_type |
incoming/outgoing |
private |
Is internal note |
status |
sent/delivered/read/failed |
/app/accounts/{id}/... in your browserprivate: true for internal noteshttps://app.chatwoot.com