Overview

A Deskee chatbot answers customers from a business's own content and hands over to a person when it matters. Everything you can do in the dashboard you can also do from code:

The API is available on every plan. Base URL: https://deskee.io. Requests and answers are JSON.

Authentication

The account owner creates keys under Account → API keys. Send one with every request:

Authorization: Bearer dsk_…

Each key only does what it was given permission for when it was created:

PermissionScopeAllows
Send messages to chatbots through the APIchatThe chat API
See chatbots and their settingschatbots:readReading chatbots, knowledge, embed code
Create chatbots and change their settings, knowledge and lookchatbots:writeThe rest of the management API
Read conversationsconversations:readConversations on every channel
Reply to, hand back and close conversationsconversations:replyAnswering as the account owner
See calendars, open times and bookings / Book and cancel appointmentscalendars:read, calendars:bookThe calendars API

Keep keys on your server. Never put one in a web page or an app people can download: for websites, use the chat widget. A key acts for the whole account, so revoke it straight away if it leaks.

Chat API

Switch the API on for a chatbot first: open it in Deskee, go to Channels → API and set it to Published (Draft switches it off). The Setup tab shows the chatbot's id.

Send a message

curl -X POST https://deskee.io/api/v1/chatbots/CHATBOT_ID/messages \
  -H "Authorization: Bearer dsk_…" \
  -H "Content-Type: application/json" \
  -d '{"text":"What are your opening hours?","visitor":{"name":"Ada","email":"ada@example.com"}}'
{
  "conversation_id": "5f0c…",
  "status": "bot",
  "reply": "We're open 8am to 4pm, Tuesday to Saturday.",
  "messages": [
    { "id": "9be9…", "role": "bot", "text": "We're open 8am to 4pm, Tuesday to Saturday.", "author_name": null, "created": "2026-10-09T18:31:04.000Z" }
  ]
}
Field
textRequired. Up to 4,000 characters.
conversation_idCarry on an earlier conversation. Leave it out to start a new one.
languageTwo-letter code for the reply language, if the chatbot speaks it.
visitor{ name, email }, shown to your team in the Service Desk.

The call waits for the chatbot's answer, usually a few seconds. reply is the chatbot's answer in Markdown; messages lists everything added after your message. status is bot, awaiting (waiting for a person), live (a person is answering) or closed. Each conversation counts towards the account's monthly AI conversations, like a website chat.

Replies from a person

When the chatbot hands over, status is live and reply is null: a teammate answers from the Service Desk later. Collect their replies with a webhook, or poll with the id of the last message you have:

curl "https://deskee.io/api/v1/conversations/CONVERSATION_ID/messages?after=MESSAGE_ID" \
  -H "Authorization: Bearer dsk_…"

Webhooks

On the chatbot's Channels → API → Webhook tab, add an HTTPS address. Replies that arrive after your request has finished (a teammate's answer, "joined" and "closed" notes) are POSTed to it. The chatbot's own replies aren't: they're already in the answer to your request.

POST https://your-server.example.com/deskee
X-Deskee-Timestamp: 1791563464
X-Deskee-Signature: sha256=4c1e…

{ "event": "message", "conversation_id": "5f0c…",
  "message": { "id": "a71d…", "role": "agent", "text": "Hi Ada, Sam here…", "author_name": "Sam", "created": "…" } }

Check each one came from Deskee: the signature is an HMAC-SHA256, keyed with the signing secret shown on the same tab, of the timestamp, a full stop and the raw request body. Send a test event on that tab posts { "event": "test" }.

// Node.js
const crypto = require("crypto");
const expected = "sha256=" + crypto.createHmac("sha256", SECRET)
  .update(req.headers["x-deskee-timestamp"] + "." + rawBody).digest("hex");
const valid = crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(req.headers["x-deskee-signature"]));

# Python
import hmac, hashlib
expected = "sha256=" + hmac.new(SECRET.encode(), (timestamp + "." + raw_body).encode(), hashlib.sha256).hexdigest()
valid = hmac.compare_digest(expected, signature)

Management API

Create and set up chatbots as you would in the dashboard: the same plan limits, defaults and checks apply. The only thing you can delete is a single knowledge source; deleting chatbots and conversations stays in the dashboard.

EndpointScope
GET /api/v1/chatbotschatbots:read
GET /api/v1/chatbots/ID: persona, website widget with its embed code, channels, knowledge, crawl progresschatbots:read
POST /api/v1/chatbots { name, description?, website?, learn_website?, match_website_theme? }chatbots:write
PATCH /api/v1/chatbots/ID { name?, description?, website?, status? }chatbots:write
PATCH /api/v1/chatbots/ID/persona { name?, title?, welcome_message?, launcher_label?, tones?, profile_image_url?, instructions?, timezone?, languages? }chatbots:write
GET /api/v1/chatbots/ID/knowledgechatbots:read
POST /api/v1/chatbots/ID/knowledge { type: "text", label, content }, { type: "webpage", url } or { type: "website", url }chatbots:write
GET /api/v1/chatbots/ID/knowledge/SOURCE_ID, with its full textchatbots:read
PATCH /api/v1/chatbots/ID/knowledge/SOURCE_ID { label?, content? (text sources), refresh?: true (webpage and Facebook sources) }chatbots:write
DELETE /api/v1/chatbots/ID/knowledge/SOURCE_ID (not Continuous Learning)chatbots:write
PATCH /api/v1/chatbots/ID/website { domain?, status?, theme?: { brand_color?, header_color?, font?, position?, launcher_style?, open_by_default? } }chatbots:write
POST /api/v1/chatbots/ID/website/match-theme { url? }chatbots:write
POST /api/v1/chatbots/ID/website/preview-link { expires_in_days?: 0, 7, 14 or 30 }chatbots:write

