API Documentation
Complete reference for the comxbot API. All endpoints use JSON request/response bodies, return a consistent error envelope, and support idempotency keys for safe retries.
Base URL
https://app.comxbot.comAll API paths are relative to this base URL. Use HTTPS for all requests.
Authentication
Public endpoints
Routes under /api/public/v1/ do not require authentication. They are rate-limited by IP address. These endpoints power the embeddable chat widget and public forms.
Organisation endpoints
Routes under /api/org/v1/ require a valid Clerk session with an active organisation context. Include the session token via cookie or the Authorization: Bearer <token> header.
API Keys
For server-to-server integration, generate Organisation API Keys in Settings > API Keys. Pass the key as a Bearer token. Keys are scoped to the organisation and can be rotated at any time.
Webhook verification
All inbound webhooks must be verified against the raw request body. Clerk uses Svix signatures, Stripe uses Stripe-Signature. Never transform the body before verification.
Security note: Never expose Organisation API keys in client-side code. Use them only in server-to-server communication.
Public API
No authentication required. Rate-limited by IP address (20 requests/minute for chat, 5/minute for enquiries).
| Method | Endpoint |
|---|---|
| POST | /api/public/v1/chat/sessions |
| POST | /api/public/v1/chat/messages |
| POST | /api/public/v1/enquiries |
| GET | /api/public/v1/answers/{answerId} |
Organisation API
Requires Clerk session with active organisation context or a valid Organisation API Key.
| Method | Endpoint |
|---|---|
| POST | /api/org/v1/sources |
| POST | /api/org/v1/ingest-jobs |
| GET | /api/org/v1/sources/{sourceId}/health |
| GET | /api/org/v1/inbox/threads |
| POST | /api/org/v1/handoffs |
| POST | /api/org/v1/actions/proposals |
| POST | /api/org/v1/actions/{proposalId}/approve |
| POST | /api/org/v1/actions/{proposalId}/execute |
| GET | /api/org/v1/templates |
| POST | /api/org/v1/templates |
| GET | /api/org/v1/safeguarding |
| PUT | /api/org/v1/safeguarding |
| POST | /api/org/v1/thinkguide/sessions |
| POST | /api/org/v1/thinkguide/sessions/{sessionId}/step |
| GET | /api/org/v1/thinkguide/sessions/{sessionId} |
| GET | /api/org/v1/learner-accessibility/{learnerId} |
| PUT | /api/org/v1/learner-accessibility/{learnerId} |
Webhooks
Inbound webhooks from third-party services. Always verify signatures before processing.
| Method | Endpoint |
|---|---|
| POST | /api/webhooks/clerk |
| POST | /api/webhooks/stripe |
Webhook Verification Example
When comxbot sends webhooks to your custom action endpoints, each request includes a signature header:
const crypto = require('crypto');
function verifyComxbotWebhook(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
// In your handler:
const signature = req.headers['x-comx-signature'];
const isValid = verifyComxbotWebhook(
JSON.stringify(req.body),
signature,
process.env.COMX_WEBHOOK_SECRET
);
if (!isValid) {
return res.status(401).json({ error: 'Invalid signature' });
}The signature is HMAC-SHA256 of the raw request body using your webhook secret (found in Settings > Webhooks). Always verify before processing.
Error Codes
All errors follow a consistent envelope format:
{
"error": {
"code": "COMX_VALIDATION_ERROR",
"message": "Human-readable description",
"request_id": "req_abc123",
"retryable": false,
"details": { "field": "email" }
}
}| Code | HTTP |
|---|---|
COMX_VALIDATION_ERROR | 400 |
COMX_UNAUTHENTICATED | 401 |
COMX_FORBIDDEN | 403 |
COMX_NOT_FOUND | 404 |
COMX_IDEMPOTENCY_CONFLICT | 409 |
COMX_POLICY_BLOCK | 403 |
COMX_RATE_LIMITED | 429 |
COMX_PROVIDER_UNAVAILABLE | 503 |
COMX_INTERNAL_ERROR | 500 |
Rate Limiting
Public chat
20
requests per minute per IP
Public enquiries
5
requests per minute per IP
Org API
60
requests per minute per key
When rate-limited, the response includes a Retry-After header with the number of seconds to wait. All mutating endpoints accept an Idempotency-Key header for safe retries.
// Rate limit response headers X-RateLimit-Limit: 60 X-RateLimit-Remaining: 54 X-RateLimit-Reset: 1716550000 Retry-After: 42 // Only present on 429 responses
Need help? Contact support or visit the Help Centre.