Everything an AI agent can do with the Crisp API.

A reference guide for building AI agents: every method, how to authenticate, and the permissions each one needs.

Endpoints30
API versionv1
Last updated23 June 2026
Orientation

How the Crisp API works.

The Crisp API is how an app or AI agent works with a Crisp support workspace: listing conversations, sending a message to a customer, moving a conversation to resolved, or creating and updating contact profiles in the CRM. Access is granted through a plugin token, which carries fine-grained scopes set per area at read or write level, so a token reaches only the conversations, messages, contacts, or settings it was granted. Crisp can also push events to a plugin's endpoint, so an integration learns about new messages and state changes without polling.

30Endpoints
8Capability groups
15Read
15Write
8Permissions
Authentication
Crisp authenticates with a token pair, an identifier and a key, sent as HTTP Basic auth (the two joined by a colon and base64-encoded) together with an X-Crisp-Tier header naming the tier. A plugin token, made in the Marketplace, works across every workspace that installs the plugin; a website token works on one workspace. Tokens are permanent and reused on every request.
Permissions
A plugin token carries fine-grained scopes, each granted at read-only, read-and-write, or write-only. A scope maps to an API area, like website:conversation:messages for reading and sending messages or website:people:profiles for the CRM, so the token reaches only what it was granted. Scopes apply to production tokens; a request beyond them returns a not_allowed error.
Versioning
The REST API is a single, continuously updated version with no dated version to pin. Routes live under the v1 path and Crisp ships changes through its product updates rather than minting new dated versions, so an integration tracks the updates instead of upgrading a version header.
Data model
Crisp is organized around a website (a workspace). Inside it, a conversation is a session identified by a session_id, holding messages; a contact is a people profile identified by a people_id in the CRM. Most routes are nested under /website/{website_id}, so an integration always works in the context of one workspace.
Connect & authenticate

Connection & authentication methods.

How an app or AI agent connects to Crisp determines what it can reach. There is a route for making calls, a route for receiving events, and a hosted server that exposes Crisp tools to agents, and each is governed by the token behind it and the scopes that token carries.

Ways to connect

REST API

The REST API takes and returns JSON over HTTPS at https://api.crisp.chat/v1, with list routes paged by a page number in the path. A call authenticates with a plugin or user token sent as HTTP Basic auth, the token identifier and key joined by a colon and base64-encoded, alongside an X-Crisp-Tier header naming the tier (plugin or user). Most routes are scoped to one website by its website_id.

Best forConnecting an app or AI agent to a Crisp workspace.
Governed byThe plugin token and the scopes it carries.
Docs ↗

Web Hooks

Crisp POSTs a JSON body to a plugin's registered HTTPS endpoint when a subscribed event fires, like message:send or session:set_state. The receiver verifies the X-Crisp-Signature header, an HMAC-SHA256 over the request timestamp and body computed with the plugin's signing secret, and must answer 200 or Crisp retries delivery.

Best forReceiving Crisp events at an app or AI agent without polling.
Governed byThe plugin subscription and its signing secret.
Docs ↗

MCP server

Crisp hosts a Model Context Protocol server that exposes a subset of its REST API to an AI agent, so an agent can retrieve workspace information and perform actions like managing the inbox and CRM. It is connected from an AI client and authenticated with Crisp plugin credentials, and the scopes on those credentials still bound what the agent can reach.

Best forConnecting an AI agent to Crisp through MCP.
Governed byThe plugin credentials and the scopes they carry.
Docs ↗
Authentication

Plugin token

A plugin token is created in the Crisp Marketplace and can act across every workspace that installs the plugin. It carries fine-grained scopes, each requested at a read-only, read-and-write, or write-only level, so the token reaches only the areas it was granted. Scopes apply to production tokens; development tokens are unrestricted but for local use only. The token is permanent and reused on every request.

TokenIdentifier + key, sent as Basic auth with X-Crisp-Tier: plugin
Best forMulti-workspace integrations and AI agents needing least-privilege scopes.
Docs ↗

Website token

A website token is generated directly in the Crisp app for a single workspace. It is not scope-limited the way a plugin token is, and it carries a higher default daily quota. It authenticates the same way, as Basic auth from the identifier and key, but with the user tier.

TokenIdentifier + key, sent as Basic auth with X-Crisp-Tier: user
Best forSingle-workspace scripts and internal tools.
Docs ↗
Capability map

What an AI agent can do in Crisp.

The Crisp API is split into areas an agent can act on, like conversations, messages, contact profiles, website settings, operators, visitors, and campaigns. Each area maps to its own plugin scope, and writing a message or changing a conversation state reaches a real customer.

Endpoint reference

Every Crisp API method.

