Saved Views API

The Saved Views API manages saved ticket filter configurations, allowing users to create, share, and quickly access customized ticket lists.

Saved View Object

{
  id: string;                    // UUID
  organization_id: string;       // UUID of the organization
  user_id: string;               // UUID of the creator
  name: string;                  // View name
  description?: string;          // Optional description
  filters: TicketFilters;        // Filter configuration
  visibility: 'personal' | 'shared';  // Who can see this view
  is_pinned: boolean;            // Pinned to sidebar
  position: number;              // Sort order
  color?: string;                // UI color code
  icon?: string;                 // UI icon name
  created_at: string;            // ISO timestamp
  updated_at: string;            // ISO timestamp
}

Ticket Filters Schema

{
  // Status and classification
  status?: ('new' | 'open' | 'pending' | 'in_progress' | 'resolved' | 'closed')[];
  priority?: ('urgent' | 'high' | 'normal' | 'low')[];
  type?: ('question' | 'bug' | 'feature' | 'task')[];

  // Assignment
  assigneeId?: string | null;    // Specific assignee UUID
  unassigned?: boolean;          // Only unassigned tickets
  groupId?: string;              // Agent group UUID

  // Content
  tags?: string[];               // Required tags
  search?: string;               // Text search
  channel?: 'email' | 'web' | 'api' | 'chat' | 'phone' | 'shopify' | 'slack';

  // Absolute date filters
  createdAfter?: string;         // ISO datetime
  createdBefore?: string;        // ISO datetime
  updatedAfter?: string;         // ISO datetime
  updatedBefore?: string;        // ISO datetime

  // Relative date filters
  createdWithin?: '1d' | '7d' | '30d' | '90d';
  updatedWithin?: '1d' | '7d' | '30d' | '90d';

  // Special filters
  hasAttachments?: boolean;      // Has file attachments
  isOverdue?: boolean;           // Past SLA deadline
}

List Saved Views

Retrieve all saved views (personal views + shared views from organization).

Procedure: savedViews.list

Authentication: Required

Input: None

Example:

curl -X GET "https://your-domain.com/api/trpc/savedViews.list" \
  -H "Cookie: your-session-cookie"

Response:

{
  "result": {
    "data": {
      "json": [
        {
          "id": "uuid",
          "name": "My Open Tickets",
          "description": "Tickets assigned to me that are open",
          "filters": {
            "status": ["new", "open"],
            "assigneeId": "user-uuid"
          },
          "visibility": "personal",
          "is_pinned": true,
          "position": 0,
          "color": "blue",
          "icon": "inbox",
          "isOwner": true,
          "creator": {
            "name": "John Smith",
            "email": "john@example.com"
          },
          "created_at": "2024-01-01T00:00:00.000Z",
          "updated_at": "2024-01-15T10:00:00.000Z"
        },
        {
          "id": "uuid-2",
          "name": "Urgent Tickets",
          "description": "All urgent priority tickets",
          "filters": {
            "priority": ["urgent"]
          },
          "visibility": "shared",
          "is_pinned": false,
          "position": 1,
          "isOwner": false,
          "creator": {
            "name": "Jane Doe",
            "email": "jane@example.com"
          },
          "created_at": "2024-01-05T00:00:00.000Z",
          "updated_at": "2024-01-10T10:00:00.000Z"
        }
      ]
    }
  }
}

Notes:

  • Results are sorted: pinned first, then by position, then by created date
  • isOwner indicates if the current user created the view

Get Saved View

Retrieve a single saved view by ID.

Procedure: savedViews.get

Authentication: Required

Input:

{
  id: string;  // View UUID
}

Example:

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

Response:

{
  "result": {
    "data": {
      "json": {
        "id": "uuid",
        "name": "My Open Tickets",
        "filters": {
          "status": ["new", "open"],
          "assigneeId": "user-uuid"
        },
        "visibility": "personal",
        "is_pinned": true,
        "isOwner": true
      }
    }
  }
}

Create Saved View

Create a new saved view.

Procedure: savedViews.create

Authentication: Required

Input:

{
  name: string;                           // 1-100 characters
  description?: string;                   // Max 500 characters
  filters: TicketFilters;                 // Filter configuration
  visibility?: 'personal' | 'shared';     // Default: 'personal'
  color?: string;                         // UI color (max 20 chars)
  icon?: string;                          // UI icon (max 50 chars)
}

Example:

curl -X POST "https://your-domain.com/api/trpc/savedViews.create" \
  -H "Content-Type: application/json" \
  -H "Cookie: your-session-cookie" \
  -d '{
    "json": {
      "name": "High Priority Bugs",
      "description": "All high priority bug tickets",
      "filters": {
        "type": ["bug"],
        "priority": ["high", "urgent"]
      },
      "visibility": "shared",
      "color": "red",
      "icon": "bug"
    }
  }'

