agentlyleads docs
Cases API

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_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Query parameters

ParameterDescription
statusNEW, OPEN, PENDING, RESOLVED or CLOSED
severityLOW, MEDIUM, HIGH or URGENT
opentrue for cases still being worked, false for resolved and closed ones
companyIdOnly cases on this company
contactIdOnly cases raised by this contact
assigneeIdOnly cases held by this workspace user
updatedSinceISO 8601 datetime. Only cases updated at or after this moment (useful for incremental sync)
limitPage size, 1–1000 (default 100)
cursorThe 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_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

open=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_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Response — 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.

On this page