Filter by method, access, or permission, or search any path. Select a row for version detail, rate limits, the related webhook event, and the source.

MethodEndpointWhat it doesAccessPermissionVersion

Conversations

Methods for listing, creating, reading, and removing conversations, each modeled as a session.4

Read on the website:conversation:sessions scope. A plugin token needs this scope granted to list sessions.

Acts onconversation
Permission (capability)website:conversation:sessions
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Write on the website:conversation:sessions scope. Returns the new session_id used for every later call on the conversation.

Acts onconversation
Permission (capability)website:conversation:sessions
VersionAvailable since the API’s base version
Webhook eventsession-request-initiated
Rate limitStandard limits apply

Read on the website:conversation:sessions scope.

Acts onconversation
Permission (capability)website:conversation:sessions
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Write on the website:conversation:sessions scope. Irreversible; the conversation and its messages are deleted.

Acts onconversation
Permission (capability)website:conversation:sessions
VersionAvailable since the API’s base version
Webhook eventsession-removed
Rate limitStandard limits apply

Messages

Methods for reading and sending the messages inside a conversation.5

Read on the website:conversation:messages scope.

Acts onmessage
Permission (capability)website:conversation:messages
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Write on the website:conversation:messages scope. A message sent from a plugin as an operator fires message:received to the visitor.

Acts onmessage
Permission (capability)website:conversation:messages
VersionAvailable since the API’s base version
Webhook eventmessage-received
Rate limitStandard limits apply

Read on the website:conversation:messages scope.

Acts onmessage
Permission (capability)website:conversation:messages
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Write on the website:conversation:messages scope.

Acts onmessage
Permission (capability)website:conversation:messages
VersionAvailable since the API’s base version
Webhook eventmessage-updated
Rate limitStandard limits apply

Write on the website:conversation:messages scope.

Acts onmessage
Permission (capability)website:conversation:messages
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Conversation state & routing

Methods for changing a conversation's state, metadata, assignment, and block status.6

Read on the website:conversation:states scope.

Acts onconversation_state
Permission (capability)website:conversation:states
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Write on the website:conversation:states scope. Moving a conversation to resolved fires session:set_state.

Acts onconversation_state
Permission (capability)website:conversation:states
VersionAvailable since the API’s base version
Webhook eventsession-set-state
Rate limitStandard limits apply

Read on the website:conversation:sessions scope.

Acts onconversation_meta
Permission (capability)website:conversation:sessions
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Write on the website:conversation:sessions scope. Setting an email or nickname fires the matching session:set_* event.

Acts onconversation_meta
Permission (capability)website:conversation:sessions
VersionAvailable since the API’s base version
Webhook eventsession-set-email
Rate limitStandard limits apply

Write on the website:conversation:sessions scope. Sets which operator the conversation is assigned to.

Acts onconversation_routing
Permission (capability)website:conversation:sessions
VersionAvailable since the API’s base version
Webhook eventsession-set-routing
Rate limitStandard limits apply

Write on the website:conversation:sessions scope. Blocking stops further incoming messages from the visitor.

Acts onconversation_block
Permission (capability)website:conversation:sessions
VersionAvailable since the API’s base version
Webhook eventsession-set-block
Rate limitStandard limits apply

People (Contacts)

Methods for listing, reading, creating, and updating CRM contact profiles.7

Read on the website:people:profiles scope. Supports search and filtering by segment, data, and text.

Acts onpeople_profile
Permission (capability)website:people:profiles
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Write on the website:people:profiles scope. Creating a profile fires people:profile:created.

Acts onpeople_profile
Permission (capability)website:people:profiles
VersionAvailable since the API’s base version
Webhook eventpeople-profile-created
Rate limitStandard limits apply

Read on the website:people:profiles scope.

Acts onpeople_profile
Permission (capability)website:people:profiles
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Write on the website:people:profiles scope. Updating a profile fires people:profile:updated.

Acts onpeople_profile
Permission (capability)website:people:profiles
VersionAvailable since the API’s base version
Webhook eventpeople-profile-updated
Rate limitStandard limits apply

Write on the website:people:profiles scope. A PUT replaces the whole profile card rather than patching fields.

Acts onpeople_profile
Permission (capability)website:people:profiles
VersionAvailable since the API’s base version
Webhook eventpeople-profile-updated
Rate limitStandard limits apply

Write on the website:people:profiles scope. Irreversible; fires people:profile:removed.

Acts onpeople_profile
Permission (capability)website:people:profiles
VersionAvailable since the API’s base version
Webhook eventpeople-profile-removed
Rate limitStandard limits apply

Read on the website:people:profiles scope.

Acts onpeople_data
Permission (capability)website:people:profiles
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Website settings

