Events API

The Events API provides access to the activity log and event sourcing system. Events track all changes to tickets, conversations, users, and other entities.

Event Object

{
  id: string;                    // UUID
  aggregate_type: string;        // Entity type: 'ticket', 'conversation', 'user', 'organization'
  aggregate_id: string;          // UUID of the entity
  event_type: string;            // Type of event (e.g., 'created', 'updated', 'assigned')
  event_data: object;            // Event-specific data
  actor_id?: string;             // UUID of user who triggered the event
  actor?: {                      // Actor details (when included)
    name: string;
    email: string;
    avatar_url?: string;
  };
  created_at: string;            // ISO timestamp
}

List Events

Retrieve events for a specific entity with cursor-based pagination.

Procedure: events.list

Authentication: Required

Input:

{
  aggregateType: string;   // 'ticket' | 'conversation' | 'user' | 'organization'
  aggregateId: string;     // UUID of the entity
  limit?: number;          // 1-100, default: 50
  cursor?: string;         // Pagination cursor (event ID)
}

Example:

curl -X GET "https://your-domain.com/api/trpc/events.list?input=%7B%22aggregateType%22:%22ticket%22,%22aggregateId%22:%22ticket-uuid%22,%22limit%22:20%7D" \
  -H "Cookie: your-session-cookie"

Response:

{
  "result": {
    "data": {
      "json": {
        "events": [
          {
            "id": "event-uuid",
            "aggregate_type": "ticket",
            "aggregate_id": "ticket-uuid",
            "event_type": "assigned",
            "event_data": {
              "assignee_id": "user-uuid",
              "assignee_name": "John Smith"
            },
            "actor_id": "actor-uuid",
            "actor": {
              "name": "Admin User",
              "email": "admin@example.com"
            },
            "created_at": "2024-01-15T10:30:00.000Z"
          },
          {
            "id": "event-uuid-2",
            "aggregate_type": "ticket",
            "aggregate_id": "ticket-uuid",
            "event_type": "created",
            "event_data": {
              "subject": "Help with order",
              "priority": "normal"
            },
            "actor_id": "customer-uuid",
            "created_at": "2024-01-15T10:00:00.000Z"
          }
        ],
        "nextCursor": "event-uuid-2",
        "hasMore": true
      }
    }
  }
}

Get Event

Retrieve a single event by ID.

Procedure: events.get

Authentication: Required

Input:

{
  id: string;  // Event UUID
}

Example:

curl -X GET "https://your-domain.com/api/trpc/events.get?input=%7B%22id%22:%22event-uuid%22%7D" \
  -H "Cookie: your-session-cookie"

Response:

{
  "result": {
    "data": {
      "json": {
        "id": "event-uuid",
        "aggregate_type": "ticket",
        "aggregate_id": "ticket-uuid",
        "event_type": "status_changed",
        "event_data": {
          "old_status": "open",
          "new_status": "resolved"
        },
        "actor_id": "user-uuid",
        "actor": {
          "name": "John Smith",
          "email": "john@example.com"
        },
        "created_at": "2024-01-15T10:30:00.000Z"
      }
    }
  }
}

List Events for Ticket

Retrieve combined events from both the ticket and its conversations, useful for displaying a complete activity timeline.

Procedure: events.listForTicket

Authentication: Required

Input:

{
  ticketId: string;    // Ticket UUID
  limit?: number;      // 1-100, default: 50
  cursor?: string;     // Pagination cursor
}

Example:

curl -X GET "https://your-domain.com/api/trpc/events.listForTicket?input=%7B%22ticketId%22:%22ticket-uuid%22%7D" \
  -H "Cookie: your-session-cookie"

Response:

{
  "result": {
    "data": {
      "json": {
        "events": [
          {
            "id": "event-uuid",
            "aggregate_type": "conversation",
            "aggregate_id": "conversation-uuid",
            "event_type": "created",
            "event_data": {
              "content_preview": "Thank you for contacting..."
            },
            "actor_id": "agent-uuid",
            "created_at": "2024-01-15T11:00:00.000Z"
          },
          {
            "id": "event-uuid-2",
            "aggregate_type": "ticket",
            "aggregate_id": "ticket-uuid",
            "event_type": "assigned",
            "event_data": {
              "assignee_id": "agent-uuid"
            },
            "actor_id": "admin-uuid",
            "created_at": "2024-01-15T10:45:00.000Z"
          },
          {
            "id": "event-uuid-3",
            "aggregate_type": "ticket",
            "aggregate_id": "ticket-uuid",
            "event_type": "created",
            "event_data": {
              "subject": "Help with my order"
            },
            "actor_id": "customer-uuid",
            "created_at": "2024-01-15T10:30:00.000Z"
          }
        ],
        "nextCursor": "event-uuid-3",
        "hasMore": false
      }
    }
  }
}

Event Types

Ticket Events

Event TypeDescriptionEvent Data
createdTicket was createdsubject, priority, channel
updatedTicket fields changedChanged fields and values
assignedTicket assigned to agentassignee_id, assignee_name
unassignedAssignment removedPrevious assignee_id
status_changedStatus updatedold_status, new_status
priority_changedPriority updatedold_priority, new_priority
taggedTags addedtags array
mergedTicket mergedmerged_into_id
deletedTicket deleted-

Conversation Events

Event TypeDescriptionEvent Data
createdReply/comment addedcontent_preview, internal
updatedContent editedold_content, new_content
deletedMessage deleted-

User Events

Event TypeDescriptionEvent Data
createdUser registeredemail, role
role_changedRole updatedold_role, new_role
deactivatedUser deactivated-

Use Cases

Activity Timeline

// Fetch ticket activity for timeline display
const { events, hasMore, nextCursor } = await trpc.events.listForTicket.query({
  ticketId: 'ticket-uuid',
  limit: 20,
})

// Display events chronologically
events.forEach(event => {
  console.log(`${event.created_at}: ${event.event_type} by ${event.actor?.name}`)
})

Audit Log

// Fetch organization-wide events for audit purposes
const { events } = await trpc.events.list.query({
  aggregateType: 'organization',
  aggregateId: orgId,
  limit: 100,
})

Error Codes

CodeDescription
NOT_FOUNDEvent not found
FORBIDDENUser doesn't have access to this entity
BAD_REQUESTInvalid aggregate type