API Endpoints
This page is the route map for the current backend API.
Use it when you already know what part of the product you are touching and need the exact path, auth expectation, or response shape.
All REST endpoints are versioned under /v1/. Successful mutations with no response body return 204 No Content. JSON field names use snake_case.
How To Read This Page
The table near the top is the quickest way to find a route.
The sections below it add more detail:
- public endpoints first
- then auth and user endpoints
- then workspace, agent, conversation, integration, notification, and support endpoints
- realtime (Socket.IO) at the end
If you are new, start with the endpoint summary and the response envelope, then jump only to the section you need.
Endpoint Summary
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /v1/health | — | Health check |
| GET | /v1/legal | — | Legal documents |
| GET | /v1/models | — | List available LLM models |
| POST | /v1/fcm-token | Yes | Save push token |
| POST | /v1/auth/sign-in | Yes | Sign in |
| POST | /v1/auth/sign-up | Yes | Sign up |
| POST | /v1/auth/logout | Yes | Log out |
| DELETE | /v1/auth/delete | Yes | Delete account |
| GET | /v1/users/profile | Yes | Get user profile |
| PATCH | /v1/users | Yes | Update user profile |
| GET | /v1/users/legal | Yes | Get user legal status |
| POST | /v1/users/legal/accept | Yes | Accept legal documents |
| GET | /v1/users/usage/summary | Yes | Get monthly usage summary |
| GET | /v1/workspaces | Yes | List workspaces |
| GET | /v1/workspaces/{id} | Yes | Get workspace |
| GET | /v1/workspaces/{id}/usage | Yes | Get workspace usage |
| GET | /v1/workspaces/{workspaceId}/agents | Yes | List agents in workspace |
| GET | /v1/workspaces/{workspaceId}/conversations | Yes | List conversations |
| POST | /v1/workspaces/{workspaceId}/conversations | Yes | Create conversation |
| GET | /v1/workspaces/{workspaceId}/conversations/{id} | Yes | Get conversation |
| DELETE | /v1/workspaces/{workspaceId}/conversations/{id} | Yes | Delete conversation |
| POST | /v1/workspaces/{workspaceId}/conversations/{id}/read | Yes | Mark conversation read |
| GET | /v1/workspaces/{workspaceId}/conversations/{id}/messages | Yes | List messages |
| GET | /v1/workspaces/{workspaceId}/conversations/{id}/messages/search | Yes | Search messages |
| POST | /v1/workspaces/{workspaceId}/conversations/{id}/messages | Yes | Send message |
| POST | /v1/workspaces/{workspaceId}/messages/{id}/action | Yes | Respond to action card |
| GET | /v1/agents/{id} | Yes | Get agent |
| GET | /v1/agents/{id}/details | Yes | Get agent details |
| GET | /v1/agents/{id}/history | Yes | Get agent conversation history |
| GET | /v1/agents/{id}/settings | Yes | Get agent settings |
| GET | /v1/agents/{id}/tools | Yes | Get agent tools |
| GET | /v1/agents/{id}/memories | Yes | List agent memories |
| POST | /v1/agents/{id}/memories | Yes | Create agent memory |
| DELETE | /v1/agents/{id}/memories/{key} | Yes | Delete agent memory |
| POST | /v1/auth/logout | Yes | Log out |
| POST | /v1/uploads | Yes | Upload file |
| GET | /v1/integrations | Yes | List tools and integrations |
| POST | /v1/integrations/connect | Yes | Get OAuth config |
| POST | /v1/integrations/callback | Yes | Send OAuth auth code |
| WS | /socket.io/ (/v1 namespace) | Yes | Realtime Socket.IO transport |
Response Envelope
Most successful REST responses are wrapped in a data envelope:
{ "data": { ... } }
Mutations that produce no body return 204 No Content.
Error Response
Errors are returned as a structured object:
{
"message": "string",
"code": "string",
"extra": {}
}
extra may be null when no additional context is available.
Common Enums
| Enum | Values |
|---|---|
| RuntimeStatus | provisioning, ready, offline, failed |
| RuntimePhase | Pending, Progressing, Ready, Error |
| AgentStatus | online, reading, thinking, writing, pending, error, offline |
| AgentModel | flash, sonnet, opus |
| ResponseLength | auto, short, medium, long |
| ConversationType | swarm, agent |
| MessageRole | user, agent, system |
| MessageStatus | pending, sent, delivered, read, failed, incomplete, silent, delegated |
| MessageContentType | text, action_card, tool_status, system, loading, delegation, artifact, workflow |
| AgentRole | manager, sub-agent |
| DelegationStatus | running, completed, failed |
| AttachmentType | image, video, audio, file |
| ActionStyle | primary, secondary, destructive |
| ToolState | running, completed, failed |
| IntegrationItemType | tool, app |
| IntegrationProvider | google_calendar, gmail, slack, jira, notion, asana, github, zoom |
Core
GET /v1/health
No authentication.
{ "data": { "online": true, "version": "1.0.0" } }
GET /v1/models
No authentication. Returns the catalog of available LLM models.
{
"data": [
{
"id": "string",
"name": "string",
"provider": "string",
"description": "string"
}
]
}
GET /v1/legal
No authentication. Returns the current legal document content and versions.
{
"data": {
"terms_of_service": "string",
"privacy_policy": "string",
"has_agreed_with_terms": false,
"has_agreed_with_privacy_policy": false,
"terms_of_service_version": "string",
"privacy_policy_version": "string"
}
}
POST /v1/fcm-token
Saves the device push token for Firebase Cloud Messaging.
Request:
{ "push_token": "string" }
Response:
{ "success": true }
Authentication
All auth endpoints require a Firebase ID token in the X-Token header.
POST /v1/auth/sign-in
No body. Response: 204 No Content.
POST /v1/auth/sign-up
No body. Response: 204 No Content.
DELETE /v1/auth/delete
Request:
{ "reason": "string", "description": "string" }
Response: 204 No Content.
POST /v1/auth/logout
Logs out the current user session.
Response: 204 No Content.
User
GET /v1/users/profile
Returns the authenticated user's full profile.
{
"data": {
"email": "string",
"firebase_uid": "string",
"nickname": "string",
"name": "string",
"surname": "string",
"avatar_url": "string",
"country_code": "string",
"date_of_birth": "ISO8601 | null",
"created_at": "ISO8601",
"is_deleted": false,
"is_banned": false,
"has_agreed_with_terms": false,
"has_agreed_with_privacy_policy": false,
"preferences": {
"platform_theme": "string",
"platform_language": "string",
"currency_code": "string"
},
"subscription": {
"name": "string",
"code": "string",
"expires_at": "ISO8601 | null"
}
}
}
PATCH /v1/users
All fields optional. Response: 204 No Content.
{
"nickname": "string",
"country_code": "string",
"surname": "string",
"name": "string",
"date_of_birth": "ISO8601",
"preferences": {
"platform_theme": "string",
"platform_language": "string",
"currency_code": "string"
}
}
GET /v1/users/legal
Returns the current legal document versions plus the user's acceptance state.
{
"data": {
"terms_of_service": "string",
"privacy_policy": "string",
"has_agreed_with_terms": false,
"has_agreed_with_privacy_policy": false,
"terms_of_service_version": "string",
"privacy_policy_version": "string"
}
}
POST /v1/users/legal/accept
Accepts one or both legal document versions. All fields optional.
Request:
{
"terms_of_service_version": "string",
"privacy_policy_version": "string"
}
Response: 204 No Content.
GET /v1/users/usage/summary
Returns the authenticated user's monthly token usage summary.
{
"data": {
"current_period": "2026-04",
"tokens_used": 487000,
"prompt_tokens_used": 312000,
"completion_tokens_used": 175000,
"request_count": 156,
"token_limit": 500000,
"plan_id": "free"
}
}
Workspaces
Each workspace response includes a runtime object representing the current swarm status.
Workspace shape:
{
"id": "string",
"name": "string",
"created_at": "ISO8601",
"updated_at": "ISO8601",
"runtime": {
"status": "provisioning | ready | offline | failed",
"phase": "Pending | Progressing | Ready | Error",
"verified": false,
"total_agents": 0,
"last_message_preview": {
"text": "string",
"sender_name": "string",
"timestamp": "ISO8601"
}
}
}
GET /v1/workspaces
Returns all workspaces owned by the authenticated user.
{ "data": [ ...workspaces ] }
GET /v1/workspaces/:id
Returns a single workspace by ID.
{ "data": workspace }
GET /v1/workspaces/:id/usage
Returns token usage for a specific workspace for the current billing period.
{
"data": {
"period": "2026-04",
"tokens_used": 487000,
"prompt_tokens_used": 312000,
"completion_tokens_used": 175000,
"request_count": 156,
"token_limit": 500000
}
}
Agents
GET /v1/workspaces/{workspaceId}/agents
Returns all agents belonging to the workspace.
{
"data": [
{
"id": "string",
"name": "string",
"role": "string",
"slug": "string",
"avatar": "string",
"status": "online | busy | pending | error | offline"
}
]
}
GET /v1/agents/{id}
Returns a single agent summary (same shape as the list item above).
{
"data": {
"id": "string",
"name": "string",
"role": "string",
"slug": "string",
"avatar": "string",
"status": "online | busy | pending | error | offline"
}
}
GET /v1/agents/{id}/details
Returns the full agent profile including skills and stats.
{
"data": {
"id": "string",
"workspace_id": "string",
"name": "string",
"role": "string",
"slug": "string",
"created_at": "ISO8601",
"updated_at": "ISO8601 | null",
"description": "string",
"avatar_url": "string",
"status": "online | busy | pending | error | offline",
"sort_order": 0,
"skills": [
"web_search",
"analysis",
"fact_check",
"news",
"sources",
"coding",
"writing",
"translation",
"summarization",
"planning"
],
"stats": {
"total_messages": 0,
"memory_used_pct": 0
}
}
}
GET /v1/agents/{id}/memories
Returns the agent's memories. Supports optional category filtering.
Query params: category (string, optional — e.g. core)
{
"data": [
{
"key": "string",
"content": "string",
"category": "core",
"created_at": "ISO8601",
"updated_at": "ISO8601"
}
]
}
POST /v1/agents/{id}/memories
Creates a new agent memory.
Request:
{
"key": "string",
"content": "string",
"category": "core"
}
Response:
{
"data": {
"key": "string",
"content": "string",
"category": "core",
"created_at": "ISO8601",
"updated_at": "ISO8601"
}
}
DELETE /v1/agents/{id}/memories/{key}
Deletes a specific agent memory by key.
Response: 204 No Content.
GET /v1/agents/{id}/settings
Returns the agent's model configuration and available system prompts.
{
"data": {
"model": "flash | sonnet | opus",
"response_length": "auto | short | medium | long",
"prompts": [
{
"id": "string",
"name": "string",
"description": "string",
"content": "string"
}
]
}
}
GET /v1/agents/:id/tools
Returns the tools available to this agent.
{
"data": [
{
"name": "string",
"description": "string",
"icon_url": "string",
"category_id": "string",
"enabled": true
}
]
}
GET /v1/agents/:id/memories
Returns the agent's stored memories.
{
"data": [
{
"key": "string",
"content": "string",
"created_at": "ISO8601"
}
]
}
POST /v1/agents/:id/memories
Creates a new memory for the agent.
Request:
{ "key": "string", "content": "string" }
Response: 204 No Content.
DELETE /v1/agents/:id/memories/:key
Deletes a specific memory by key.
Response: 204 No Content.
Conversations and Messages
GET /v1/workspaces/:workspaceId/conversations
Lists conversations for a workspace. Each item includes the last message and unread count.
{
"data": [
{
"id": "string",
"type": "swarm | agent",
"title": "string",
"created_at": "ISO8601",
"updated_at": "ISO8601",
"unread_count": 0,
"agent": {
"id": "string",
"name": "string",
"role": "string",
"slug": "string",
"avatar": "string",
"status": "string"
},
"last_message": "MessageData | null"
}
]
}
agent is null for swarm conversations.
POST /v1/workspaces/:workspaceId/conversations
Creates a new conversation in the workspace.
Request:
{ "type": "swarm | agent", "agent_id": "string | null" }
Response: returns the created conversation object.
GET /v1/workspaces/:workspaceId/conversations/:id
Returns one conversation (same shape as a list item).
DELETE /v1/workspaces/:workspaceId/conversations/:id
Deletes a conversation permanently.
Response: 204 No Content.
POST /v1/workspaces/:workspaceId/conversations/:id/read
Marks a conversation as read.
Response: 204 No Content.
GET /v1/workspaces/:workspaceId/conversations/:id/messages
Lists messages with cursor-based pagination.
Query params: scrollId (string, cursor token), limit (int), direction ("forward" or "backward")
{
"data": [
{
"id": "string",
"conversation_id": "string",
"role": "user | agent | system",
"content": "MessageContent (see below)",
"status": "pending | delivered | failed",
"created_at": "ISO8601",
"updated_at": "ISO8601",
"local_id": "string | null",
"agent": "AgentData | null",
"attachments": [
{
"id": "string",
"url": "string",
"type": "image | video | audio | file",
"name": "string",
"size": 0,
"mime_type": "string",
"duration": "int | null"
}
],
"mentions": [
{
"agent_id": "string",
"agent_name": "string",
"offset": 0,
"length": 0
}
]
}
],
"pagination": {
"next_scroll_id": "string",
"prev_scroll_id": "string",
"has_next": true,
"has_prev": false
}
}
MessageContent
content is a discriminated union on the type field:
| type | Fields |
|---|---|
text | text: string |
action_card | title: string, description: string, actions: [{ id, label, style }], selected_action_id: string? |
tool_status | tool: string, description: string, state: running | completed | failed |
system | text: string |
loading | (no additional fields) |
delegation | from: AgentData?, to: AgentData?, status: running | completed | failed, task_preview: string |
artifact | artifact_id: string, title: string, version: int, status: string, agent_slug: string, content_preview: string |
workflow | workflow_id: string, workflow_name: string, execution_id: string, status: string, steps: WorkflowStepSummary[] |
ActionStyle values: primary, secondary, destructive.
Delegation content type
Sent via socket as the agent.delegation event payload embedded in a message. Represents an agent-to-agent task hand-off.
{
"type": "delegation",
"from": {
"id": "string",
"name": "string",
"role": "manager|sub-agent",
"slug": "string",
"avatar": "string",
"status": "online|offline|busy"
},
"to": {
"id": "string",
"name": "string",
"role": "manager|sub-agent",
"slug": "string",
"avatar": "string",
"status": "online|offline|busy"
},
"status": "running|completed|failed",
"task_preview": "string"
}
from and to are nullable — the backend may omit either if the agent is not resolved. status defaults to running on creation and is updated to completed or failed when the delegation resolves.
GET /v1/workspaces/{workspaceId}/conversations/{id}/messages/search
Searches messages within a conversation.
Query params: q (string, search query)
{
"data": [ ...messages ]
}
POST /v1/workspaces/{workspaceId}/conversations/{id}/messages
Sends a new message to a conversation.
Request:
{
"local_id": "string",
"content": { "type": "text", "text": "Hello" },
"attachments": [],
"mentions": []
}
Response: returns the created MessageData object.
POST /v1/workspaces/:workspaceId/messages/:id/action
Responds to an action card by selecting one of its actions.
Request:
{ "action_id": "string" }
Response: returns the updated MessageData object.
Uploads
POST /v1/uploads
Uploads a file. Content-Type must be multipart/form-data.
Response: returns the upload metadata.
Integrations
The integrations routes describe OAuth-backed external apps.
GET /v1/integrations
Returns categories and a flat item list containing both tools and integrations.
{
"data": {
"categories": [
{
"id": "string",
"name": "string",
"image_url": "string"
}
],
"items": [
{
"name": "string",
"description": "string",
"icon_url": "string",
"category_id": "string",
"type": "tool | app",
"provider": "google_calendar | gmail | slack | jira | notion | asana | github | zoom | null",
"enabled": true
}
]
}
}
provider is null for built-in tools. category_id may be absent on integration-type items.
POST /v1/integrations/connect
Requests the OAuth configuration for a provider.
Request:
{ "provider": "gmail" }
Response:
{
"client_id": "string",
"redirect_url": "string",
"authorization_endpoint": "string",
"token_endpoint": "string",
"scopes": ["string"],
"additional_parameters": { "key": "value" }
}
POST /v1/integrations/callback
Sends the OAuth authorization code to the backend to complete the connection flow.
Request:
{
"provider": "gmail",
"authorization_code": "string",
"code_verifier": "string",
"redirect_url": "string"
}
Response: 204 No Content.
Realtime
The Socket.IO transport endpoint is /socket.io/, and the mobile client connects to namespace /v1.
Authentication uses the same security headers as HTTP (X-Token, X-Signature, X-Device-Info, X-Device-ID, X-Version, X-Timezone, X-Timestamp).
Client → Server Events
| Event | Payload |
|---|---|
workspace.subscribe | { "workspace_ids": ["string"] } |
workspace.unsubscribe | { "workspace_ids": ["string"] } |
message.send | { "workspace_id": "string", "conversation_id": "string", "local_id": "string", "content": { "type": "string", "text": "string" }, "mentions": [{ "agent_id": "string", "agent_name": "string", "offset": int, "length": int }], "attachments": [{ "id": "string", "name": "string", "url": "string", "type": "string", "size": int, "mime_type?": "string" }] } |
Server → Client Events
| Event | Payload |
|---|---|
message.new | { "message": MessageData } |
message.updated | { "message": MessageData } |
message.send.ack | { "local_id": "string", "message_id": "string", "status": "received" } |
message.send.error | { "local_id": "string", "error": "string" } |
message.chunk | { "message_id": "string", "conversation_id": "string", "agent_id": "string", "chunk": "string" } |
message.done | { "message_id": "string", "conversation_id": "string", "agent_id": "string", "status": "delivered" | "failed" } |
agent.tool | { "agent_id": "string", "conversation_id": "string", "tool": "string", "status": "running" | "done", "query?": "string" } |
agent.status | { "agent_id": "string", "status": "AgentStatus", "conversation_id?": "string" } |
workspace.subscribed | { "workspace_ids": ["string"] } |
API Configuration Reference
| Setting | Value |
|---|---|
| Base URL (dev) | https://dev.api.crawbl.com |
| Base URL (prod) | https://api.crawbl.com |
| MCP endpoint (dev) | https://dev.api.crawbl.com (port 7172) |
| MCP endpoint (prod) | https://api.crawbl.com (port 7172) |
| River UI (prod) | https://river.crawbl.com |
| WebSocket | {baseUrl}/v1 via Socket.IO |
| Auth header | X-Token (Firebase ID token) |
| HMAC header | X-Signature = HMAC-SHA256({token}:{timestamp}, hmacSecret) |
| Extra headers | X-Device-Info, X-Device-ID, X-Version, X-Timezone, X-Timestamp |
| Connect timeout | 10s |
| Send timeout | 10s |
| Receive timeout | 60s |
| JSON casing | snake_case |
Environment Endpoints
| Environment | API | Purpose |
|---|---|---|
| dev | https://dev.api.crawbl.com | Development and CI/CD testing |
| prod | https://api.crawbl.com | Production traffic |
| River UI (prod) | https://river.crawbl.com | Background job dashboard (River) |
🔗 Terms On This Page
If a term below is unfamiliar, open its glossary entry. For the full list, go to Internal Glossary.
- Firebase JWT: The signed Firebase identity token used to authenticate a user request.
- FCM: Firebase Cloud Messaging, used for device push notifications.
- UserSwarm: The Crawbl custom resource that represents one user runtime and its lifecycle.
- Socket.IO: The realtime transport layer used to push events from the backend to connected clients.
- Cursor Pagination: A pagination style that returns opaque cursor tokens instead of page numbers.
- OAuth: The delegated login and consent flow used to connect external apps without storing user passwords.