API Reference
Helpdesk
Create helpdesk tickets from external sources like contact forms using the secret key, and read tickets and their messages with a personal access token (e.g. from the CLI).
Create a Ticket
/api/v1/helpdesk/tickets
Secret Key
10/min
Creates a new helpdesk conversation with an initial message. Finds or creates a contact by email and links to a company by email domain if one exists.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| subject | string | Yes | Ticket subject line |
| message | string | Yes | Message body (plain text) |
| string | Yes | Contact email address | |
| name | string | No | Contact name (defaults to email) |
| priority | string | No | low, normal, high, or urgent (defaults to none) |
Success Response (201)
{
"id": 42,
"subject": "Question about pricing",
"state": "new",
"priority": "normal",
"contact": {
"email": "visitor@example.com",
"name": "Visitor"
},
"created_at": "2026-02-21T10:30:00Z"
}
Error Responses
// 401 Unauthorized
{ "error": "Invalid API key" }
// 404 Not Found (helpdesk not enabled)
// 422 Unprocessable Entity
{ "error": "subject is required" }
{ "error": "message is required" }
{ "error": "email is required" }
{ "error": "priority must be one of: low, normal, high, urgent" }
// 429 Too Many Requests (rate limited)
Example
curl -X POST https://squirrelstack.app/api/v1/helpdesk/tickets \
-H "X-Api-Key: sk_live_your_secret_key" \
-H "Content-Type: application/json" \
-d '{
"subject": "Question about pricing",
"message": "Hi, I would like to know more about your pricing plans.",
"email": "visitor@example.com",
"name": "Visitor",
"priority": "normal"
}'
List Tickets
/api/v1/tickets
Secret Key / PAT
30/min
Lists helpdesk tickets for the account, most recently updated first. Returns open tickets (new + assigned) by default.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| state | string | No | open (default), new, assigned, closed, or all |
| priority | string | No | low, normal, high, or urgent |
| limit | integer | No | Max tickets to return, 1–100 (defaults to 50) |
Success Response (200)
{
"tickets": [
{
"id": 42,
"subject": "Billing question",
"state": "assigned",
"priority": "high",
"source": "email",
"contact": { "id": 7, "email": "bob@example.com", "name": "Bob Jones" },
"assignee": { "id": 5, "name": "Jane Agent" },
"created_at": "2026-02-21T10:30:00Z",
"updated_at": "2026-02-21T11:05:00Z",
"messages_count": 3
}
]
}
assignee is null when the ticket is unassigned.
Error Responses
// 401 Unauthorized
{ "error": "Invalid or revoked token" }
// 404 Not Found (helpdesk not enabled)
// 422 Unprocessable Entity
{ "error": "state must be one of: open, all, new, assigned, closed" }
// 429 Too Many Requests (rate limited)
Example
curl https://squirrelstack.app/api/v1/tickets?state=open \
-H "Authorization: Bearer pat_your_token" \
-H "X-Account-Slug: your_account_slug"
Get a Ticket
/api/v1/tickets/:id
Secret Key / PAT
30/min
Returns a single ticket with its summary and full message history (inbound and outbound emails plus internal notes) in chronological order.
Success Response (200)
{
"ticket": {
"id": 42,
"subject": "Billing question",
"state": "assigned",
"priority": "high",
"source": "email",
"contact": { "id": 7, "email": "bob@example.com", "name": "Bob Jones" },
"assignee": { "id": 5, "name": "Jane Agent" },
"created_at": "2026-02-21T10:30:00Z",
"updated_at": "2026-02-21T11:05:00Z",
"summary": "Customer is querying a charge on their latest invoice.",
"messages": [
{
"id": 101,
"type": "email",
"body": "I have a question about my latest bill.",
"author": "Bob Jones",
"created_at": "2026-02-21T10:30:00Z",
"direction": "inbound",
"subject": "Billing question",
"from": "bob@example.com",
"to": "support@acme.example.com",
"received_at": "2026-02-21T10:30:00Z"
}
]
}
}
Message objects use the same shape as List Messages on a Ticket below — email messages include a files array when attachments are present, and notes omit the email-only fields.
Error Responses
// 401 Unauthorized
{ "error": "Invalid or revoked token" }
// 404 Not Found (helpdesk not enabled, or ticket not on this account)
// 429 Too Many Requests (rate limited)
List Messages on a Ticket
/api/v1/helpdesk/tickets/:ticket_id/messages
Secret Key
60/min
Lists the messages on a ticket — inbound and outbound emails plus internal notes — in chronological order. The ticket ID is returned when creating a ticket.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| ticket_id | integer | Yes | Ticket ID (URL segment) |
| limit | integer | No | Max messages to return, 1–100 (defaults to 50) |
Success Response (200)
{
"messages": [
{
"id": 101,
"type": "email",
"body": "I have a question about my latest bill.",
"author": "Bob Jones",
"created_at": "2026-02-21T10:30:00Z",
"direction": "inbound",
"subject": "Billing question",
"from": "bob@example.com",
"to": "support@acme.example.com",
"received_at": "2026-02-21T10:30:00Z"
},
{
"id": 102,
"type": "note",
"body": "Internal: VIP customer, expedite.",
"author": "Jane Agent",
"created_at": "2026-02-21T10:35:00Z"
}
]
}
Email messages also include a files array (id, filename, content_type, byte_size) when attachments are present. Notes omit the email-only fields (direction, subject, from, to, received_at).
Error Responses
// 401 Unauthorized
{ "error": "Invalid API key" }
// 404 Not Found (helpdesk not enabled, or ticket not on this account)
// 429 Too Many Requests (rate limited)
Example
curl https://squirrelstack.app/api/v1/helpdesk/tickets/42/messages \
-H "X-Api-Key: sk_live_your_secret_key"
Get a Message
/api/v1/helpdesk/tickets/:ticket_id/messages/:id
Secret Key
60/min
Returns a single message on a ticket. The message must belong to the given ticket.
Success Response (200)
{
"id": 103,
"type": "email",
"body": "Thanks, looking into your bill now.",
"author": "Jane Agent",
"created_at": "2026-02-21T10:40:00Z",
"direction": "outbound",
"subject": "Re: Billing question",
"from": "support@acme.example.com",
"to": "bob@example.com",
"received_at": null,
"files": [
{ "id": 7, "filename": "invoice.pdf", "content_type": "application/pdf", "byte_size": 18234 }
]
}
Error Responses
// 401 Unauthorized
{ "error": "Invalid API key" }
// 404 Not Found (helpdesk not enabled, or message not on this ticket)
// 429 Too Many Requests (rate limited)