Browse sections

API reference

The endpoints most integrations need, with pagination, errors and a ready curl example for each.

On this page

This page covers the endpoints most integrations need. Every path below starts with https://app.hadir.chat/api/v1/accounts/{account_id}, and every request sends your token in the api_access_token header. To get both, see Access token and API base URL. The examples set them once:

BASE="https://app.hadir.chat/api/v1/accounts/acc_7Hk2mPq9RtWx"
TOKEN="YOUR_ACCESS_TOKEN"

Basics

  • IDs: a conversation is addressed by the number the inbox shows (#123), not an internal ID. Contacts, labels, teams, agents and inboxes use their id from list responses.
  • Pagination: contacts come 15 per page and conversations 25 per page; pass ?page=2 and so on. A conversation's messages come 20 at a time, newest last; pass ?before= the oldest message ID you have to get the 20 before it.
  • Permissions: requests act as the token's owner. Creating or changing labels, teams, agents, inboxes, custom attributes and webhooks needs the Administrator role.

Errors

  • 401: the token is wrong, you are not a member of this workspace, or your role does not allow the action. Body: {"error": "…"}.
  • 402: the plan does not include this, or a plan limit is reached. Body has error_code (feature_not_in_plan or limit_reached).
  • 404: {"error": "Resource could not be found"}.
  • 422: invalid data. Body: {"message": "…", "attributes": [...]} or {"error": "…"}.
  • 429: too many requests. Wait for the seconds in the Retry-After header, then retry.

Contacts

# List, search, show
curl "$BASE/contacts?page=1" -H "api_access_token: $TOKEN"
curl "$BASE/contacts/search?q=0500000000" -H "api_access_token: $TOKEN"
curl "$BASE/contacts/42" -H "api_access_token: $TOKEN"

# Create (update is PATCH /contacts/42 with the same fields)
curl -X POST "$BASE/contacts" -H "api_access_token: $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "Sara", "phone_number": "+966500000000", "email": "sara@example.com",
       "identifier": "cust-1001", "custom_attributes": {"city": "Riyadh"}}'

A contact's conversations: GET /contacts/42/conversations. Its labels: GET or POST /contacts/42/labels with {"labels": [...]}.

Conversations

# List: status = open | resolved | pending | snoozed | all; assignee_type = me | assigned | unassigned | all
curl "$BASE/conversations?status=open&assignee_type=all&page=1" -H "api_access_token: $TOKEN"
curl "$BASE/conversations/123" -H "api_access_token: $TOKEN"

# Change status
curl -X POST "$BASE/conversations/123/toggle_status" -H "api_access_token: $TOKEN" \
  -H "Content-Type: application/json" -d '{"status": "resolved"}'

# Assign to an agent (or {"team_id": 3} for a team)
curl -X POST "$BASE/conversations/123/assignments" -H "api_access_token: $TOKEN" \
  -H "Content-Type: application/json" -d '{"assignee_id": 7}'

To start a conversation: POST /conversations with inbox_id, contact_id and optionally "message": {"content": "…"}. On WhatsApp, a customer who has not written in the last 24 hours can only be messaged with an approved template; see WhatsApp templates.

Messages

curl "$BASE/conversations/123/messages" -H "api_access_token: $TOKEN"

# Reply to the customer
curl -X POST "$BASE/conversations/123/messages" -H "api_access_token: $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"content": "Your order has shipped.", "message_type": "outgoing", "private": false}'

Send "private": true for a private note that the customer never sees.

Labels

curl "$BASE/labels" -H "api_access_token: $TOKEN"
curl -X POST "$BASE/labels" -H "api_access_token: $TOKEN" -H "Content-Type: application/json" \
  -d '{"label": {"title": "vip", "description": "Top customers", "color": "#087D77", "show_on_sidebar": true}}'

# Set a conversation's labels (replaces the whole list)
curl -X POST "$BASE/conversations/123/labels" -H "api_access_token: $TOKEN" \
  -H "Content-Type: application/json" -d '{"labels": ["vip", "order"]}'

Inboxes, teams and agents

curl "$BASE/inboxes" -H "api_access_token: $TOKEN"
curl "$BASE/teams" -H "api_access_token: $TOKEN"
curl "$BASE/agents" -H "api_access_token: $TOKEN"

curl -X POST "$BASE/teams" -H "api_access_token: $TOKEN" -H "Content-Type: application/json" \
  -d '{"team": {"name": "Sales", "description": "Pre-sales questions", "allow_auto_assign": true}}'
curl -X POST "$BASE/agents" -H "api_access_token: $TOKEN" -H "Content-Type: application/json" \
  -d '{"agent": {"name": "Khalid", "email": "khalid@example.com", "role": "agent"}}'

Team members: GET /teams/3/team_members, and POST with {"user_ids": [7, 8]} to add. Adding an agent beyond your plan's limit answers 402.

Canned replies

curl "$BASE/canned_responses" -H "api_access_token: $TOKEN"
curl -X POST "$BASE/canned_responses" -H "api_access_token: $TOKEN" -H "Content-Type: application/json" \
  -d '{"canned_response": {"short_code": "hours", "content": "We are open 9 am to 11 pm."}}'

Custom attributes

curl "$BASE/custom_attribute_definitions?attribute_model=contact_attribute" -H "api_access_token: $TOKEN"
curl -X POST "$BASE/custom_attribute_definitions" -H "api_access_token: $TOKEN" -H "Content-Type: application/json" \
  -d '{"custom_attribute_definition": {"attribute_display_name": "City", "attribute_key": "city",
       "attribute_display_type": "text", "attribute_model": "contact_attribute"}}'

attribute_model is contact_attribute or conversation_attribute; attribute_display_type is one of text, number, currency, percent, link, date, list, checkbox. More in Custom attributes.

Webhooks

curl "$BASE/webhooks" -H "api_access_token: $TOKEN"
curl -X POST "$BASE/webhooks" -H "api_access_token: $TOKEN" -H "Content-Type: application/json" \
  -d '{"webhook": {"name": "Orders system", "url": "https://example.com/hadir/events",
       "subscriptions": ["conversation_created", "message_created"]}}'

The response includes the webhook's secret for checking signatures. Update with PATCH /webhooks/5, remove with DELETE /webhooks/5. Events and payloads are in Webhooks.

Note: every change you make through the API is real and immediate, and messages reach the customer. Test with your own number or a test contact first.

Was this helpful?

Thanks for your feedback ✓

Please don't include personal details

We got your note and will review the article with it in mind.

To see how this site uses cookies, read our Privacy Policy