Chatwoot customer support API via curl. Use this skill to manage contacts, conversations, and messages for multi-channel customer support.
Install
npx skillscat add vm0-ai/vm0-skills/chatwoot Install via the SkillsCat registry.
This skill provides access to the Chatwoot API via curl to manage contacts, conversations, and messages across multiple support channels. It enables the automation of customer support workflows and integration with external CRM or ticketing systems. Developers should use it to programmatically handle customer profiles, send replies, and track support interactions.
Chatwoot
Use Chatwoot via direct curl calls to manage customer support across multiple channels (website, email, WhatsApp, etc.).
Official docs:
https://developers.chatwoot.com/api-reference/introduction
When to Use
Use this skill when you need to:
- Manage contacts - create, search, and update customer profiles
- Handle conversations - create, assign, and track support conversations
- Send messages - reply to customers or add internal notes
- List agents - get support team information
- Automate workflows - integrate with CRM, ticketing, or notification systems
Prerequisites
- Set up Chatwoot (Cloud or Self-hosted)
- Log in and go to Profile Settings to get your API access token
- Note your Account ID from the URL (e.g.,
/app/accounts/1/...)
export CHATWOOT_API_TOKEN="your-api-access-token"
export CHATWOOT_ACCOUNT_ID="1"
export CHATWOOT_BASE_URL="https://app.chatwoot.com" # or your self-hosted URLAPI Types
| API Type | Auth | Use Case |
|---|---|---|
| Application API | User access_token | Agent/admin automation |
| Client API | inbox_identifier | Custom chat interfaces |
| Platform API | Platform App token | Multi-tenant management (self-hosted only) |
Important: When using
$VARin a command that pipes to another command, wrap the command containing$VARinbash -c '...'. Due to a Claude Code bug, environment variables are silently cleared when pipes are used directly.bash -c 'curl -s "https://api.example.com" -H "Authorization: Bearer $API_KEY"' | jq .
How to Use
All examples use the Application API with user access token.
1. Create a Contact
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:
bash -c 'curl -s -X POST "${CHATWOOT_BASE_URL}/api/v1/accounts/${CHATWOOT_ACCOUNT_ID}/contacts" -H "api_access_token: ${CHATWOOT_API_TOKEN}" -H "Content-Type: application/json" -d @/tmp/chatwoot_request.json'2. Search Contacts
Search contacts by email, phone, or name:
bash -c 'curl -s -X GET "${CHATWOOT_BASE_URL}/api/v1/accounts/${CHATWOOT_ACCOUNT_ID}/contacts/search?q=john@example.com" -H "api_access_token: ${CHATWOOT_API_TOKEN}"' | jq '.payload[] | {id, name, email}'3. Get Contact Details
Get a specific contact by ID. Replace <contact-id> with the actual contact ID from the "Search Contacts" or "Create a Contact" response:
bash -c 'curl -s -X GET "${CHATWOOT_BASE_URL}/api/v1/accounts/${CHATWOOT_ACCOUNT_ID}/contacts/<contact-id>" -H "api_access_token: ${CHATWOOT_API_TOKEN}"'4. Create a Conversation
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:
bash -c 'curl -s -X POST "${CHATWOOT_BASE_URL}/api/v1/accounts/${CHATWOOT_ACCOUNT_ID}/conversations" -H "api_access_token: ${CHATWOOT_API_TOKEN}" -H "Content-Type: application/json" -d @/tmp/chatwoot_request.json'5. List Conversations
Get all conversations with optional filters:
# List open conversations
bash -c 'curl -s -X GET "${CHATWOOT_BASE_URL}/api/v1/accounts/${CHATWOOT_ACCOUNT_ID}/conversations?status=open" -H "api_access_token: ${CHATWOOT_API_TOKEN}"' | jq '.data.payload[] | {id, status, contact: .meta.sender.name}'6. Get Conversation Details
Get details of a specific conversation. Replace <conversation-id> with the actual conversation ID from the "List Conversations" or "Create a Conversation" response:
bash -c 'curl -s -X GET "${CHATWOOT_BASE_URL}/api/v1/accounts/${CHATWOOT_ACCOUNT_ID}/conversations/<conversation-id>" -H "api_access_token: ${CHATWOOT_API_TOKEN}"'7. Send a Message
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:
bash -c 'curl -s -X POST "${CHATWOOT_BASE_URL}/api/v1/accounts/${CHATWOOT_ACCOUNT_ID}/conversations/<conversation-id>/messages" -H "api_access_token: ${CHATWOOT_API_TOKEN}" -H "Content-Type: application/json" -d @/tmp/chatwoot_request.json'8. Add Private Note
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:
bash -c 'curl -s -X POST "${CHATWOOT_BASE_URL}/api/v1/accounts/${CHATWOOT_ACCOUNT_ID}/conversations/<conversation-id>/messages" -H "api_access_token: ${CHATWOOT_API_TOKEN}" -H "Content-Type: application/json" -d @/tmp/chatwoot_request.json'9. Assign Conversation
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:
bash -c 'curl -s -X POST "${CHATWOOT_BASE_URL}/api/v1/accounts/${CHATWOOT_ACCOUNT_ID}/conversations/<conversation-id>/assignments" -H "api_access_token: ${CHATWOOT_API_TOKEN}" -H "Content-Type: application/json" -d @/tmp/chatwoot_request.json'10. Update Conversation Status
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:
bash -c 'curl -s -X POST "${CHATWOOT_BASE_URL}/api/v1/accounts/${CHATWOOT_ACCOUNT_ID}/conversations/<conversation-id>/toggle_status" -H "api_access_token: ${CHATWOOT_API_TOKEN}" -H "Content-Type: application/json" -d @/tmp/chatwoot_request.json'11. List Agents
Get all agents in the account:
bash -c 'curl -s -X GET "${CHATWOOT_BASE_URL}/api/v1/accounts/${CHATWOOT_ACCOUNT_ID}/agents" -H "api_access_token: ${CHATWOOT_API_TOKEN}"' | jq '.[] | {id, name, email, role, availability_status}'12. List Inboxes
Get all inboxes (channels) in the account:
bash -c 'curl -s -X GET "${CHATWOOT_BASE_URL}/api/v1/accounts/${CHATWOOT_ACCOUNT_ID}/inboxes" -H "api_access_token: ${CHATWOOT_API_TOKEN}"' | jq '.payload[] | {id, name, channel_type}'13. Get Conversation Counts
Get counts by status for dashboard:
bash -c 'curl -s -X GET "${CHATWOOT_BASE_URL}/api/v1/accounts/${CHATWOOT_ACCOUNT_ID}/conversations/meta" -H "api_access_token: ${CHATWOOT_API_TOKEN}"' | jq '.meta.all_count, .meta.mine_count'Conversation Status
| Status | Description |
|---|---|
open |
Active conversation |
resolved |
Closed/completed |
pending |
Waiting for response |
snoozed |
Temporarily paused |
Message Types
| Type | Value | Description |
|---|---|---|
| Outgoing | outgoing |
Agent to customer |
| Incoming | incoming |
Customer to agent |
| Private | private: true |
Internal note (not visible to customer) |
Response Fields
Contact
| Field | Description |
|---|---|
id |
Contact ID |
name |
Contact name |
email |
Email address |
phone_number |
Phone number |
identifier |
External system ID |
custom_attributes |
Custom fields |
Conversation
| Field | Description |
|---|---|
id |
Conversation ID |
inbox_id |
Channel/inbox ID |
status |
Current status |
assignee |
Assigned agent |
contact |
Customer info |
Message
| Field | Description |
|---|---|
id |
Message ID |
content |
Message text |
message_type |
incoming/outgoing |
private |
Is internal note |
status |
sent/delivered/read/failed |
Guidelines
- Get API token from Profile Settings: Log into Chatwoot → Profile → Access Token
- Account ID is in URL: Look at
/app/accounts/{id}/...in your browser - Inbox ID is required: Get inbox IDs first with the list inboxes endpoint
- Use source_id for conversations: Required to create conversations via API
- Private messages: Set
private: truefor internal notes - Self-hosted: Change
CHATWOOT_BASE_URLto your instance URL - Webhooks recommended: Use webhooks for real-time updates instead of polling