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

StatusDescription
newNewly created ticket, not yet viewed
openTicket is being worked on
pendingWaiting for customer response
in_progressActively being resolved
resolvedIssue has been resolved
closedTicket is closed

Priority Values

PriorityDescription
urgentRequires immediate attention
highHigh priority
normalStandard priority (default)
lowLow priority

Type Values

TypeDescription
questionGeneral inquiry (default)
bugBug report
featureFeature request
taskInternal 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.created automation 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.updated automation event
  • Triggers ticket.status_changed if status changed
  • Triggers ticket.priority_changed if priority changed
  • Triggers ticket.assigned if 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

OperationLimit
Create ticket20 per minute per user
Bulk operations10 per minute per user

Webhooks

The following webhook events are available for tickets:

EventDescription
ticket.createdTriggered when a ticket is created
ticket.updatedTriggered when a ticket is updated
ticket.status_changedTriggered when ticket status changes
ticket.priority_changedTriggered when ticket priority changes
ticket.assignedTriggered when ticket is assigned
ticket.deletedTriggered when ticket is deleted

See Webhooks for configuration details.