curl --request POST \
--url 'https://api.noresponse.org/v1/assessments/query' \
--header "Authorization: Bearer $NORESPONSE_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"account_id": "acct_7f3a9c",
"limit": 20
}'
import { NoResponse } from "@noresponse/node";
const noResponse = new NoResponse({
apiKey: process.env["NORESPONSE_API_KEY"] ?? "",
});
async function run() {
const result = await noResponse.assessments.query({
accountId: "acct_7f3a9c",
});
for await (const page of result) {
console.log(page);
}
}
run();
from noresponse import NoResponse
import os
with NoResponse(
api_key=os.getenv("NORESPONSE_API_KEY", ""),
) as no_response:
res = no_response.assessments.query(account_id="acct_7f3a9c", limit=20, cursor="eyJvIjoyMH0")
while res is not None:
# Handle items
res = res.next()
package main
import(
"context"
"os"
noresponse "github.com/noresponsehq/go/v5"
"github.com/noresponsehq/go/v5/models/components"
"log"
)
func main() {
ctx := context.Background()
s := noresponse.New(
noresponse.WithSecurity(os.Getenv("NORESPONSE_API_KEY")),
)
res, err := s.Assessments.Query(ctx, components.AssessmentQuery{
AccountID: "acct_7f3a9c",
})
if err != nil {
log.Fatal(err)
}
if res != nil {
for {
// handle items
res, err = res.Next()
if err != nil {
// handle error
}
if res == nil {
break
}
}
}
}
package hello.world;
import java.lang.Exception;
import org.noresponse.NoResponse;
import org.noresponse.models.errors.AuthenticationException;
import org.noresponse.models.errors.BadRequestException;
import org.noresponse.models.errors.ConflictException;
import org.noresponse.models.errors.NotFoundException;
import org.noresponse.models.errors.PermissionDeniedException;
import org.noresponse.models.errors.RateLimitException;
import org.noresponse.models.operations.QueryAccountAssessmentsResponse;
import org.noresponse.models.shared.AssessmentQuery;
public class Application {
public static void main(String[] args) throws Exception {
NoResponse sdk = NoResponse.builder()
.apiKey(System.getenv().getOrDefault("NORESPONSE_API_KEY", ""))
.build();
AssessmentQuery req = AssessmentQuery.builder()
.accountId("acct_7f3a9c")
.build();
sdk.assessments().query()
.callAsStream()
.forEach((QueryAccountAssessmentsResponse item) -> {
// handle page
});
}
}
using NoResponse;
using NoResponse.Models.Operations;
using NoResponse.Models.Shared;
using System;
var sdk = new NoResponseClient(apiKey: Environment.GetEnvironmentVariable("NORESPONSE_API_KEY"));
AssessmentQuery req = new AssessmentQuery() {
AccountId = "acct_7f3a9c",
};
QueryAccountAssessmentsResponse? res = await sdk.Assessments.QueryAsync(req);
while(res != null)
{
// handle items
res = await res.Next!();
}
<?php
declare(strict_types=1);
require 'vendor/autoload.php';
use NoResponse;
use NoResponse\Models\Shared;
$sdk = NoResponse\NoResponseClient::builder()
->setSecurity(
getenv('NORESPONSE_API_KEY') ?: ''
)
->build();
$request = new Shared\AssessmentQuery(
accountId: 'acct_7f3a9c',
);
$responses = $sdk->assessments->query(
request: $request
);
foreach ($responses as $response) {
if ($response->statusCode === 200) {
// handle response
}
}
require 'noresponse'
Models = ::NoResponse::Models
s = ::NoResponse::NoResponseClient.new(
api_key: ENV.fetch('NORESPONSE_API_KEY', '')
)
req = Models::Shared::AssessmentQuery.new(
account_id: 'acct_7f3a9c'
)
res = s.assessments.query(request: req)
unless res.nil?
# handle response
end
{
"schema_version": "1",
"account_id": "acct_7f3a9c",
"items": [
{
"schema_version": "1",
"assessment_id": "asm_01JA2Z8K6Q4V7W9XBCDEFGHJKM",
"account_id": "acct_7f3a9c",
"request_id": "req-2026-10-14-0001",
"policy_version": "heuristic-2026-10.1",
"policy_basis": "heuristic_unvalidated",
"assessment_version": 2,
"created_at": "2026-10-14T09:00:00.000Z",
"updated_at": "2026-10-14T09:00:00.412Z",
"expires_at": "2027-10-14T09:00:00.000Z",
"timing": {
"deadline_ms": 300,
"elapsed_ms": 287
},
"status": "complete",
"recommendation": "step_up",
"confidence": "medium",
"signals": [
{
"type": "account_presence",
"identifier": "email",
"outcome": "found",
"source_id": "src_7k2m9q",
"evidence_ref": "evr_01JA2Z8K6Q4V7W9XBCDEFGHJKN",
"observed_at": "2026-10-14T09:00:00.210Z",
"last_checked_at": "2026-10-14T09:00:00.210Z",
"freshness": "fresh"
},
{
"type": "account_presence",
"identifier": "username",
"outcome": "not_found",
"source_id": "src_3d8w1v",
"last_checked_at": "2026-10-14T09:00:00.190Z",
"freshness": "fresh"
},
{
"type": "breach_exposure",
"identifier": "email",
"outcome": "found",
"source_id": "src_x4p6t0",
"evidence_ref": "evr_01JA2Z8K6Q4V7W9XBCDEFGHJKP",
"observed_at": "2025-03-02T00:00:00Z",
"last_checked_at": "2026-10-14T09:00:00.150Z",
"freshness": "stale"
}
],
"incomplete_sources": []
},
{
"schema_version": "1",
"assessment_id": "asm_01JA2Z9Y3R5T6V7W8X9ZABCDEF",
"account_id": "acct_7f3a9c",
"request_id": "req-2026-10-01-0007",
"policy_version": "heuristic-2026-10.1",
"policy_basis": "heuristic_unvalidated",
"assessment_version": 2,
"created_at": "2026-10-01T12:00:00Z",
"updated_at": "2026-10-01T12:00:05Z",
"expires_at": "2027-10-01T12:00:00.000Z",
"timing": {
"deadline_ms": 300,
"elapsed_ms": 287
},
"status": "complete",
"recommendation": "allow",
"confidence": "high",
"signals": [
{
"type": "account_presence",
"identifier": "username",
"outcome": "not_found",
"source_id": "src_3d8w1v",
"last_checked_at": "2026-10-14T09:00:00.190Z",
"freshness": "fresh"
}
],
"incomplete_sources": []
}
],
"next_cursor": "eyJiIjoiY2hrXzAxIn0",
"retention_days": 365
}{
"type": "<string>",
"title": "<string>",
"status": 400,
"detail": "<string>",
"code": "invalid_request",
"request_id": "<string>",
"instance": "<string>",
"invalid_params": [
{
"field": "<string>",
"reason": "<string>",
"example": "<string>"
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 401,
"detail": "<string>",
"code": "unauthorized",
"request_id": "<string>",
"instance": "<string>",
"invalid_params": [
{
"field": "<string>",
"reason": "<string>",
"example": "<string>"
}
]
}{
"type": "https://docs.noresponse.org/problems/workspace-forbidden",
"title": "Forbidden",
"status": 403,
"detail": "The API key does not carry a scope this operation accepts.",
"code": "workspace_forbidden",
"request_id": "0123456789abcdef0123456789abcdef"
}{
"type": "<string>",
"title": "<string>",
"status": 413,
"detail": "<string>",
"code": "payload_too_large",
"request_id": "<string>",
"instance": "<string>",
"invalid_params": [
{
"field": "<string>",
"reason": "<string>",
"example": "<string>"
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 415,
"detail": "<string>",
"code": "unsupported_media_type",
"request_id": "<string>",
"instance": "<string>",
"invalid_params": [
{
"field": "<string>",
"reason": "<string>",
"example": "<string>"
}
]
}{
"type": "https://docs.noresponse.org/problems/rate-limited",
"title": "Rate limited",
"status": 429,
"detail": "The tenant's assessment rate is exhausted; retry after the Retry-After interval.",
"code": "rate_limited",
"request_id": "0123456789abcdef0123456789abcdef"
}{
"type": "<string>",
"title": "<string>",
"status": 503,
"detail": "<string>",
"code": "service_unavailable",
"request_id": "<string>",
"instance": "<string>",
"invalid_params": [
{
"field": "<string>",
"reason": "<string>",
"example": "<string>"
}
]
}List an account's assessments
Pages through the unexpired assessments for one of your accounts, newest first, each at its latest version.
It is a POST so that account_id stays out of URLs and access logs. It is read-only and safe to retry, and takes no Idempotency-Key. An account with no assessments answers 200 with empty items.
Pass next_cursor back unchanged to read the next page. A changed, foreign or expired cursor answers 400 invalid_cursor.
Requires the history scope. response_mode: "detailed" also needs the detailed scope.
curl --request POST \
--url 'https://api.noresponse.org/v1/assessments/query' \
--header "Authorization: Bearer $NORESPONSE_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"account_id": "acct_7f3a9c",
"limit": 20
}'
import { NoResponse } from "@noresponse/node";
const noResponse = new NoResponse({
apiKey: process.env["NORESPONSE_API_KEY"] ?? "",
});
async function run() {
const result = await noResponse.assessments.query({
accountId: "acct_7f3a9c",
});
for await (const page of result) {
console.log(page);
}
}
run();
from noresponse import NoResponse
import os
with NoResponse(
api_key=os.getenv("NORESPONSE_API_KEY", ""),
) as no_response:
res = no_response.assessments.query(account_id="acct_7f3a9c", limit=20, cursor="eyJvIjoyMH0")
while res is not None:
# Handle items
res = res.next()
package main
import(
"context"
"os"
noresponse "github.com/noresponsehq/go/v5"
"github.com/noresponsehq/go/v5/models/components"
"log"
)
func main() {
ctx := context.Background()
s := noresponse.New(
noresponse.WithSecurity(os.Getenv("NORESPONSE_API_KEY")),
)
res, err := s.Assessments.Query(ctx, components.AssessmentQuery{
AccountID: "acct_7f3a9c",
})
if err != nil {
log.Fatal(err)
}
if res != nil {
for {
// handle items
res, err = res.Next()
if err != nil {
// handle error
}
if res == nil {
break
}
}
}
}
package hello.world;
import java.lang.Exception;
import org.noresponse.NoResponse;
import org.noresponse.models.errors.AuthenticationException;
import org.noresponse.models.errors.BadRequestException;
import org.noresponse.models.errors.ConflictException;
import org.noresponse.models.errors.NotFoundException;
import org.noresponse.models.errors.PermissionDeniedException;
import org.noresponse.models.errors.RateLimitException;
import org.noresponse.models.operations.QueryAccountAssessmentsResponse;
import org.noresponse.models.shared.AssessmentQuery;
public class Application {
public static void main(String[] args) throws Exception {
NoResponse sdk = NoResponse.builder()
.apiKey(System.getenv().getOrDefault("NORESPONSE_API_KEY", ""))
.build();
AssessmentQuery req = AssessmentQuery.builder()
.accountId("acct_7f3a9c")
.build();
sdk.assessments().query()
.callAsStream()
.forEach((QueryAccountAssessmentsResponse item) -> {
// handle page
});
}
}
using NoResponse;
using NoResponse.Models.Operations;
using NoResponse.Models.Shared;
using System;
var sdk = new NoResponseClient(apiKey: Environment.GetEnvironmentVariable("NORESPONSE_API_KEY"));
AssessmentQuery req = new AssessmentQuery() {
AccountId = "acct_7f3a9c",
};
QueryAccountAssessmentsResponse? res = await sdk.Assessments.QueryAsync(req);
while(res != null)
{
// handle items
res = await res.Next!();
}
<?php
declare(strict_types=1);
require 'vendor/autoload.php';
use NoResponse;
use NoResponse\Models\Shared;
$sdk = NoResponse\NoResponseClient::builder()
->setSecurity(
getenv('NORESPONSE_API_KEY') ?: ''
)
->build();
$request = new Shared\AssessmentQuery(
accountId: 'acct_7f3a9c',
);
$responses = $sdk->assessments->query(
request: $request
);
foreach ($responses as $response) {
if ($response->statusCode === 200) {
// handle response
}
}
require 'noresponse'
Models = ::NoResponse::Models
s = ::NoResponse::NoResponseClient.new(
api_key: ENV.fetch('NORESPONSE_API_KEY', '')
)
req = Models::Shared::AssessmentQuery.new(
account_id: 'acct_7f3a9c'
)
res = s.assessments.query(request: req)
unless res.nil?
# handle response
end
{
"schema_version": "1",
"account_id": "acct_7f3a9c",
"items": [
{
"schema_version": "1",
"assessment_id": "asm_01JA2Z8K6Q4V7W9XBCDEFGHJKM",
"account_id": "acct_7f3a9c",
"request_id": "req-2026-10-14-0001",
"policy_version": "heuristic-2026-10.1",
"policy_basis": "heuristic_unvalidated",
"assessment_version": 2,
"created_at": "2026-10-14T09:00:00.000Z",
"updated_at": "2026-10-14T09:00:00.412Z",
"expires_at": "2027-10-14T09:00:00.000Z",
"timing": {
"deadline_ms": 300,
"elapsed_ms": 287
},
"status": "complete",
"recommendation": "step_up",
"confidence": "medium",
"signals": [
{
"type": "account_presence",
"identifier": "email",
"outcome": "found",
"source_id": "src_7k2m9q",
"evidence_ref": "evr_01JA2Z8K6Q4V7W9XBCDEFGHJKN",
"observed_at": "2026-10-14T09:00:00.210Z",
"last_checked_at": "2026-10-14T09:00:00.210Z",
"freshness": "fresh"
},
{
"type": "account_presence",
"identifier": "username",
"outcome": "not_found",
"source_id": "src_3d8w1v",
"last_checked_at": "2026-10-14T09:00:00.190Z",
"freshness": "fresh"
},
{
"type": "breach_exposure",
"identifier": "email",
"outcome": "found",
"source_id": "src_x4p6t0",
"evidence_ref": "evr_01JA2Z8K6Q4V7W9XBCDEFGHJKP",
"observed_at": "2025-03-02T00:00:00Z",
"last_checked_at": "2026-10-14T09:00:00.150Z",
"freshness": "stale"
}
],
"incomplete_sources": []
},
{
"schema_version": "1",
"assessment_id": "asm_01JA2Z9Y3R5T6V7W8X9ZABCDEF",
"account_id": "acct_7f3a9c",
"request_id": "req-2026-10-01-0007",
"policy_version": "heuristic-2026-10.1",
"policy_basis": "heuristic_unvalidated",
"assessment_version": 2,
"created_at": "2026-10-01T12:00:00Z",
"updated_at": "2026-10-01T12:00:05Z",
"expires_at": "2027-10-01T12:00:00.000Z",
"timing": {
"deadline_ms": 300,
"elapsed_ms": 287
},
"status": "complete",
"recommendation": "allow",
"confidence": "high",
"signals": [
{
"type": "account_presence",
"identifier": "username",
"outcome": "not_found",
"source_id": "src_3d8w1v",
"last_checked_at": "2026-10-14T09:00:00.190Z",
"freshness": "fresh"
}
],
"incomplete_sources": []
}
],
"next_cursor": "eyJiIjoiY2hrXzAxIn0",
"retention_days": 365
}{
"type": "<string>",
"title": "<string>",
"status": 400,
"detail": "<string>",
"code": "invalid_request",
"request_id": "<string>",
"instance": "<string>",
"invalid_params": [
{
"field": "<string>",
"reason": "<string>",
"example": "<string>"
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 401,
"detail": "<string>",
"code": "unauthorized",
"request_id": "<string>",
"instance": "<string>",
"invalid_params": [
{
"field": "<string>",
"reason": "<string>",
"example": "<string>"
}
]
}{
"type": "https://docs.noresponse.org/problems/workspace-forbidden",
"title": "Forbidden",
"status": 403,
"detail": "The API key does not carry a scope this operation accepts.",
"code": "workspace_forbidden",
"request_id": "0123456789abcdef0123456789abcdef"
}{
"type": "<string>",
"title": "<string>",
"status": 413,
"detail": "<string>",
"code": "payload_too_large",
"request_id": "<string>",
"instance": "<string>",
"invalid_params": [
{
"field": "<string>",
"reason": "<string>",
"example": "<string>"
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 415,
"detail": "<string>",
"code": "unsupported_media_type",
"request_id": "<string>",
"instance": "<string>",
"invalid_params": [
{
"field": "<string>",
"reason": "<string>",
"example": "<string>"
}
]
}{
"type": "https://docs.noresponse.org/problems/rate-limited",
"title": "Rate limited",
"status": 429,
"detail": "The tenant's assessment rate is exhausted; retry after the Retry-After interval.",
"code": "rate_limited",
"request_id": "0123456789abcdef0123456789abcdef"
}{
"type": "<string>",
"title": "<string>",
"status": 503,
"detail": "<string>",
"code": "service_unavailable",
"request_id": "<string>",
"instance": "<string>",
"invalid_params": [
{
"field": "<string>",
"reason": "<string>",
"example": "<string>"
}
]
}Authorizations
Your API key, sent as Authorization: Bearer <key>. A key is nrk_live_ or nrk_test_, a 26-character key id, _ and a 43-character secret. A key sees only its own environment's data.
Each key has one or more scopes: assess creates and reads assessments, records outcomes and reports key usage; history reads assessments, an account's current risk and an account's history, and erases an account; detailed adds the detailed view; webhooks registers, tests, rotates and deletes webhook endpoints; integrations registers and manages hosted provider integrations. A missing, unknown, revoked or expired key answers 401. A valid key without the scope an operation needs answers 403.
Body
POST /v1/assessments/query body. account_id travels in the body rather than the URL path so a provider value that turns out to hold personal data is not written to access logs, proxies or browser history. Read-only: no Idempotency-Key. An account with no unexpired assessments answers 200 with empty items.
The provider's own opaque identifier for the account being checked, scoped to the calling workspace. It must be provider-opaque and must not contain a direct identifier (email, phone, name, national id): that is a provider obligation the schema can only partly check. '|' is accepted so an Auth0 user id such as 'auth0|64abc' passes unchanged; '@', '+', '$' and whitespace are refused by the pattern, as is an exact-shape JWT; a hex digest such as a SHA-256 is allowed, because hashing an internal id is a common pseudonymous scheme. A value such as '07700900123' or 'jane.doe.gmail.com' cannot be told apart from an opaque id. It travels in bodies, and in a URL only as the path segment of GET /v1/accounts/{account_id} and its /assessments. An assessment requested by a provider hook at pre_registration, which has no account yet, carries the server-issued account_id pre: followed by its assessment_id.
1 - 128^[A-Za-z0-9][A-Za-z0-9._:|-]{0,127}$1 <= x <= 50next_cursor from the previous page, unchanged. Opaque, MAC'd and bound to the workspace and account_id.
1 - 256^[A-Za-z0-9_-]+$standard returns the consolidated risk response; detailed adds merged provider-neutral facts when the key has detailed scope. raw is never available to a workspace.
standard, detailed Response
One page of the account's unexpired assessments.
Body of the 200 answer to POST /v1/assessments/query: one page of the calling workspace's unexpired assessments for one account, newest first, each at its latest assessment_version, as its detail (the assessment detail schema); the account's current risk is GET /v1/accounts/{account_id}. Every item's account_id equals the page's. An assessment past its expires_at is not listed. next_cursor is present only when another page exists.
Version of the body shape.
The provider's own opaque identifier for the account being checked, scoped to the calling workspace. It must be provider-opaque and must not contain a direct identifier (email, phone, name, national id): that is a provider obligation the schema can only partly check. '|' is accepted so an Auth0 user id such as 'auth0|64abc' passes unchanged; '@', '+', '$' and whitespace are refused by the pattern, as is an exact-shape JWT; a hex digest such as a SHA-256 is allowed, because hashing an internal id is a common pseudonymous scheme. A value such as '07700900123' or 'jane.doe.gmail.com' cannot be told apart from an opaque id. It travels in bodies, and in a URL only as the path segment of GET /v1/accounts/{account_id} and its /assessments. An assessment requested by a provider hook at pre_registration, which has no account yet, carries the server-issued account_id pre: followed by its assessment_id.
1 - 128^[A-Za-z0-9][A-Za-z0-9._:|-]{0,127}$50Show child attributes
Show child attributes
The workspace's current retention period, so a consumer knows how far back history reaches. Every item expires no later than its created_at plus this many days.
1 <= x <= 365Opaque cursor for the next page: server-generated, integrity-protected with a server-held MAC key, and bound to the workspace principal and the account_id it was issued for. Pass it back unchanged in the next query; a cursor that fails the MAC, belongs to another workspace or account, or has expired answers 400 invalid_cursor. Consumers must not parse it.
1 - 256^[A-Za-z0-9_-]+$