API Documentation
Integrate TacoHelp into your apps with our REST API. Available on Pro plans and above.
Authentication
All API requests require a Bearer token. Create an API key in Settings → API Keys after signing in.
Key format: th_ prefix + 32 bytes base64url
Scopes: tickets:read, tickets:write, chat:read, chat:write, or *
Rate Limiting
100 requests per 60-second sliding window per API key. Rate limit info is returned in response headers:
Webhooks
Register webhook endpoints in Settings → Webhooks to receive real-time events. Payloads are signed with HMAC-SHA256.
Events: ticket.created, ticket.updated, ticket.commented, ticket.resolved, ticket.closed, ticket.reopened, ticket.merged
Signature header: X-Webhook-Signature
Retry policy: 3 attempts with exponential backoff (2s, 8s, 32s)
Circuit breaker: Endpoint disabled after 10 consecutive failures
Endpoints
/api/external/ticketsScope: tickets:readList tickets for your organization
Query Parameters
statusstringFilter by status (OPEN, IN_PROGRESS, WAITING, RESOLVED, CLOSED)limitnumberResults per page (default: 50, max: 100)offsetnumberPagination offset (default: 0)Response
{
"tickets": [
{
"id": "clx...",
"ticketNumber": 42,
"subject": "Login page bug",
"status": "OPEN",
"priority": "HIGH",
"tags": ["bug", "login"],
"createdAt": "2026-03-17T...",
"createdBy": { "name": "Sam", "email": "sam@example.com" },
"assignee": { "name": "Jordan", "email": "dev@example.com" }
}
],
"total": 1,
"limit": 50,
"offset": 0
}/api/external/ticketsScope: tickets:writeCreate a new ticket
Request Body
{
"subject": "Login page shows blank screen",
"description": "When I try to log in using Safari...",
"priority": "HIGH",
"createdByEmail": "client@example.com",
"tags": ["bug", "safari"]
}Response
{
"id": "clx...",
"ticketNumber": 43,
"subject": "Login page shows blank screen",
"status": "OPEN",
"priority": "HIGH",
"source": "API",
...
}/api/external/tickets/:ticketIdScope: tickets:readGet a ticket with comments
Response
{
"id": "clx...",
"ticketNumber": 42,
"subject": "Login page bug",
"description": "Full description...",
"comments": [
{
"id": "clx...",
"content": "Thanks for reporting...",
"author": { "name": "Jordan" },
"createdAt": "2026-03-17T..."
}
],
...
}/api/external/tickets/:ticketIdScope: tickets:writeUpdate a ticket
Request Body
{
"status": "IN_PROGRESS",
"priority": "URGENT",
"assigneeId": "clx...",
"tags": ["bug", "urgent"]
}Response
{ "id": "clx...", "status": "IN_PROGRESS", ... }/api/external/tickets/:ticketId/commentsScope: tickets:writeAdd a comment to a ticket
Request Body
{
"content": "We've identified the issue...",
"authorEmail": "dev@example.com"
}Response
{
"id": "clx...",
"content": "We've identified the issue...",
"author": { "name": "dev", "email": "dev@example.com" },
"createdAt": "2026-03-17T..."
}Chat API
/api/external/chat/conversationsScope: chat:readList chat conversations for your organization
Query Parameters
statusstringFilter by status (active, ended)limitnumberResults per page (default: 50, max: 100)offsetnumberPagination offset (default: 0)Response
{
"conversations": [
{
"id": "clx...",
"status": "active",
"visitorName": "Sam",
"visitorEmail": "sam@example.com",
"createdAt": "2026-03-17T...",
"updatedAt": "2026-03-17T..."
}
],
"total": 1,
"limit": 50,
"offset": 0
}/api/external/chat/conversationsScope: chat:writeStart a new chat conversation
Request Body
{
"visitorName": "Sam",
"visitorEmail": "sam@example.com"
}Response
{
"id": "clx...",
"status": "active",
"visitorName": "Sam",
"visitorEmail": "sam@example.com",
"createdAt": "2026-03-17T..."
}/api/external/chat/conversations/:conversationIdScope: chat:readGet a conversation with its messages
Response
{
"id": "clx...",
"status": "active",
"visitorName": "Sam",
"visitorEmail": "sam@example.com",
"messages": [
{
"id": "clx...",
"senderType": "visitor",
"content": "Hi, I need help with...",
"createdAt": "2026-03-17T..."
},
{
"id": "clx...",
"senderType": "agent",
"senderId": "clx...",
"content": "Sure, let me look into that.",
"createdAt": "2026-03-17T..."
}
],
"createdAt": "2026-03-17T...",
"updatedAt": "2026-03-17T..."
}/api/external/chat/conversations/:conversationId/messagesScope: chat:writeSend a message in a conversation
Request Body
{
"content": "Hi, I need help with my account.",
"senderType": "visitor"
}Response
{
"id": "clx...",
"senderType": "visitor",
"content": "Hi, I need help with my account.",
"createdAt": "2026-03-17T..."
}/api/external/chat/conversations/:conversationIdScope: chat:writeEnd a conversation
Request Body
{
"status": "ended"
}Response
{
"id": "clx...",
"status": "ended",
"updatedAt": "2026-03-17T..."
}Error Responses
400Bad request — missing or invalid parameters401Unauthorized — invalid or missing API key403Forbidden — insufficient scope404Not found — resource doesn't exist in your org429Rate limit exceeded — wait and retry500Server error — contact support