Page through run history
GET /runs lists your tenant's runs, newest first, with an ID tie-breaker
for stable ordering. It requires the read scope. Pages carry items and
an opaque nextCursor — treat nextCursor as an opaque string and never
derive a page number, offset, or ordering from it; its internal shape can
change without notice.
Listing one page
import { client, listRuns } from '@one-unity/rule-line-sdk';
client.setConfig({
baseUrl: 'https://api.rule-line.example.com',
auth: 'rl_key_your_api_key',
});
const page = await listRuns({ query: { limit: 50 } });
if (page.error) {
throw new Error(`list failed: ${page.error.code}`);
}
console.log(`${page.data.items.length} run(s), nextCursor: ${page.data.nextCursor}`);
Pass the previous response's nextCursor back as the cursor query
parameter to fetch the next page. A null nextCursor means you've reached
the last page:
let cursor: string | undefined;
do {
const page = await listRuns({ query: { limit: 50, cursor } });
if (page.error) throw new Error(`list failed: ${page.error.code}`);
for (const run of page.data.items) {
console.log(run.runId, run.status, run.outcome);
}
cursor = page.data.nextCursor ?? undefined;
} while (cursor);
Equivalent raw HTTP
GET /runs?limit=50 HTTP/1.1
Host: api.rule-line.example.com
Authorization: Bearer rl_key_your_api_key
The second (and every later) page repeats the call with &cursor=<opaque>
appended, using the exact string the previous response returned.
Expected response
{
"items": [
{
"runId": "22222222-2222-4222-8222-222222222222",
"rulesetId": "11111111-1111-4111-8111-111111111111",
"rulesetName": "invoice-routing",
"rulesetVersion": 3,
"status": "succeeded",
"outcome": "succeeded",
"test": false,
"createdAt": "2026-09-14T12:00:00.000Z",
"deliveryStatus": "succeeded"
}
],
"nextCursor": null
}
rulesetName is additive (plan 07-69, UAT-D8): every row now also carries the ruleset's own
name — the name stored on the exact ruleset_versions row the run executed, or null when that
row is not visible to you. No existing field changed meaning.
Iterating every run
The generated SDK's own async iterator follows nextCursor for you,
opaquely and unchanged, until the backend reports no further page:
import { client, listRunsIterator } from '@one-unity/rule-line-sdk';
client.setConfig({
baseUrl: 'https://api.rule-line.example.com',
auth: 'rl_key_your_api_key',
});
for await (const run of listRunsIterator({ limit: 50 })) {
console.log(run.runId, run.status, run.outcome);
}
This throws the terminal RuleLineError if any underlying page request
fails — wrap it in a try/catch in production code.
Filtering
Every filter below is AND-combined — supplying more than one narrows the result, it never widens it:
| Query parameter | Filters on |
|---|---|
rulesetId | One exact ruleset version. |
rulesetName | Every version of one ruleset, by its exact (case-sensitive) name — not a version picker, and not a pattern match. Additive (plan 07-69, UAT-D8): an optional parameter, and every existing parameter keeps its own meaning unchanged. |
status | Lifecycle status (queued, active, succeeded, failed, purged). |
outcome | Immutable terminal outcome (succeeded, failed) — stays queryable even after status becomes purged. |
test | Whether the run was submitted with test: true. |
createdFrom / createdTo | A creation-time range. |
deliveryStatus | Webhook delivery status (due, claimed, succeeded, failed, exhausted). |
const failedTestRuns = await listRuns({
query: { rulesetId: '11111111-1111-4111-8111-111111111111', outcome: 'failed', test: true, limit: 50 },
});
rulesetName combines with every other filter above, AND-combined exactly like the rest — a
name plus rulesetId narrows to that one version if it belongs to the named ruleset (or an empty
page if it does not):
const namedFailedTestRuns = await listRuns({
query: { rulesetName: 'invoice-routing', outcome: 'failed', test: true, limit: 50 },
});
Errors
| Code | When |
|---|---|
VALIDATION_FAILED | A query parameter fails validation. |
RUN_CURSOR_INVALID | The presented cursor is invalid or has expired — start over from the first page. |
AUTHENTICATION_REQUIRED / FORBIDDEN | Missing, invalid, or under-scoped credentials. |
See the full GET /runs reference
for the complete schema.