The Dazza REST API

Read conversations and contacts, add Q&As, reply as the team and resolve conversations from your own systems.

4 MIN READUPDATED 7 SECTIONS

The API lets your own code work with Dazza: sync conversations and contacts to your CRM, teach Dazza from your product catalogue, or reply and resolve from another tool. Everything is JSON over HTTPS.

https://app.dazza.io/api/v1

To hear about things as they happen instead of asking, use event webhooks.

Keys

Admins create keys in Settings → Developers → API keys. Make one for each system that uses the API, so you can revoke one without breaking the others.

  • A key is shown once, when you create it. Dazza only keeps a fingerprint of it.
  • Keys start with dz_sk_. Keep them on your server, never in a web page or an app.
  • Revoke stops a key working straight away.
  • A workspace can have up to 10 keys.

Send the key as a bearer token:

curl https://app.dazza.io/api/v1/conversations \
  -H "Authorization: Bearer dz_sk_…"

Every request is limited to your own workspace. Preview chats from the Agent page are never included.

Limits

Each key can make 120 requests a minute. Every response says where you are:

  • x-ratelimit-limit: requests allowed a minute
  • x-ratelimit-remaining: requests left this minute
  • x-ratelimit-reset: when the minute starts again, in Unix seconds

Past the limit you get 429 with a retry-after header in seconds.

Errors

Errors use the HTTP status and a JSON body with a code you can check and a message you can show:

{ "error": { "code": "not_found", "message": "No conversation with that id in this workspace." } }
Status Means
400 Something in the request isn’t valid. The message says what.
401 The key is missing, wrong or revoked.
404 Nothing with that id in your workspace.
422 Dazza understood the request but couldn’t do it.
429 Too many requests this minute.
502 A reply was saved but the channel didn’t accept it.

Pagination

Lists return the newest first, 20 at a time. Ask for up to 100 with limit. When there’s more, has_more is true and next_cursor fetches the next page:

{ "object": "list", "data": [ … ], "has_more": true, "next_cursor": "MjAyNi0xMC0y…" }
curl "https://app.dazza.io/api/v1/conversations?limit=50&cursor=MjAyNi0xMC0y…" \
  -H "Authorization: Bearer dz_sk_…"

Conversations

List conversations

GET /conversations

Parameter
status open or resolved
channel web, email, whatsapp, messenger, instagram, telegram, sms, line, viber, slack, teams or discord
contact_id Only this contact’s conversations
limit, cursor See Pagination
curl "https://app.dazza.io/api/v1/conversations?status=open&channel=email" \
  -H "Authorization: Bearer dz_sk_…"

Each conversation looks like this:

{
  "object": "conversation",
  "id": "cnv_9x2k…",
  "channel": "web",
  "status": "open",
  "with": "team",
  "needs_reply": true,
  "subject": "Can I change my booking?",
  "contact_id": "cnt_4hq1…",
  "contact": { "object": "contact", "id": "cnt_4hq1…", "name": "Sam Taylor", "email": "sam@example.com", "phone": null, "attributes": { "plan": "Pro" }, "created_at": "…", "updated_at": "…" },
  "verified": { "email": "sam@example.com", "via": "signed" },
  "assignee": null,
  "handover": { "at": "2026-10-27T10:42:00.000Z", "reason": "customer_request", "reason_label": "Asked for a person", "summary": "Sam wants to move their booking to Friday." },
  "tags": ["Bookings"],
  "sentiment": "neutral",
  "rating": { "value": "good", "comment": null, "rated_at": "…" },
  "language": "en",
  "page_url": "https://example.com/contact",
  "created_at": "2026-10-27T10:40:12.000Z",
  "last_message_at": "2026-10-27T10:42:03.000Z",
  "resolved_at": null
}

with is dazza while Dazza is answering, and team once it’s handed over or someone took it over. verified is only set when the customer proved who they are; see Verify your customers.

Get a conversation

GET /conversations/{id} returns the conversation with all its messages, oldest first.

