Conventions
Pagination, filtering and sorting
Every list endpoint pages with cursors, filters on the fields its reference documents, sorts by one field and searches with q. The rules are the same everywhere.
Lists return up to limit records — 50 unless you ask for between 1 and 100 — and a meta object. When meta.has_more is true, pass meta.next_cursor back as cursor to get the next page. On the last page next_cursor is null.
{
"data": [
{
"id": "8f2d6c1a-4b7e-4f0a-9c3d-2e1b5a6f7c80",
"title": "Northwind Analytics — annual plan",
"value": 24000,
"currency": "EUR",
"status": "in_progress",
"pipeline": {
"id": "9d4b2f7a-3c8e-4b1d-a6f2-5e7c9b0d1a34",
"name": "New business"
},
"stage": {
"id": "5b1e9f3c-2a7d-4c6e-8f1b-3d9a0c4e7b21",
"name": "Proposal",
"type": "open"
},
"pipeline_id": "9d4b2f7a-3c8e-4b1d-a6f2-5e7c9b0d1a34",
"stage_id": "5b1e9f3c-2a7d-4c6e-8f1b-3d9a0c4e7b21",
"probability": 60,
"expected_close_date": "2026-11-27",
"closed_at": null,
"forecast_category": "best_case",
"loss_reason": null,
"competitor": null,
"contact_id": "3f1c9a7e-2b4d-4c8e-9f60-1a2b3c4d5e6f",
"company_id": "2b7e4c9a-5d1f-4a8e-9b3c-7f0a1d2e4c56",
"owner_id": "0c4f8e2a-7b3d-4a1f-9e6c-5d2b8a1f3e47",
"custom_fields": {
"seats": 40
},
"created_at": "2026-10-01T10:12:00Z",
"updated_at": "2026-10-09T15:40:22Z"
}
],
"meta": {
"limit": 1,
"has_more": true,
"next_cursor": "eyJpZCI6IjNmMWM5YTdlIiwiY3JlYXRlZF9hdCI6IjIwMjYtMDktMTRUMDk6MzA6MDBaIn0"
}
}- limitinteger
The page size used.
- has_moreboolean
Whether more records follow.
Pass as
cursorfor the next page;nullon the last page.- totalinteger
The number of matching records, when the endpoint can count them cheaply. It may be absent; never use it to decide whether to fetch more.
Cursors are opaque: do not build or change them. A cursor carries the sort of the request that made it, so keep sort, order, filters and q the same while you page.
async function* allDeals(params = {}) {
let cursor;
do {
const query = new URLSearchParams({ ...params, limit: '100', ...(cursor ? { cursor } : {}) });
const response = await fetch(`https://acme.nextora.co/api/v1/deals?${query}`, {
headers: { Authorization: `Bearer ${process.env.NEXTORA_API_KEY}` },
});
const { data, meta } = await response.json();
yield* data;
cursor = meta.next_cursor;
} while (cursor);
}
for await (const deal of allDeals({ status: 'in_progress' })) {
console.log(deal.title, deal.value);
}Older integrations may page with offset instead of cursor; it is still accepted and returns the same records. New code should use cursors.
Filter with a query parameter per field: ?status=in_progress matches exactly. Add an operator in brackets for anything else: ?value[gte]=10000. Filters combine with AND.
| Operator | Matches | Example |
|---|---|---|
eq | Equal — the same as no operator. | status[eq]=won |
neq | Not equal. | status[neq]=lost |
gt, gte | Greater than; greater than or equal. | value[gte]=10000 |
lt, lte | Less than; less than or equal. | expected_close_date[lte]=2026-12-31 |
like | Contains the text, ignoring case. | name[like]=north |
in | Any of a comma-separated list. | status[in]=won,lost |
Each list endpoint documents the fields it filters on, under Filters. Any other field — or a value of the wrong type — is a 400 validation_failed that names the parameter, never a silently unfiltered list.
curl -G https://acme.nextora.co/api/v1/deals \
-H "Authorization: Bearer $NEXTORA_API_KEY" \
-d status=in_progress \
-d 'value[gte]=10000' \
-d 'expected_close_date[lte]=2026-12-31'For OR logic, emptiness checks, date windows and custom fields, pass filter: a JSON object of conditions, URL-encoded. It works alongside the field filters.
{
"conjunction": "and",
"conditions": [
{
"field": "status",
"operator": "any_of",
"value": [
"new",
"contacted"
]
},
{
"field": "created_at",
"operator": "last_n_days",
"value": 30
},
{
"field": "email",
"operator": "is_not_empty"
}
]
}How the conditions combine.
One of
andorThe conditions.
| Operator | Value | Matches |
|---|---|---|
eq, neq | A value | Equal, not equal. Text compares without case. |
contains, not_contains | Text | Contains the text, or does not. |
starts_with, ends_with | Text | Starts or ends with the text. |
any_of, none_of | An array | Equals one of the values, or none of them. |
gt, gte, lt, lte | A number or date | Comparisons. |
between | [from, to] | Inclusive range. |
last_n_days | A number | A date or time within the last N days. |
is_empty, is_not_empty | None | Has no value, or has one. |
checked, not_checked | None | A checkbox field is on, or off. |
Negative operators — neq, not_contains, none_of — also match records where the field is empty. A filter that is not valid JSON, or that uses an unknown field or operator, is a 400 validation_failed.
curl -G https://acme.nextora.co/api/v1/leads \
-H "Authorization: Bearer $NEXTORA_API_KEY" \
--data-urlencode 'filter={"conjunction":"and","conditions":[{"field":"status","operator":"any_of","value":["new","contacted"]},{"field":"created_at","operator":"last_n_days","value":30},{"field":"email","operator":"is_not_empty"}]}'{
"data": [
{
"id": "a7c9e1b3-5f2d-4a6c-8e9b-2d4f6a8c0e13",
"name": "Grace Whitfield",
"email": "[email protected]",
"phone": "+44 161 496 0732",
"company_name": "Harbor Logistics",
"status": "new",
"source": "website",
"score": 0,
"owner_id": "0c4f8e2a-7b3d-4a1f-9e6c-5d2b8a1f3e47",
"custom_fields": {
"budget": 15000
},
"created_at": "2026-10-10T07:58:31Z",
"updated_at": "2026-10-10T07:58:31Z"
}
],
"meta": {
"limit": 50,
"has_more": false,
"next_cursor": null
}
}sort takes one of the fields listed on the endpoint, and order is asc or desc. The default is the newest first: sort=created_at&order=desc. An unlisted field is a 400 validation_failed.
curl -G https://acme.nextora.co/api/v1/deals \
-H "Authorization: Bearer $NEXTORA_API_KEY" \
-d status=in_progress \
-d sort=expected_close_date \
-d order=ascq searches the text fields each endpoint names — contacts by name, email and phone, deals by title — and combines with filters and sorting. It matches parts of words, ignoring case.
curl -G https://acme.nextora.co/api/v1/contacts \
-H "Authorization: Bearer $NEXTORA_API_KEY" \
-d q=ada \
-d company_id=2b7e4c9a-5d1f-4a8e-9b3c-7f0a1d2e4c56