Skip to main content

Dolly CX Agent API Reference

Complete API reference for integrating with Dolly CX Agent. All endpoints require authentication (JWT bearer token) unless otherwise noted.

Base URL

https://api.dolly.shin0x.space/api/

Authentication

All endpoints require a JWT bearer token in the Authorization header:

Authorization: Bearer <jwt_token>

Obtaining a token:

  1. Register: POST /api/auth/register
  2. Login: POST /api/auth/login
  3. Use returned access_token on subsequent requests
  4. Refresh token expires in 7 days — use /api/auth/refresh to get a new one

Webhook endpoints (/webhooks/...) use HMAC signature validation instead of JWT.


Sections


Error Responses

All errors follow this schema:

{
"error": {
"code": "ERROR_CODE",
"message": "Human-readable error message",
"details": {
"field": "value_that_caused_error"
}
}
}

Common Error Codes

CodeHTTPMeaning
INVALID_REQUEST400Request validation failed (missing/malformed fields)
UNAUTHORIZED401Missing or invalid JWT token
FORBIDDEN403Insufficient permissions (e.g., accessing another tenant's data)
NOT_FOUND404Resource does not exist
CONFLICT409Resource already exists (e.g., duplicate API key name)
RATE_LIMIT429Too many requests — back off with exponential delay
INTERNAL_ERROR500Unexpected server error — contact support

Rate Limiting

All authenticated endpoints are rate-limited per tenant:

  • Default: 100 requests / minute
  • Webhook endpoint: Fair-queued, no rate limit (token bucket per tenant)

Rate limit headers:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1678951234

On hitting the limit, the API returns 429 Too Many Requests with Retry-After header. Implement exponential backoff.


Pagination

List endpoints support cursor-based pagination:

GET /api/tenants/me/conversations?limit=20&after=cursor_from_previous_page

Response includes:

{
"data": [ ... ],
"pagination": {
"limit": 20,
"hasMore": true,
"nextCursor": "next_cursor_token"
}
}

Webhook Validation

Pancake webhook requests are signed with HMAC-SHA256. Validate the signature:

const crypto = require('crypto');
const signature = req.headers['x-pancake-signature'];
const body = req.rawBody; // Raw bytes, not JSON
const secret = process.env.PANCAKE_WEBHOOK_SECRET;

const hash = crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex');

if (hash !== signature) {
return res.status(401).send('Invalid signature');
}

Always respond to webhook within 5 seconds with HTTP 200, or Pancake will retry.


Appendix