Skip to content

Get and query assessments

Two reads exist. GET /v1/assessments/{assessment_id} returns the latest version of one assessment and is the authoritative way to poll a pending answer or refresh one a webhook told you about. POST /v1/assessments/query pages through every unexpired assessment of one account. Both are in the interactive reference.

GET /v1/assessments/{assessment_id} needs the assess or the history scope. A key with only assess can read the assessments it created without being able to list an account’s history.

const assessment = await nr.assessments.get("asm_01JB3C4D5E6F7G8H9JKMNPQRST");
// Poll until it is no longer pending, honouring Retry-After. Gives up after 30 s by default.
const settled = await nr.assessments.wait("asm_01JB3C4D5E6F7G8H9JKMNPQRST", { timeoutMs: 10_000 });
Parameter In Required Value
assessment_id path Yes asm_ and 26 characters, matched case-sensitively. A value of any other shape answers 404, not 400.
response_mode query No standard (default) or detailed. detailed needs the detailed scope as well.

200 OK with the assessment object at its highest assessment_version. While status is pending, or partial with a source still continuing, the response carries Retry-After; poll no faster than it says. The SDK wait helpers poll on Retry-After, with a one second floor when the header is absent, and stop at their timeout with a timeout error.

Status Code When
401 unauthorized No key, or a malformed, unknown, revoked or expired key.
403 tenant_forbidden The key has neither assess nor history, or asked for detailed without the scope.
404 not_found See below.
429 rate_limited Retry after Retry-After.
503 service_unavailable Retry after Retry-After.

An unknown id, an expired assessment, a malformed id and another organisation’s assessment all answer the same 404 not_found.

An assessment expires at its expires_at at the latest: created_at plus your retention period when it was created, 365 days by default. If you shorten your retention period it is gone sooner. After that moment it is gone. GET answers 404, the assessment leaves history, and one last assessment.updated webhook with status: "expired" closes it. A later revision keeps the original expires_at, and a new assessment for the same account does not renew an older one. See Data retention.

POST /v1/assessments/query needs the history scope. The account id travels in the body rather than the URL, so it stays out of access logs and proxies. The request is read-only and safe to retry; it takes no Idempotency-Key.

// One page.
const page = await nr.assessments.query({ accountId: "usr_8f2k1", limit: 20 });
console.log(page.items.length, page.hasMore, page.nextCursor);
// Every item, across pages.
for await (const assessment of await nr.assessments.query({ accountId: "usr_8f2k1" })) {
console.log(assessment.assessmentId, assessment.status, assessment.risk?.score);
}
Field Type Required Value
account_id string Yes The account to list, in the same shape as on create.
limit integer No 1 to 50 items per page. Default 20.
cursor string No next_cursor from the previous page, unchanged. 1 to 256 characters of letters, digits, _ and -.
response_mode string No standard (default) or detailed. detailed needs the detailed scope as well as history.

200 OK with one page:

{
"schema_version": "1",
"account_id": "usr_8f2k1",
"items": [
{ "assessment_id": "asm_01JA2Z8K6Q4V7W9XBCDEFGHJKM", "status": "complete", "recommendation": "step_up", "...": "..." },
{ "assessment_id": "asm_01JA2Z9Y3R5T6V7W8X9ZABCDEF", "status": "complete", "recommendation": "allow", "...": "..." }
],
"next_cursor": "eyJiIjoiY2hrXzAxIn0",
"retention_days": 365
}
Field Type Meaning
schema_version string "1".
account_id string The account you asked about. Every item’s account_id equals it.
items array At most limit assessment objects, newest first, each at its latest assessment_version. Only unexpired assessments are listed. An account with none answers 200 with an empty array, not 404.
next_cursor string Present only when another page exists. Opaque, integrity-protected and bound to your organisation and this account_id. Do not parse it.
retention_days integer Your current retention period, 1 to 365, so you know how far back history reaches. No item expires later than its created_at plus this many days.
Status Code When
400 invalid_request The body breaks a rule above.
400 invalid_cursor The cursor was changed, was issued for another account or organisation, or has expired. Start again without one.
401 unauthorized No key, or a malformed, unknown, revoked or expired key.
403 tenant_forbidden The key lacks history, or detailed when asked for.
413 payload_too_large The body is over 32,768 bytes.
415 unsupported_media_type Content-Type is not application/json.
429 rate_limited Retry after Retry-After.
503 service_unavailable Retry after Retry-After.

A page carries next_cursor only when more items exist. To read the next page, send the same account_id and limit with cursor set to that value. When a page has no next_cursor, you have everything.

The SDK iterators do this for you: for await over the query in TypeScript, plain iteration over the page in Python, and noresponse.AllAssessments in Go, which returns an iter.Seq2 of assessment and error. Each fetches the next page as you reach the end of the current one, so a long history costs one request per 50 items and no more memory than one page.