Tickets

.md

The firm's support queue, searched, filtered and sorted the way the website's Tickets screen does it.

Scopesadmin:read
Permissionview_tickets
GET/v1/admin/tickets

Every 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

ParameterDescription
statuswaiting (for the team), open (not ended), ai (the assistant is answering), trader (waiting on the trader), ended (resolved or closed), or all (the default)
assigneeanyone (the default), me (yours and your teams'), none (no agent and no team), or the id of an agent
teamany (the default), none, or the id of a team
priorityurgent, high, normal, low, or all (the default)
tagOnly tickets with this tag, or all (the default). A tag that no longer exists finds nothing
qSearch, up to 100 characters. See below
sortqueue (the default), -last_message_at latest activity first, -created_at newest first, created_at oldest first, or -priority most urgent first
limitHow many, see pagination
starting_afterThe 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"
    }
}
FieldDescription
numberWhat people read out: the last six characters of the id
statusopen (the assistant is answering), awaiting_admin (waits for the team), awaiting_trader, resolved or closed. The last two are final
prioritylow, normal, high or urgent
ai_enabledThe assistant answers this ticket now. It goes off for good at the team's first answer
ai_blockedThe trader may not call the assistant back in. See block the assistant
unreadMessages from the trader and the assistant that the team has not read
last_fromWho wrote the last message the trader can see: trader, admin, ai or system. Says whose turn it is. Null without one
last_message_atThe last message the trader can see. A note does not move it
closed_atWhen it was resolved or closed. Null while it is open
traderWho asked. deleted is true for a trader who deleted their account, whose ticket stays in the firm's history
assigneeThe agent who holds it, with id, name and avatar_url. Null for nobody
teamThe team it was given to, with id and name. Null for none
tagsThe team's own labels, each with id, name and color
action_urlWhere the website shows the ticket, a path inside the web application

Errors

StatusCodeMeaning
400workspace_requiredAsked by our own staff without naming a firm
400validation_failedstatus, assignee, team, priority or tag is not one of its values or an id of the right kind, or q is not text
400invalid_sortsort is not one of the five orders
400invalid_limitlimit is not a positive integer
400invalid_cursorstarting_after is not a cursor handed out for this sort
401invalid_tokenNot a token, or the secret does not match
401revoked_tokenSigned out here or from another device
401expired_tokenNinety days without use, or a set expiry passed
403admin_access_requiredThis account no longer helps run the environment
403insufficient_scopeThis device does not hold admin:read
403workspace_not_permittedThe Propper-Workspace header names an environment this account cannot act in
403forbiddenWithout view_tickets