curl https://app.dazza.io/api/v1/conversations/cnv_9x2k… \
  -H "Authorization: Bearer dz_sk_…"
{
  "object": "conversation",
  "id": "cnv_9x2k…",
  "…": "…",
  "messages": [
    { "object": "message", "id": "msg_…", "conversation_id": "cnv_9x2k…", "role": "customer", "text": "Can I change my booking to Friday?", "author_name": null, "sources": [], "action": null, "delivery": null, "rating": null, "created_at": "…" },
    { "object": "message", "id": "msg_…", "conversation_id": "cnv_9x2k…", "role": "dazza", "text": "You can move a booking up to 24 hours before [1].", "author_name": null, "sources": [{ "n": 1, "title": "Bookings", "url": "https://example.com/bookings" }], "action": null, "delivery": null, "rating": "helpful", "created_at": "…" }
  ]
}

role is customer, dazza, team, note (internal, never seen by the customer), system or action (something Dazza did, with its name and status). delivery is set for email and messaging apps: draft, sent, delivered, failed and so on.

Reply as the team

POST /conversations/{id}/reply

Field
text Required. Up to 5,000 characters.
author_name Optional. The name the customer sees, e.g. “Maya Patel”. Their first name shows in the chat and signs emails. Defaults to “Team”.

The reply goes out on the conversation’s own channel: into the website chat, as an email in the same thread, or on WhatsApp, Messenger and the rest. If Dazza is still answering, the team takes the conversation over first, as Take over does in the inbox, so Dazza and your team never both reply.

curl -X POST https://app.dazza.io/api/v1/conversations/cnv_9x2k…/reply \
  -H "Authorization: Bearer dz_sk_…" \
  -H "Content-Type: application/json" \
  -d '{ "text": "Hi Sam, Friday at 10 is booked for you.", "author_name": "Maya Patel" }'

Returns 201 with the message and the updated conversation. If the channel refused it (for example, WhatsApp’s 24-hour window had passed), you get 502 with the saved message and why.

Resolve a conversation

POST /conversations/{id}/resolve marks it resolved. Resolving one that’s already resolved is fine. Returns the conversation.

curl -X POST https://app.dazza.io/api/v1/conversations/cnv_9x2k…/resolve \
  -H "Authorization: Bearer dz_sk_…"

If the customer writes again, it reopens, as it does in the inbox.

Contacts

List contacts

GET /contacts lists customers Dazza knows by email, phone or name, newest first. Visitors who chatted without saying who they are aren’t included.

Parameter
email Find one person by email
limit, cursor See Pagination
curl "https://app.dazza.io/api/v1/contacts?email=sam@example.com" \
  -H "Authorization: Bearer dz_sk_…"

attributes holds the details your own sign-in sent about the customer, such as their plan. See Verify your customers.

Get a contact

GET /contacts/{id}

curl https://app.dazza.io/api/v1/contacts/cnt_4hq1… \
  -H "Authorization: Bearer dz_sk_…"

Knowledge

Add a Q&A

POST /knowledge/qa

Field
question Required. Up to 300 characters.
answer Required. Up to 5,000 characters.
title Optional. What it’s called in Knowledge. Defaults to the question.

Like Q&As written in the dashboard, it counts as your own words: it ranks first, and wins over a web page that says something different. Dazza can answer from it straight away.

curl -X POST https://app.dazza.io/api/v1/knowledge/qa \
  -H "Authorization: Bearer dz_sk_…" \
  -H "Content-Type: application/json" \
  -d '{ "question": "Do you deliver on Saturdays?", "answer": "Yes, in London. Order by 2pm on Friday." }'
{ "object": "knowledge_source", "id": "src_…", "type": "qa", "title": "Do you deliver on Saturdays?", "question": "…", "answer": "…", "status": "ready", "error": null, "created_at": "…" }

To change or remove a Q&A, use Knowledge in the dashboard.

Still stuck? A person reads every message. Contact us ↗