List Cases
Page through your company's cases with GET /v3/api/cases — filters, cursor pagination and the response shape.
Returns your company's cases, newest first, one page at a time.
GET https://api.nextsign.dk/v3/api/casesAuthenticated with an API key — see Authorization.
Quickstart
curl "https://api.nextsign.dk/v3/api/cases?limit=25&state=open" \
-H "Authorization: Bearer $NEXTSIGN_API_KEY"const params = new URLSearchParams({ limit: '25', state: 'open' });
const response = await fetch(`https://api.nextsign.dk/v3/api/cases?${params}`, {
headers: { Authorization: `Bearer ${process.env.NEXTSIGN_API_KEY}` },
});
const { cases, nextCursor, hasMore } = await response.json();import os, requests
response = requests.get(
"https://api.nextsign.dk/v3/api/cases",
headers={"Authorization": f"Bearer {os.environ['NEXTSIGN_API_KEY']}"},
params={"limit": 25, "state": "open"},
)
page = response.json()Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 25 | Cases per page, 1–100 |
cursor | string | — | Where to continue from. Use nextCursor from the previous page |
state | string | all | One of draft, open, completed, denied, cancelled |
referenceId | string | all | Exact match on your own identifier. Not a search |
folder | string | all | Exact folder name |
createdAfter | string | — | ISO 8601. Cases created at or after this moment |
createdBefore | string | — | ISO 8601. Cases created at or before this moment |
includeDeleted | boolean | false | Include cases moved to the bin |
publicUrls | boolean | false | Return downloadable document links. See Document URLs |
Anything else is rejected. A misspelled parameter returns 400 validation-failed naming it, rather than silently returning unfiltered results — a filter that is quietly ignored is the one mistake you cannot see in the response.
{
"error": "validation-failed",
"details": [{ "field": "page", "message": "unknown field" }]
}Dates must be ISO 8601 — 2026-01-31 or 2026-01-31T09:00:00Z. A bare year like 2026 is rejected rather than quietly read as January 1st.
Pagination
Paging is by cursor, not page number. Each response carries a nextCursor; pass it back to get the next page, and stop when hasMore is false.
let cursor = null;
const all = [];
do {
const params = new URLSearchParams({ limit: '100' });
if (cursor) params.set('cursor', cursor);
const response = await fetch(`https://api.nextsign.dk/v3/api/cases?${params}`, {
headers: { Authorization: `Bearer ${process.env.NEXTSIGN_API_KEY}` },
});
const page = await response.json();
all.push(...page.cases);
cursor = page.nextCursor;
} while (cursor);Two things follow from this that page numbers would not give you:
- New cases do not shift your pages. A cursor marks a position in the results, not an offset, so a case created while you are paging cannot push a row onto a page you have already read — with
?page=it would, and you would see the same case twice. - The last page costs what the first one did. Every page is a bounded lookup rather than a count-and-skip, so paging deep into a long history does not get slower.
Treat the cursor as opaque. It is a position marker whose format is ours to change — do not parse it, build one, or store one long-term. A cursor you did not receive from us returns 400 validation-failed on the cursor field.
There is no total. Counting every case in a company is the one query that would make deep paging expensive again, so we do not run it on your behalf. If you need a count, page with limit=100 and add up what you receive.
Document URLs
By default documents[].url is the document's stored address. It identifies the file and is stable, but it is protected — fetching it without credentials returns 403.
Pass ?publicUrls=true to get downloadable links instead:
curl "https://api.nextsign.dk/v3/api/cases?publicUrls=true" \
-H "Authorization: Bearer $NEXTSIGN_API_KEY"{ "url": "https://nextsign-de.fsn1.your-objectstorage.com/65ab/contract.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=3600&X-Amz-Signature=fa2ca5b25…" }These expire after an hour, which is why they are opt-in: minting one for every document on every page — when most callers are checking who has signed — produces links that are stale before anyone clicks them. Ask for them on the page where you intend to download.
Documents you supplied as a url are returned exactly as you gave them, with or without this parameter. We store those by reference and never re-host them — which is also why their type is null, since we never fetched the bytes to inspect.
Response
{
"cases": [
{
"id": "65ab12cd34ef56ab78cd90b0",
"referenceId": "Jrn. 2342-23",
"title": "Lejeaftale",
"state": "open",
"language": "da",
"createdAt": "2026-07-27T14:48:36.356Z",
"expiresAt": "2026-08-10T14:48:36.356Z",
"folder": { "id": "65ab12cd34ef56ab78cd90a2", "name": "Default" },
"sender": {
"id": "65ab12cd34ef56ab78cd90ef",
"name": "Anna Beck",
"email": "anna@example.com"
},
"activeGroup": 0,
"recipients": [
{
"id": "65ab12cd34ef56ab78cd91a1",
"uid": "4t5ZQbtB",
"name": "Andreas Lauridsen",
"email": "al@example.com",
"phone": "",
"position": "",
"group": 0,
"type": "email",
"signing": true,
"status": "signed",
"needsCpr": false,
"signingSchema": ""
}
],
"documents": [
{
"id": "65ab12cd34ef56ab78cd92c3",
"name": "contract.pdf",
"type": "application/pdf",
"url": "https://nextsign-de.fsn1.your-objectstorage.com/65ab/contract.pdf",
"signObligated": true,
"documentMustBeRead": false,
"signatories": []
}
],
"notices": []
}
],
"nextCursor": "MTc4NTI0NDYwNjU5OS42NWFiMTJjZDM0ZWY1NmFiNzhjZDkwYjA",
"hasMore": true
}Each entry is the same case object Create a Case returns, so anything you already parse from a creation response works here unchanged.
| Field | Description |
|---|---|
cases | This page of cases, newest first |
nextCursor | Pass as ?cursor= for the next page. null on the last page |
hasMore | Whether another page exists. Equivalent to nextCursor !== null |
Two fields from the creation response are absent here, both because they describe an event rather than the case:
deliveryreports the outcome of sending, which happened once, at creation.recipients[].signingUrlis not returned by the list. Signing links contain the credential that authenticates a signing session, and a list is what integrations put on a schedule — one such request should not be able to collect every open case's signing link. Fetch the case with Retrieve a Case when you need them.
notices is present and always empty. It records what we filled in for you while creating a case; nothing is being filled in here.
What you see
An API key belongs to a company, and this endpoint returns that company's cases — all of them, regardless of which colleague created each one or which folder it sits in. Folder permissions govern what a person sees when they log in; they do not narrow what a key can read.
Errors
error | Status | Meaning |
|---|---|---|
validation-failed | 400 | A query parameter is invalid or unrecognised. See details |
Reading never changes anything, so every request here is safe to retry. Full detail in Errors.