/v1/admin/ticketsEvery support ticket of the firm's traders. The same list as Tickets on the website, with the same search and the same filters. Where the website reads a value it does not know as the default, because its addresses get bookmarked, this refuses it: a client that thinks it filtered and got everything shows the wrong list.
One ticket, with what it takes to answer it, is a ticket. The counters above the list are the summary, and the agents, teams and tags to filter on are the options.
Needs a firm. Our own staff name one with the Propper-Workspace header.
Request
| Parameter | Description |
|---|---|
status | waiting (for the team), open (not ended), ai (the assistant is answering), trader (waiting on the trader), ended (resolved or closed), or all (the default) |
assignee | anyone (the default), me (yours and your teams'), none (no agent and no team), or the id of an agent |
team | any (the default), none, or the id of a team |
priority | urgent, high, normal, low, or all (the default) |
tag | Only tickets with this tag, or all (the default). A tag that no longer exists finds nothing |
q | Search, up to 100 characters. See below |
sort | queue (the default), -last_message_at latest activity first, -created_at newest first, created_at oldest first, or -priority most urgent first |
limit | How many, see pagination |
starting_after | The next_cursor of the page before. A cursor only works with the sort it was handed out with |
queue is the order the website opens on. First what waits for the team, the
most urgent on top and then whoever has waited longest since the trader last
wrote. Then what the assistant is answering, then what waits on a trader, then
everything that ended, each with the latest activity first.
q takes what a trader or a colleague has in hand. A whole ticket id or
trader id finds exactly that one. Anything else is split into words, and every
word has to match somewhere: the subject, the trader's name or email address,
or any message of the conversation, the team's internal notes included. A word
of six letters and digits also finds the ticket with that number. A word
starting with # looks only at the number, so #Q45CA7 does not also find a
message holding those letters.
curl "https://api.proppertrading.com/v1/admin/tickets?status=waiting&limit=2" \
-H "Authorization: Bearer ptat_9f2c1a44_3b8e7d2f5c9a1b4e6d8f0a2c4e6b8d1f" \
-H "Propper-Workspace: acme"
Response
{
"data": [
{
"object": "ticket",
"id": "tkt_tattwr6c8dunw3f9",
"number": "#UNW3F9",
"subject": "Spread on gold looked wrong at the open",
"status": "awaiting_admin",
"priority": "high",
"ai_enabled": false,
"ai_blocked": false,
"unread": 1,
"last_from": "trader",
"last_message_at": "2026-10-07T05:00:26+00:00",
"created_at": "2026-10-07T05:00:26+00:00",
"closed_at": null,
"trader": {
"id": "usr_5t9et623ep5cygcm",
"name": "Ines Rossi",
"email": "[email protected]",
"avatar_url": null,
"deleted": false
},
"assignee": null,
"team": null,
"tags": [],
"action_url": "/admin/tickets/tkt_tattwr6c8dunw3f9"
},
{
"object": "ticket",
"id": "tkt_ebcgbewt26spv54q",
"number": "#SPV54Q",
"subject": "Payout still pending after five days",
"status": "awaiting_admin",
"priority": "high",
"ai_enabled": false,
"ai_blocked": false,
"unread": 1,
"last_from": "trader",
"last_message_at": "2026-10-08T19:23:11+00:00",
"created_at": "2026-10-08T19:23:11+00:00",
"closed_at": null,
"trader": {
"id": "usr_c3jpdarm9q2wndhs",
"name": "Julia Nilsson",
"email": "[email protected]",
"avatar_url": null,
"deleted": false
},
"assignee": null,
"team": null,
"tags": [],
"action_url": "/admin/tickets/tkt_ebcgbewt26spv54q"
}
],
"meta": {
"request_id": "req_01m50va7n21xvavmhds6n2p3a7",
"has_more": true,
"next_cursor": "eyJzIjoicXVldWUiLCJ2IjpbMCwtMiwiMTc5MTQ4NzM5MS4wMDAwMDAiXSwiaWQiOiJ0a3RfZWJjZ2Jld3QyNnNwdjU0cSJ9"
}
}
| Field | Description |
|---|---|
number | What people read out: the last six characters of the id |
status | open (the assistant is answering), awaiting_admin (waits for the team), awaiting_trader, resolved or closed. The last two are final |
priority | low, normal, high or urgent |
ai_enabled | The assistant answers this ticket now. It goes off for good at the team's first answer |
ai_blocked | The trader may not call the assistant back in. See block the assistant |
unread | Messages from the trader and the assistant that the team has not read |
last_from | Who wrote the last message the trader can see: trader, admin, ai or system. Says whose turn it is. Null without one |
last_message_at | The last message the trader can see. A note does not move it |
closed_at | When it was resolved or closed. Null while it is open |
trader | Who asked. deleted is true for a trader who deleted their account, whose ticket stays in the firm's history |
assignee | The agent who holds it, with id, name and avatar_url. Null for nobody |
team | The team it was given to, with id and name. Null for none |
tags | The team's own labels, each with id, name and color |
action_url | Where the website shows the ticket, a path inside the web application |
Errors
| Status | Code | Meaning |
|---|---|---|
| 400 | workspace_required | Asked by our own staff without naming a firm |
| 400 | validation_failed | status, assignee, team, priority or tag is not one of its values or an id of the right kind, or q is not text |
| 400 | invalid_sort | sort is not one of the five orders |
| 400 | invalid_limit | limit is not a positive integer |
| 400 | invalid_cursor | starting_after is not a cursor handed out for this sort |
| 401 | invalid_token | Not a token, or the secret does not match |
| 401 | revoked_token | Signed out here or from another device |
| 401 | expired_token | Ninety days without use, or a set expiry passed |
| 403 | admin_access_required | This account no longer helps run the environment |
| 403 | insufficient_scope | This device does not hold admin:read |
| 403 | workspace_not_permitted | The Propper-Workspace header names an environment this account cannot act in |
| 403 | forbidden | Without view_tickets |