Methods for reading and updating a website's configuration.2

Read on the website:settings scope.

Acts onwebsite_settings
Permission (capability)website:settings
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Write on the website:settings scope. Changes apply to the whole workspace.

Acts onwebsite_settings
Permission (capability)website:settings
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Operators

Methods for listing and reading the operators (team members) on a website.2

Read on the website:operators scope.

Acts onoperator
Permission (capability)website:operators
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Read on the website:operators scope.

Acts onoperator
Permission (capability)website:operators
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Visitors

Methods for listing and counting the visitors currently browsing.2

Read on the website:visitors scope.

Acts onvisitor
Permission (capability)website:visitors
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Read on the website:visitors scope.

Acts onvisitor
Permission (capability)website:visitors
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Campaigns

Methods for listing and dispatching marketing campaigns.2

Read on the website:campaign:templates scope.

Acts oncampaign
Permission (capability)website:campaign:templates
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Write on the website:campaign:templates scope. Dispatching sends the campaign to contacts.

Acts oncampaign
Permission (capability)website:campaign:templates
VersionAvailable since the API’s base version
Webhook eventcampaign-dispatched
Rate limitStandard limits apply
No endpoints match those filters.
Webhooks

Webhook events.

Crisp can notify an app when something happens in a workspace, like a visitor sending a message or a conversation moving to resolved. A plugin registers for the events it wants and Crisp posts each one to the plugin's HTTPS endpoint, so an integration learns about activity without polling.

EventWhat it signalsTriggered by
message:sendA message was sent from a visitor and received by operators. This is the primary signal that a customer has written in.In-app only
message:receivedA message was sent from an operator and received by the visitor, including messages an integration sends./website/{website_id}/conversation/{session_id}/message
message:updatedA message in a conversation was updated./website/{website_id}/conversation/{session_id}/message/{fingerprint}
session:request:initiatedA session was initiated, meaning a conversation was started./website/{website_id}/conversation
session:set_stateA conversation's state changed, for example to resolved./website/{website_id}/conversation/{session_id}/state
session:set_emailAn email address was set on a conversation's contact./website/{website_id}/conversation/{session_id}/meta
session:set_routingA routing assignment was set on a conversation./website/{website_id}/conversation/{session_id}/routing
session:set_blockA conversation was blocked or unblocked./website/{website_id}/conversation/{session_id}/block
session:removedA session was removed, meaning a conversation was deleted./website/{website_id}/conversation/{session_id}
people:profile:createdA people (CRM contact) profile was created./website/{website_id}/people/profile
people:profile:updatedA people (CRM contact) profile was updated./website/{website_id}/people/profile/{people_id}
/website/{website_id}/people/profile/{people_id}
people:profile:removedA people (CRM contact) profile was removed./website/{website_id}/people/profile/{people_id}
campaign:dispatchedA campaign was dispatched to its audience./website/{website_id}/campaign/{campaign_id}/dispatch
No events match that search.
Rate limits & pagination

Rate limits, pagination & request size.

Crisp limits how much an app can call through a daily request quota on a plugin token, with separate global and per-route limiters guarding the platform underneath.

Request rate

Crisp guards the API with several limiters. A permanent plugin token is governed by a daily request quota, 5,000 requests per day by default, and a website token by a higher 10,000 per day; a plugin quota can be raised on request in the Marketplace. Underneath, a global limiter keyed by IP and identifier and a per-route limiter apply to non-plugin traffic, and a permissive edge load-balancer limit sits on top. GET and HEAD requests pass through a cache layer that lets them be called more often without counting the same way, with a Bloom-Status response header showing MISS, HIT, DIRECT, or OFFLINE. Going over returns HTTP 429, or 420 from the calm limiter.

Pagination

List routes page through results with a page number in the path, like /conversations/{page_number} or /people/profiles/{page_number}, starting at page 1 and incrementing until a page returns fewer results. Conversation messages page instead by a timestamp_before query value, fetching older messages before a given point.

Request size

List pages return a fixed number of items per page set by the route, so an integration walks pages rather than asking for a custom page size. Message history is retrieved in timestamp-bounded windows rather than one unbounded list.

Errors

Status codes & error handling.

The status codes an agent should handle, and what to do about each.