Response:

{
  "result": {
    "data": {
      "json": {
        "id": "new-uuid",
        "name": "High Priority Bugs",
        "description": "All high priority bug tickets",
        "filters": {
          "type": ["bug"],
          "priority": ["high", "urgent"]
        },
        "visibility": "shared",
        "is_pinned": false,
        "position": 5,
        "color": "red",
        "icon": "bug",
        "created_at": "2024-01-15T10:30:00.000Z",
        "updated_at": "2024-01-15T10:30:00.000Z"
      }
    }
  }
}

Update Saved View

Update an existing saved view. Only the creator can update.

Procedure: savedViews.update

Authentication: Required

Input:

{
  id: string;                             // View UUID (required)
  name?: string;                          // 1-100 characters
  description?: string;                   // Max 500 characters
  filters?: TicketFilters;                // Filter configuration
  visibility?: 'personal' | 'shared';
  isPinned?: boolean;
  color?: string;
  icon?: string;
}

Example:

curl -X POST "https://your-domain.com/api/trpc/savedViews.update" \
  -H "Content-Type: application/json" \
  -H "Cookie: your-session-cookie" \
  -d '{
    "json": {
      "id": "view-uuid",
      "name": "Critical Bugs",
      "filters": {
        "type": ["bug"],
        "priority": ["urgent"]
      }
    }
  }'

Response:

{
  "result": {
    "data": {
      "json": {
        "id": "view-uuid",
        "name": "Critical Bugs",
        "filters": {
          "type": ["bug"],
          "priority": ["urgent"]
        },
        "updated_at": "2024-01-15T11:00:00.000Z"
      }
    }
  }
}

Delete Saved View

Delete a saved view. Only the creator can delete.

Procedure: savedViews.delete

Authentication: Required

Input:

{
  id: string;  // View UUID
}

Example:

curl -X POST "https://your-domain.com/api/trpc/savedViews.delete" \
  -H "Content-Type: application/json" \
  -H "Cookie: your-session-cookie" \
  -d '{"json":{"id":"view-uuid"}}'

Response:

{
  "result": {
    "data": {
      "json": {
        "success": true
      }
    }
  }
}

Toggle Pin

Toggle the pinned status of a saved view. Only the creator can modify.

Procedure: savedViews.togglePin

Authentication: Required

Input:

{
  id: string;  // View UUID
}

Example:

curl -X POST "https://your-domain.com/api/trpc/savedViews.togglePin" \
  -H "Content-Type: application/json" \
  -H "Cookie: your-session-cookie" \
  -d '{"json":{"id":"view-uuid"}}'

Response:

{
  "result": {
    "data": {
      "json": {
        "id": "view-uuid",
        "is_pinned": true,
        "updated_at": "2024-01-15T11:00:00.000Z"
      }
    }
  }
}

Reorder Views

Update the display order of saved views.

Procedure: savedViews.reorder

Authentication: Required

Input:

{
  viewIds: string[];  // Ordered array of view UUIDs
}

Example:

curl -X POST "https://your-domain.com/api/trpc/savedViews.reorder" \
  -H "Content-Type: application/json" \
  -H "Cookie: your-session-cookie" \
  -d '{
    "json": {
      "viewIds": ["uuid-1", "uuid-2", "uuid-3"]
    }
  }'

Response:

{
  "result": {
    "data": {
      "json": {
        "success": true
      }
    }
  }
}

Use Cases

Sidebar Navigation

// Load views for sidebar
const views = await trpc.savedViews.list.query()

// Separate pinned views for quick access
const pinnedViews = views.filter(v => v.is_pinned)
const otherViews = views.filter(v => !v.is_pinned)

Creating a Personal View

// Save current filter as a view
await trpc.savedViews.create.mutate({
  name: 'My Active Tickets',
  filters: {
    assigneeId: currentUser.id,
    status: ['new', 'open', 'in_progress'],
  },
  visibility: 'personal',
})

Team Shared View

// Create a view visible to the whole team
await trpc.savedViews.create.mutate({
  name: 'Unassigned Urgent',
  description: 'Urgent tickets needing assignment',
  filters: {
    priority: ['urgent'],
    unassigned: true,
  },
  visibility: 'shared',
  color: 'red',
})

Applying Filters

// Load view and apply filters to ticket list
const view = await trpc.savedViews.get.query({ id: viewId })

const tickets = await trpc.tickets.list.query({
  filters: view.filters,
})

Error Codes

CodeDescription
FORBIDDENCannot modify another user's view
NOT_FOUNDView not found or not accessible
INTERNAL_SERVER_ERRORDatabase error