CrowdStack API
Everything you can do in the app, you can do over HTTP. The API covers tickets, contacts, companies, deals, notes, tasks, campaigns, knowledge articles, docs, feedback, revenue and the change log, and the same 64 operations are exposed as tools on an MCP server so an AI agent can run your workspace for you.
Base URL
All endpoints live under https://crowdstack.org/api/v1/. The version is part of the path; breaking changes ship as a new version and the old one keeps working. Requests and responses are JSON, and responses are never cached.
Authentication
Create a key under Settings → General → API keys. Keys belong to the workspace, not to a person, and are shown once at creation. Send one as a bearer token on every request:
Authorization: Bearer cs_live_…
Content-Type: application/jsonWrites made with a key are attributed to the member who created it, so the audit trail always names a person. Revoking a key takes effect immediately. Keep keys in your integration's secret store; if one leaks, revoke it and create another.
Connect an AI agent
CrowdStack runs a Model Context Protocol server. Point any MCP client at it and every operation in this reference becomes a tool the model can call: read the inbox, reply to tickets, move deals, enrol contacts in campaigns, write help articles, and so on. The server tells the model to call get_workspace first so it uses your statuses, stages and fields, and it marks deleting tools as destructive so a careful client asks before using them.
| Client | How to connect |
|---|---|
| Claude Code, Cursor, and other clients that send headers | URL https://crowdstack.org/api/mcp with header Authorization: Bearer cs_live_…. For example: claude mcp add --transport http crowdstack https://crowdstack.org/api/mcp --header "Authorization: Bearer cs_live_…" |
| claude.ai and Claude Desktop connectors, ChatGPT connectors | These take a URL and nothing else, so put the key in the URL: https://crowdstack.org/api/mcp/cs_live_…. Treat that URL as the secret it is: make a dedicated key for the connector so you can revoke it on its own. |
| Custom GPTs, LangChain, and anything that reads OpenAPI | Import https://crowdstack.org/api/v1/openapi.json. It is generated from the same definitions as this page, with bearer auth declared and every operation marked consequential or not. |
The MCP server is stateless: each request is complete in itself, there is no session to keep alive, and it answers with plain JSON. The endpoint accepts POST only; GET returns 405 by design.
A few tools act outward. A public reply on a ticket can email the customer, activating a campaign starts sending, and the delete tools are permanent. The tool descriptions say so, and it is worth telling your agent which of those it may do without asking.
Errors
Every error has the same shape. code is stable and meant for programs; message is for people.
{
"error": {
"code": "validation_failed",
"message": "The request body did not validate.",
"details": [
{ "path": "fields.demo_url", "message": "Unknown field. Defined fields: plan_interest." }
]
}
}| Status | Code | When |
|---|---|---|
| 400 | invalid_request | The body is not valid JSON. |
| 401 | unauthorized | The key is missing, revoked, or unknown. |
| 404 | not_found | The record is not in this workspace. |
| 422 | validation_failed | The body failed validation. `details` lists each problem. |
| 429 | rate_limited | The key is over its per-minute limit. Retry after a short wait. |
| 500 | internal | Something failed on our side. Safe to retry. |
Rate limits
300 requests per minute per key, whether the calls come over REST or MCP. Over the limit you get a 429 with code rate_limited; wait a moment and retry. Limits apply per key, so give each integration its own key and one runaway script cannot starve the others.
Conventions
- Lists are newest first and paged with a cursor. Pass the
nextCursorfrom one page ascursoron the next; it isnullon the last page.limitis 1 to 100. - Updates are partial. Only keys you send change;
nullclears a value. - Statuses, priorities and stages accept the value or its label as configured in your workspace.
GET /api/v1/workspacelists them along with your custom fields and teams. - Custom field keys must already exist in Settings. Unknown keys are rejected with 422 rather than silently dropped.
Resources
- WorkspaceConfiguration an integration needs before it writes anything: statuses, priorities, stages, fields and teams.
- UsersThe people in the workspace, for assignee, owner and creator ids.
- ContactsPeople in the CRM: create or update by email, edit by id, read their timeline.
- CompaniesOrganisations in the CRM, matched by domain or name.
- DealsPipelines, stages and the deals moving through them.
- NotesFree-text notes on contacts, companies and deals.
- TicketsSupport conversations: read, open, update, reply and add internal notes.
- TasksWork items numbered T-1, T-2 and so on, with comments and projects.
- CampaignsOutreach sequences: build them, enrol people, read replies, pause and resume.
- KnowledgeHelp-centre categories and articles that ground the support AI.
- DocsInternal documentation pages the whole workspace can see.
- FeedbackProduct feedback items, votes and statuses.
- RevenueRead-only subscription metrics and customers synced from Stripe.
- AI agentsInstalled background agents and the findings they raise.
- EventsThe workspace change log, for polling what happened.