A chatbot from a website, in one call

Give a website and Deskee reads the whole site into the chatbot's knowledge in the background (follow site_crawl on GET /api/v1/chatbots/ID), styles the widget in the site's colours and font, and locks it to that domain.

curl -X POST https://deskee.io/api/v1/chatbots \
  -H "Authorization: Bearer dsk_…" -H "Content-Type: application/json" \
  -d '{"name":"Harbour Bakery","website":"https://bakery.example.com"}'

Persona, knowledge and look

PATCH /api/v1/chatbots/ID/persona
{ "name": "Bella", "welcome_message": "Hi! How can I help?", "tones": ["friendly", "concise"] }

POST /api/v1/chatbots/ID/knowledge
{ "type": "text", "label": "This week", "content": "Special: bacon & brie sourdough with a coffee, £6.50 until Sunday." }

PATCH /api/v1/chatbots/ID/website
{ "theme": { "brand_color": "#C2410C", "font": "lato", "launcher_style": "pill" }, "status": "published" }

When something changes, such as a new weekly special, update the existing source (PATCH with new content) rather than adding another, so the chatbot doesn't see both. Reading a whole website tidies every page with AI, so an account can start 5 of those through the API a day; refreshing single pages is limited to 50 a day.

Persona updates change only the fields you send; text is in the chatbot's main language. Tones: friendly, professional, concise, playful, empathetic, formal, casual, enthusiastic, reassuring. Colours are hex codes: a full light and dark palette is built from them, and a colour too pale to build one from is refused. Launcher styles: bubble, edge_tab, peek, drawer, pill, ask_bar, chips, preview, dock, spotlight. Positions: bottom-right, bottom-left, top-right, top-left, middle-right, middle-left.

Conversations

Read and answer conversations from every channel: website, email, phone, Telegram, SMS and the chat API. Phone calls can only be read: to follow one up, call the customer back.

EndpointScope
GET /api/v1/conversations?chatbot_id&status&before&limit, newest firstconversations:read
GET /api/v1/conversations/ID, with its messagesconversations:read
POST /api/v1/conversations/ID/reply { text }: replies as the account owner and takes the conversation overconversations:reply
POST /api/v1/conversations/ID/hand-back, POST /api/v1/conversations/ID/closeconversations:reply

MCP server

Deskee is a Model Context Protocol server at https://deskee.io/mcp (Streamable HTTP), so an AI assistant can build and run a chatbot for you: "Set up a Deskee chatbot for my bakery from my website and match my colours." It uses the same API keys; each tool checks its key's permissions.

Tools: list_chatbots, get_chatbot, create_chatbot, update_chatbot, update_persona, list_knowledge, get_knowledge, add_knowledge, update_knowledge, remove_knowledge, update_website, match_website_theme, get_preview_link, ask_chatbot, list_conversations, get_conversation, reply_to_conversation, hand_back_conversation, close_conversation. Apart from removing a knowledge source, nothing can be deleted. ask_chatbot runs a private test chat that doesn't use the monthly AI conversations.

Claude Code

claude mcp add --transport http deskee https://deskee.io/mcp --header "Authorization: Bearer dsk_…"

Cursor and other clients that take a URL and headers

{
  "mcpServers": {
    "deskee": {
      "url": "https://deskee.io/mcp",
      "headers": { "Authorization": "Bearer dsk_…" }
    }
  }
}

Claude Desktop

{
  "mcpServers": {
    "deskee": {
      "command": "npx",
      "args": ["mcp-remote", "https://deskee.io/mcp", "--header", "Authorization: Bearer dsk_…"]
    }
  }
}

The web connectors on claude.ai and ChatGPT sign in with OAuth rather than a key, so they can't connect yet. We're working on it.

Calendars

Read open times and book appointments in an account's Deskee calendars, with the calendars:read and calendars:book permissions. Bookings get the same confirmation emails and calendar invites as any other.

GET  /api/calendars/CALENDAR_ID/slots?from=2026-10-01&to=2026-10-07
POST /api/calendars/CALENDAR_ID/bookings     (send an Idempotency-Key header)
{ "start": "2026-10-06T09:00:00+01:00", "attendee_name": "Ada Lovelace", "attendee_email": "ada@example.com" }
POST /api/calendars/CALENDAR_ID/bookings/BOOKING_ID/cancel

Errors and limits

Errors come back as { "error": "…" } with a readable message:

StatusMeans
400Something in the request isn't valid
401The key is missing, wrong or revoked
403The key lacks the permission (named in scope)
404No such chatbot or conversation on this account
409Switched off or closed: the chatbot's API channel or the chatbot is in Draft, the conversation is closed, or a plan limit is reached
429Too many requests: 120 a minute per key (see Retry-After), or the daily limit on whole-website reads (5) or page refreshes (50)

Questions or ideas? hello@deskee.io

Get your API key

The API and MCP server come with Pro. Create a key under Account → API keys and you're ready.

Get Pro