GET /api/v1/cases
Returns the workspace's support cases, newest-created first. Requires the read:cases scope (or * for full access).
Request
GET /api/v1/cases HTTP/1.1
Host: agentlyleads.com
Authorization: Bearer alk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxQuery parameters
| Parameter | Description |
|---|---|
status | NEW, OPEN, PENDING, RESOLVED or CLOSED |
severity | LOW, MEDIUM, HIGH or URGENT |
open | true for cases still being worked, false for resolved and closed ones |
companyId | Only cases on this company |
contactId | Only cases raised by this contact |
assigneeId | Only cases held by this workspace user |
updatedSince | ISO 8601 datetime. Only cases updated at or after this moment (useful for incremental sync) |
limit | Page size, 1–1000 (default 100) |
cursor | The nextCursor value from the previous page |
All parameters are optional and can be combined. Filters that match nothing return an empty list, not a 404.
The live queue, worst first in your own code:
GET /api/v1/cases?open=true&severity=URGENT HTTP/1.1
Authorization: Bearer alk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxopen=true means NEW, OPEN or PENDING. It is a shorthand for the three statuses that mean somebody still owes the customer something, so a dashboard does not have to hard-code that list and drift from it later.
Everything ever raised by one account:
GET /api/v1/cases?companyId=cmq2comp0alk34567890 HTTP/1.1
Authorization: Bearer alk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxResponse — 200
{
"cases": [
{
"id": "cmq2case0alk34567890",
"number": 31,
"subject": "Pallet arrived damaged",
"description": "Two of six bags split in transit.",
"status": "OPEN",
"severity": "HIGH",
"source": "EMAIL",
"open": true,
"ageMins": 4320,
"overdue": true,
"company": { "id": "cmq2comp0alk34567890", "name": "Acme Corp" },
"contact": { "id": "cmq2cont0alk34567891", "name": "Jane Buyer" },
"assignee": { "id": "cmq9user0alk34567890", "name": "Kevin Rep" },
"threadKey": "AAMkAGI2...",
"firstResponseAt": "2026-09-04T08:12:00.000Z",
"resolvedAt": null,
"createdAt": "2026-09-04T07:55:00.000Z",
"updatedAt": "2026-09-06T14:02:00.000Z"
}
],
"nextCursor": null
}open, ageMins and overdue are worked out at the moment you ask, so two requests a day apart report two different ages for the same unresolved case. See the Case object for why they are not columns.
Pagination
Responses are cursor-paginated. When more rows exist beyond the requested limit, nextCursor holds the ID of the last returned record. Pass it back as cursor to fetch the next page. On the last page, nextCursor is null.
Writing cases
There is no write endpoint. Cases are opened and moved in the app or through the AI connector, where create_case can open one straight from a received email. The status transitions carry the resolution clock with them (first response is stamped when a case leaves NEW, and the resolution is stamped once and kept when the case is later filed), and raw status writes from an integration would quietly break both.