StatusCodeMeaningWhat to do
400invalid_dataThe submitted data was rejected by the route's schema validators.Read the reason in the response body, fix the request fields, and resend.
401invalid_sessionThe token was missing or not encoded correctly as Basic auth, so the request was not authenticated.Base64-encode the identifier and key joined by a colon, send it as Basic auth, and include the X-Crisp-Tier header.
403not_allowedThe token is valid but lacks the scope or permission the route needs.Grant the route's scope to the plugin token at the right read or write level and retry.
404not_foundThe requested resource, like a conversation or profile, does not exist or is not visible to this token.Verify the website_id, session_id, or people_id and that the resource lives in this workspace.
409conflictThe request conflicts with the current state of the resource, such as creating something that already exists.Re-check the resource state and adjust the request before retrying.
429rate_limitedToo many requests, or a plugin token's daily quota was exhausted. Crisp may also return 420 for its calm limiter.Back off and retry later, lean on the GET cache layer, and request a quota increase in the Marketplace if needed.
Versioning & freshness

Version history.

Crisp serves a single, continuously updated version of its REST API, with no dated version to pin, and ships changes through its product updates rather than new dated versions.

Version history

What changed, and when

Latest versionv1
v1Current version
REST API v1 (current)

Crisp serves a single, continuously updated version of its REST API under the v1 path, with no dated version to pin. New routes and fields are added in place and announced through Crisp's product updates, so an integration tracks the updates rather than upgrading a version header.

What changed
  • Single continuously updated v1 API; no dated version pinning.
  • Plugin tokens carry fine-grained, per-area scopes at read or write levels.
  • A first-party MCP server exposes a subset of the API to AI agents.
2026-04-02Feature update
Spring 2026 platform update

An additive platform update extended the API surface without changing the v1 version, adding programmatic control of the Hugo AI agent and hardening the MCP server.

What changed
  • REST API can now trigger Hugo AI Agent conversations and launch workflow scenarios programmatically.
  • Hugo MCP server added HMAC signatures so receivers can verify requests come from Crisp.
  • Expanded MCP documentation for connecting Crisp to external tools.

There is one current API; track Crisp's product updates for changes.

Crisp product updates ↗
Questions

Crisp API, answered.

How does an app authenticate to the Crisp REST API?+
Every request carries a token pair, an identifier and a key, encoded as HTTP Basic auth: the two are joined with a colon and base64-encoded into the Authorization header. A separate X-Crisp-Tier header names the tier, plugin or user. Sending the token unencoded returns an invalid_session error. All requests must use HTTPS.
What is the difference between a plugin token and a website token?+
A website token is generated in the Crisp app for a single workspace and is not scope-limited. A plugin token is created in the Crisp Marketplace, can act across every workspace that installs the plugin, and carries fine-grained scopes set per area. A plugin token sends the plugin tier; a website token sends the user tier.
How do scopes work for a plugin token?+
Each scope maps to an API area and is requested at a permission level, read-only, read-and-write, or write-only. For example website:conversation:messages covers reading and sending messages, website:conversation:sessions covers reading and updating conversations, and website:people:profiles covers the CRM. Scopes apply to production tokens; development tokens are unrestricted but for local use only. A call beyond a token's scopes is rejected.
What are the rate limits?+
A permanent plugin token is governed by a daily quota, 5,000 requests per day by default, which can be raised on request in the Marketplace; a website token gets 10,000 per day. Global and per-route limiters apply underneath, and GET and HEAD requests pass through a cache layer that eases their cost. Going over returns HTTP 429, or 420 from Crisp's calm limiter.
How does an integration receive events from Crisp?+
A plugin registers web hooks for the events it wants, like message:send when a visitor writes in or session:set_state when a conversation is resolved. Crisp POSTs each event as JSON to the plugin's HTTPS endpoint. The receiver verifies the X-Crisp-Signature header, an HMAC-SHA256 over the timestamp and body, and must answer 200 or Crisp retries delivery.
Does Crisp offer an MCP server for AI agents?+
Yes. Crisp hosts a Model Context Protocol server that exposes a subset of the REST API to an AI agent, letting it retrieve workspace information and perform actions like managing the inbox and CRM. It is connected from an AI client using Crisp plugin credentials, and the scopes on those credentials still limit what the agent can reach.
How are conversations and contacts identified?+
A conversation is a session identified by a session_id, unique within a website. A contact in the CRM is a people profile identified by a people_id. Both are scoped to one website, identified by its website_id, which is the first segment of almost every route.
Related

More support API guides for agents

What is Bollard AI?

Control what every AI agent can do in Crisp.

Bollard AI sits between a team's AI agents and Crisp. Grant each agent exactly the access it needs, read or write, resource by resource, and every call is checked and logged.

  • Set read, write, or full access per agent, never a shared Crisp token.
  • Denied by default, so an agent reaches only what has been explicitly allowed.
  • Every call recorded in plain English: who, what, where, and the decision.
Crisp
Support Agent
Read conversations ResourceOffReadFull use
Send messages ActionOffReadFull use
Contact profiles ResourceOffReadFull use
Website settings ResourceOffReadFull use
Per-agent access, set in Bollard AI, not in Crisp