Tickets API
The Tickets API allows you to create, read, update, and delete support tickets. Tickets are the core entity for tracking customer support requests.
Ticket Object
{
id: string; // UUID
number: number; // Human-readable ticket number
organization_id: string; // UUID
subject: string; // Ticket subject (max 500 chars)
description: object; // Rich text content (TipTap JSON)
description_html?: string; // HTML version of description
status: string; // new, open, pending, in_progress, resolved, closed
priority: string; // urgent, high, normal, low
type: string; // question, bug, feature, task
tags: string[]; // Array of tag strings
requester_id?: string; // UUID of user who created the ticket
assignee_id?: string; // UUID of assigned agent
customer_id?: string; // UUID of linked customer
first_response_at?: string; // ISO timestamp of first response
resolved_at?: string; // ISO timestamp when resolved
detected_language?: string; // ISO 639-1 language code
original_subject?: string; // Original subject before translation
original_description?: object; // Original description before translation
ai_summary?: string; // AI-generated summary
metadata?: object; // Additional metadata (custom fields, etc.)
cc_emails?: string[]; // CC email addresses
created_at: string; // ISO timestamp
updated_at: string; // ISO timestamp
deleted_at?: string; // ISO timestamp (soft delete)
}
Status Values
| Status | Description |
|---|---|
new | Newly created ticket, not yet viewed |
open | Ticket is being worked on |
pending | Waiting for customer response |
in_progress | Actively being resolved |
resolved | Issue has been resolved |
closed | Ticket is closed |
Priority Values
| Priority | Description |
|---|---|
urgent | Requires immediate attention |
high | High priority |
normal | Standard priority (default) |
low | Low priority |
Type Values
| Type | Description |
|---|---|
question | General inquiry (default) |
bug | Bug report |
feature | Feature request |
task | Internal task |
List Tickets
Retrieve a paginated list of tickets with optional filters.
Procedure: tickets.list
Authentication: Required
Input:
{
// Status filters
status?: 'all' | 'new' | 'open' | 'pending' | 'in_progress' | 'resolved' | 'closed';
statuses?: Array<'new' | 'open' | 'pending' | 'in_progress' | 'resolved' | 'closed'>;
// Priority filters
priority?: 'urgent' | 'high' | 'normal' | 'low';
priorities?: Array<'urgent' | 'high' | 'normal' | 'low'>;
// Type filters
type?: 'question' | 'bug' | 'feature' | 'task';
types?: Array<'question' | 'bug' | 'feature' | 'task'>;
// Assignment filters
assigneeId?: string; // Filter by assignee UUID
unassigned?: boolean; // Filter to unassigned tickets only
// Other filters
tags?: string[]; // Filter by tags (overlaps)
createdWithin?: '1d' | '7d' | '30d' | '90d';
updatedWithin?: '1d' | '7d' | '30d' | '90d';
search?: string; // Search in subject and AI summary
// Pagination
cursor?: string; // UUID for cursor-based pagination
limit?: number; // 1-100, default: 50
// Sorting
orderBy?: 'created_at' | 'updated_at'; // default: created_at
}
Example:
curl -X GET "https://your-domain.com/api/trpc/tickets.list?input=%7B%22limit%22:20,%22statuses%22:[%22new%22,%22open%22]%7D" \
-H "Cookie: your-session-cookie"
Response:
{
"result": {
"data": {
"json": {
"tickets": [
{
"id": "uuid",
"number": 1234,
"subject": "Cannot login to my account",
"status": "new",
"priority": "high",
"type": "bug",
"tags": ["login", "urgent"],
"requester": {
"name": "John Doe",
"email": "john@example.com"
},
"assignee": null,
"customer": {
"name": "John Doe",
"email": "john@example.com"
},
"created_at": "2024-01-15T10:30:00.000Z",
"updated_at": "2024-01-15T10:30:00.000Z"
}
],
"count": 150,
"nextCursor": "uuid-of-last-ticket"
}
}
}
}
Get Ticket
Retrieve a single ticket by ID with full details including conversations.
Procedure: tickets.get
Authentication: Required
Input:
{
id: string; // Ticket UUID
}
Example:
curl -X GET "https://your-domain.com/api/trpc/tickets.get?input=%7B%22id%22:%22uuid-here%22%7D" \
-H "Cookie: your-session-cookie"
Response:
{
"result": {
"data": {
"json": {
"id": "uuid",
"number": 1234,
"subject": "Cannot login to my account",
"description": {
"type": "doc",
"content": [...]
},
"status": "open",
"priority": "high",
"type": "bug",
"tags": ["login"],
"requester": {
"id": "uuid",
"name": "John Doe",
"email": "john@example.com"
},
"assignee": {
"id": "uuid",
"name": "Support Agent",
"email": "agent@company.com"
},
"customer": {
"id": "uuid",
"name": "John Doe",
"email": "john@example.com"
},
"conversations": [
{
"id": "uuid",
"content": {...},
"content_text": "Plain text content",
"type": "comment",
"internal": false,
"created_at": "2024-01-15T10:35:00.000Z"
}
],
"ai_summary": "Customer unable to login, receiving error message...",
"detected_language": "en",
"created_at": "2024-01-15T10:30:00.000Z",
"updated_at": "2024-01-15T11:00:00.000Z"
}
}
}
}
Notes:
- Results are cached for 1 minute for performance
- Includes related conversations, requester, assignee, and customer data
Create Ticket
Create a new support ticket.
Procedure: tickets.create
Authentication: Required
Input:
{
subject: string; // Required, 1-500 characters
description: object; // Rich text content (TipTap JSON)
priority?: 'urgent' | 'high' | 'normal' | 'low'; // default: normal
type?: 'question' | 'bug' | 'feature' | 'task'; // default: question
requesterId?: string; // UUID, defaults to current user
assigneeId?: string; // UUID of agent to assign
tags?: string[]; // Array of tags
formId?: string; // Custom form ID (for Zendesk imports)
customFields?: Record<string, any>; // Custom field values
}
Example:
curl -X POST "https://your-domain.com/api/trpc/tickets.create" \
-H "Content-Type: application/json" \
-H "Cookie: your-session-cookie" \
-d '{
"json": {
"subject": "Cannot login to my account",
"description": {
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [
{"type": "text", "text": "I am getting an error when trying to login..."}
]
}
]
},
"priority": "high",
"type": "bug",
"tags": ["login", "urgent"]
}
}'
Response:
{
"result": {
"data": {
"json": {
"id": "uuid",
"number": 1234,
"subject": "Cannot login to my account",
"status": "new",
"priority": "high",
"type": "bug",
"tags": ["login", "urgent"],
"created_at": "2024-01-15T10:30:00.000Z"
}
}
}
}
Side Effects:
- Triggers
ticket.createdautomation event - Sends email notification to assignee (if assigned)
- Auto-assigns to available agent (if auto-assignment is enabled)
- Content is automatically translated to English (if non-English)
- Rate limited to prevent abuse
Update Ticket
Update an existing ticket's properties.
Procedure: tickets.update
Authentication: Required
Input:
{
id: string; // Required, ticket UUID
subject?: string; // 1-500 characters
description?: object; // Rich text content
status?: 'new' | 'open' | 'pending' | 'in_progress' | 'resolved' | 'closed';
priority?: 'urgent' | 'high' | 'normal' | 'low';
assigneeId?: string | null; // UUID or null to unassign
tags?: string[];
formId?: string;
customFields?: Record<string, any>;
ccEmails?: string[]; // Email addresses to CC
}
Example:
curl -X POST "https://your-domain.com/api/trpc/tickets.update" \
-H "Content-Type: application/json" \
-H "Cookie: your-session-cookie" \
-d '{
"json": {
"id": "uuid-here",
"status": "in_progress",
"assigneeId": "agent-uuid",
"priority": "urgent"
}
}'
Response:
{
"result": {
"data": {
"json": {
"id": "uuid",
"number": 1234,
"subject": "Cannot login to my account",
"status": "in_progress",
"priority": "urgent",
"assignee_id": "agent-uuid",
"updated_at": "2024-01-15T11:00:00.000Z"
}
}
}
}
Side Effects:
- Triggers
ticket.updatedautomation event - Triggers
ticket.status_changedif status changed - Triggers
ticket.priority_changedif priority changed - Triggers
ticket.assignedif assignee changed - Sends email notification on status change
- Records change history for undo/redo
Delete Ticket
Soft delete a ticket (marks as deleted but retains data).
Procedure: tickets.delete
Authentication: Required
Input:
{
id: string; // Ticket UUID
}
Example:
curl -X POST "https://your-domain.com/api/trpc/tickets.delete" \
-H "Content-Type: application/json" \
-H "Cookie: your-session-cookie" \
-d '{"json":{"id":"uuid-here"}}'
Response:
{
"result": {
"data": {
"json": {
"success": true
}
}
}
}
AI-Triaged Tickets
Get tickets organized by urgency using AI-based triage logic.
Procedure: tickets.triaged
Authentication: Required
Input: None
Example:
curl -X GET "https://your-domain.com/api/trpc/tickets.triaged" \
-H "Cookie: your-session-cookie"
Response:
{
"result": {
"data": {
"json": {
"needsImmediateAttention": [...],
"needsResponse": [...],
"awaitingCustomer": [...],
"canWait": [...],
"totalOpen": 45
}
}
}
}
Triage Categories:
- needsImmediateAttention: Urgent/high priority tickets that are new or open
- needsResponse: New tickets without first response older than 1 hour
- awaitingCustomer: Tickets with pending status
- canWait: All other open tickets
Undo/Redo
Undo or redo the last update to a ticket.
Undo
Procedure: tickets.undo
Input:
{
id: string; // Ticket UUID
}
Example:
curl -X POST "https://your-domain.com/api/trpc/tickets.undo" \
-H "Content-Type: application/json" \
-H "Cookie: your-session-cookie" \
-d '{"json":{"id":"uuid-here"}}'
Redo
Procedure: tickets.redo
Input:
{
id: string; // Ticket UUID
}
Mark as Spam
Mark a ticket as spam, close it, and optionally block the sender.
Procedure: tickets.markAsSpam
Authentication: Required
Input:
{
id: string; // Ticket UUID
}
Example:
curl -X POST "https://your-domain.com/api/trpc/tickets.markAsSpam" \
-H "Content-Type: application/json" \
-H "Cookie: your-session-cookie" \
-d '{"json":{"id":"uuid-here"}}'
Response:
{
"result": {
"data": {
"json": {
"success": true,
"blockedEmail": "spammer@example.com"
}
}
}
}
Side Effects:
- Adds "SPAM" tag to ticket
- Sets status to "closed"
- Blocks the requester from creating future tickets
- Adds internal note documenting the action
Bulk Operations
Perform operations on multiple tickets at once. Limited to 100 tickets per operation.
Bulk Update
Procedure: tickets.bulkUpdate
Authentication: Required (admin or agent)
Input:
{
ticketIds: string[]; // Array of ticket UUIDs (1-100)
updates: {
status?: 'new' | 'open' | 'pending' | 'in_progress' | 'resolved' | 'closed';
priority?: 'urgent' | 'high' | 'normal' | 'low';
assigneeId?: string | null;
tags?: string[];
};
}
Example:
curl -X POST "https://your-domain.com/api/trpc/tickets.bulkUpdate" \
-H "Content-Type: application/json" \
-H "Cookie: your-session-cookie" \
-d '{
"json": {
"ticketIds": ["uuid1", "uuid2", "uuid3"],
"updates": {
"status": "resolved",
"assigneeId": "agent-uuid"
}
}
}'
Response:
{
"result": {
"data": {
"json": {
"success": true,
"updatedCount": 3
}
}
}
}
Bulk Delete
Procedure: tickets.bulkDelete
Authentication: Required (admin only)
Input:
{
ticketIds: string[]; // Array of ticket UUIDs (1-100)
}
Bulk Assign
Procedure: tickets.bulkAssign
Authentication: Required (admin or agent)
Input:
{
ticketIds: string[]; // Array of ticket UUIDs (1-100)
assigneeId: string | null; // Agent UUID or null to unassign
}
Bulk Mark as Spam
Procedure: tickets.bulkMarkAsSpam
Authentication: Required (admin or agent)
Input:
{
ticketIds: string[]; // Array of ticket UUIDs (1-100)
}
Response:
{
"result": {
"data": {
"json": {
"success": true,
"markedCount": 5,
"blockedEmails": ["spam1@example.com", "spam2@example.com"]
}
}
}
}
Bulk Unmark as Spam
Procedure: tickets.bulkMarkAsNotSpam
Authentication: Required (admin or agent)
Input:
{
ticketIds: string[]; // Array of ticket UUIDs (1-100)
}
Get Next Ticket
Get the next ticket in the queue (useful for auto-advance after replying).
Procedure: tickets.getNextTicket
Authentication: Required
Input:
{
currentTicketId: string; // UUID of current ticket
filters?: {
statuses?: Array<'new' | 'open' | 'pending' | 'in_progress' | 'resolved' | 'closed'>;
priorities?: Array<'urgent' | 'high' | 'normal' | 'low'>;
types?: Array<'question' | 'bug' | 'feature' | 'task'>;
assigneeId?: string | null;
unassigned?: boolean;
tags?: string[];
search?: string;
createdWithin?: '1d' | '7d' | '30d' | '90d';
};
}
Response:
{
"result": {
"data": {
"json": "next-ticket-uuid"
}
}
}
Returns null if no next ticket is available.
Re-translate Ticket
Re-run translation for a ticket (useful if initial translation failed).
Procedure: tickets.retranslate
Authentication: Required
Input:
{
id: string; // Ticket UUID
}
Response:
{
"result": {
"data": {
"json": {
"success": true,
"translated": true,
"detectedLanguage": "es",
"languageName": "Spanish"
}
}
}
}
Rate Limits
| Operation | Limit |
|---|---|
| Create ticket | 20 per minute per user |
| Bulk operations | 10 per minute per user |
Webhooks
The following webhook events are available for tickets:
| Event | Description |
|---|---|
ticket.created | Triggered when a ticket is created |
ticket.updated | Triggered when a ticket is updated |
ticket.status_changed | Triggered when ticket status changes |
ticket.priority_changed | Triggered when ticket priority changes |
ticket.assigned | Triggered when ticket is assigned |
ticket.deleted | Triggered when ticket is deleted |
See Webhooks for configuration details.