> ## Documentation Index
> Fetch the complete documentation index at: https://docs.noresponse.org/llms.txt
> Use this file to discover all available pages before exploring further.

# 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.



## OpenAPI

````yaml /openapi.json post /v1/assessments/query
openapi: 3.1.0
info:
  title: NoResponse API
  version: '1'
  description: >-
    The NoResponse API assesses a signup, login or purchase and answers with the
    account's one current risk: a 0 to 100 score, a decision for the flow
    (`allow`, `step_up`, `review` or `block`), the reasons behind it and the
    decision for each flow. The assessment's own facts, such as its status,
    confidence and incomplete sources, sit under `detail`.


    Authenticate every request with your API key as `Authorization: Bearer
    nrk_...`. Call the API only from your backend.


    Guides, SDKs and webhook verification are at
    [docs.noresponse.org](https://docs.noresponse.org/). Every error is an RFC
    9457 problem document; see
    [Errors](https://docs.noresponse.org/reference/errors).
servers:
  - url: https://api.noresponse.org
    description: Production
security:
  - tenantBearer: []
tags:
  - name: assess
    x-displayName: Assessments
    x-group: Assessments
    description: Create, read and list assessments, and report outcomes.
  - name: accounts
    x-displayName: Accounts
    x-group: Accounts
    description: >-
      Each of your accounts holds one current risk, and its assessments are its
      history.
  - name: usage
    x-displayName: Key usage
    x-group: Key usage
    description: >-
      Report usage of the API keys your signup gate issued, so a shared or
      stolen key raises its account's risk.
  - name: keys
    x-displayName: API keys
    x-group: API keys
    description: Rotate your own API key.
  - name: integrations
    x-displayName: Integrations
    x-group: Integrations
    description: >-
      Hosted endpoints that answer your WorkOS or Auth0 sign-up and sign-in
      hooks.
  - name: webhooks
    x-displayName: Webhooks
    x-group: Webhooks
    description: Your webhook endpoints, and the signed events NoResponse sends to them.
paths:
  /v1/assessments/query:
    post:
      tags:
        - assess
      summary: List an account's assessments
      description: >-
        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.
      operationId: queryAccountAssessments
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AssessmentQuery'
            examples:
              firstPage:
                value:
                  account_id: acct_7f3a9c
                  limit: 20
      responses:
        '200':
          $ref: '#/components/responses/AssessmentList'
        '400':
          $ref: '#/components/responses/InvalidHistoryQuery'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/WorkspaceForbidden'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '429':
          $ref: '#/components/responses/RateLimited'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
      security:
        - tenantBearer: []
      x-codeSamples:
        - lang: curl
          label: cURL
          source: |
            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
            }'
        - lang: typescript
          label: TypeScript
          source: |
            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();
        - lang: python
          label: Python
          source: |
            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()
        - lang: go
          label: Go
          source: "package main\n\nimport(\n\t\"context\"\n\t\"os\"\n\tnoresponse \"github.com/noresponsehq/go/v5\"\n\t\"github.com/noresponsehq/go/v5/models/components\"\n\t\"log\"\n)\n\nfunc main() {\n    ctx := context.Background()\n\n    s := noresponse.New(\n        noresponse.WithSecurity(os.Getenv(\"NORESPONSE_API_KEY\")),\n    )\n\n    res, err := s.Assessments.Query(ctx, components.AssessmentQuery{\n        AccountID: \"acct_7f3a9c\",\n    })\n    if err != nil {\n        log.Fatal(err)\n    }\n    if res != nil {\n        for {\n            // handle items\n\n            res, err = res.Next()\n\n            if err != nil {\n                // handle error\n            }\n\n            if res == nil {\n                break\n            }\n        }\n    }\n}\n"
        - lang: java
          label: Java
          source: >
            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
                            });

                }
            }
        - lang: csharp
          label: C#
          source: >
            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!();
            }
        - lang: php
          label: PHP
          source: |
            <?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
                }
            }
        - lang: ruby
          label: Ruby
          source: |
            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
components:
  schemas:
    AssessmentQuery:
      title: Account assessment history query
      description: >-
        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.
      type: object
      additionalProperties: false
      required:
        - account_id
      properties:
        account_id:
          type: string
          minLength: 1
          maxLength: 128
          pattern: ^[A-Za-z0-9][A-Za-z0-9._:|-]{0,127}$
          description: >-
            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.
          not:
            description: refused_text plus secret_encoded, for account_id.
            anyOf:
              - description: >-
                  A line feed anywhere, refused with `not` beside every anchored
                  pattern.
                pattern: \n
              - description: >-
                  Exact shapes only: a complete modular-crypt password hash
                  (bcrypt $2a$/$2b$/$2x$/$2y$ with a two-digit cost and 53
                  characters; $argon2i/d/id with its m, t, p parameters, salt
                  and hash; md5-crypt $1$, sha256-crypt $5$ or sha512-crypt $6$
                  with a 22, 43 or 86 character hash; passlib $scrypt$ with ln,
                  r, p, salt and hash) or a three-segment JWT whose header is
                  base64url JSON opening with an "alg", "typ", "kid" or "cty"
                  member (eyJhbGciOi, eyJ0eXAiOi, eyJraWQiOi or eyJjdHkiOi). A
                  value that merely starts with '$2' or 'eyJ', such as
                  eyJohnathan.doe.x, is not refused. Best effort, not a
                  guarantee; see the provider obligation in the README.
                anyOf:
                  - pattern: ^\$2[abxy]?\$[0-9]{2}\$[./A-Za-z0-9]{53}$
                  - pattern: >-
                      ^\$argon2(?:id|i|d)\$(?:v=[0-9]{1,4}\$)?m=[0-9]{1,10},t=[0-9]{1,10},p=[0-9]{1,3}\$[A-Za-z0-9+/]{8,}\$[A-Za-z0-9+/]{16,}$
                  - pattern: >-
                      ^\$[156]\$(?:rounds=[0-9]{1,9}\$)?[./A-Za-z0-9]{1,16}\$(?:[./A-Za-z0-9]{22}|[./A-Za-z0-9]{43}|[./A-Za-z0-9]{86})$
                  - pattern: >-
                      ^\$scrypt\$ln=[0-9]{1,2},r=[0-9]{1,3},p=[0-9]{1,3}\$[A-Za-z0-9+/.]{8,}\$[A-Za-z0-9+/.]{16,}$
                  - pattern: >-
                      ^eyJ(?:hbGciOi|0eXAiOi|raWQiOi|jdHkiOi)[A-Za-z0-9_-]*\.[A-Za-z0-9_-]{2,}\.[A-Za-z0-9_-]*$
        limit:
          type: integer
          minimum: 1
          maximum: 50
          default: 20
        cursor:
          type: string
          minLength: 1
          maxLength: 256
          pattern: ^[A-Za-z0-9_-]+$
          not:
            description: >-
              A line feed anywhere, refused with `not` beside every anchored
              pattern.
            pattern: \n
          description: >-
            next_cursor from the previous page, unchanged. Opaque, MAC'd and
            bound to the workspace and account_id.
        response_mode:
          enum:
            - standard
            - detailed
          default: standard
          description: >-
            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.
    AssessmentList:
      title: Account assessment history
      description: >-
        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.
      type: object
      additionalProperties: false
      required:
        - schema_version
        - account_id
        - items
        - retention_days
      properties:
        schema_version:
          const: '1'
          description: Version of the body shape.
        account_id:
          type: string
          minLength: 1
          maxLength: 128
          pattern: ^[A-Za-z0-9][A-Za-z0-9._:|-]{0,127}$
          description: >-
            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.
          not:
            description: refused_text plus secret_encoded, for account_id.
            anyOf:
              - description: >-
                  A line feed anywhere, refused with `not` beside every anchored
                  pattern.
                pattern: \n
              - description: >-
                  Exact shapes only: a complete modular-crypt password hash
                  (bcrypt $2a$/$2b$/$2x$/$2y$ with a two-digit cost and 53
                  characters; $argon2i/d/id with its m, t, p parameters, salt
                  and hash; md5-crypt $1$, sha256-crypt $5$ or sha512-crypt $6$
                  with a 22, 43 or 86 character hash; passlib $scrypt$ with ln,
                  r, p, salt and hash) or a three-segment JWT whose header is
                  base64url JSON opening with an "alg", "typ", "kid" or "cty"
                  member (eyJhbGciOi, eyJ0eXAiOi, eyJraWQiOi or eyJjdHkiOi). A
                  value that merely starts with '$2' or 'eyJ', such as
                  eyJohnathan.doe.x, is not refused. Best effort, not a
                  guarantee; see the provider obligation in the README.
                anyOf:
                  - pattern: ^\$2[abxy]?\$[0-9]{2}\$[./A-Za-z0-9]{53}$
                  - pattern: >-
                      ^\$argon2(?:id|i|d)\$(?:v=[0-9]{1,4}\$)?m=[0-9]{1,10},t=[0-9]{1,10},p=[0-9]{1,3}\$[A-Za-z0-9+/]{8,}\$[A-Za-z0-9+/]{16,}$
                  - pattern: >-
                      ^\$[156]\$(?:rounds=[0-9]{1,9}\$)?[./A-Za-z0-9]{1,16}\$(?:[./A-Za-z0-9]{22}|[./A-Za-z0-9]{43}|[./A-Za-z0-9]{86})$
                  - pattern: >-
                      ^\$scrypt\$ln=[0-9]{1,2},r=[0-9]{1,3},p=[0-9]{1,3}\$[A-Za-z0-9+/.]{8,}\$[A-Za-z0-9+/.]{16,}$
                  - pattern: >-
                      ^eyJ(?:hbGciOi|0eXAiOi|raWQiOi|jdHkiOi)[A-Za-z0-9_-]*\.[A-Za-z0-9_-]{2,}\.[A-Za-z0-9_-]*$
        items:
          type: array
          maxItems: 50
          items:
            title: Assessment detail
            description: >-
              One assessment's own facts: the detail member of the assessment
              resource (the assessment schema) and one item of an account's
              history page. The recommendation is advisory and produced by a
              hand-authored, unvalidated heuristic policy: the 0-100 risk score
              is a heuristic sum of reason weights, never a probability, and no
              provider score is published. Failure and absence stay separate:
              every lane that did not settle is listed in incomplete_sources
              with a reason, and a lane that failed or timed out is never
              reported not_found. No field is defined for a password, hash,
              token, raw breach value or workspace identifier, and unknown
              members are refused; evidence is referenced by opaque
              evidence_ref. risk here is this assessment's own score; the
              account's current risk is the assessment resource's account.
            type: object
            additionalProperties: false
            required:
              - schema_version
              - assessment_id
              - account_id
              - status
              - confidence
              - incomplete_sources
              - policy_version
              - policy_basis
              - assessment_version
              - created_at
              - updated_at
              - expires_at
              - timing
            properties:
              schema_version:
                const: '1'
                description: Version of the body shape.
              assessment_id:
                type: string
                pattern: ^asm_[0-9A-HJKMNP-TV-Z]{26}$
                description: >-
                  Opaque, server-assigned assessment id: 'asm_' and a
                  26-character Crockford base32 ULID. Unique within the
                  workspace; another workspace's assessment id answers 404.
                not:
                  description: >-
                    A line feed anywhere, refused with `not` beside every
                    anchored pattern.
                  pattern: \n
              account_id:
                type: string
                minLength: 1
                maxLength: 128
                pattern: ^[A-Za-z0-9][A-Za-z0-9._:|-]{0,127}$
                description: >-
                  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.
                not:
                  description: refused_text plus secret_encoded, for account_id.
                  anyOf:
                    - description: >-
                        A line feed anywhere, refused with `not` beside every
                        anchored pattern.
                      pattern: \n
                    - description: >-
                        Exact shapes only: a complete modular-crypt password
                        hash (bcrypt $2a$/$2b$/$2x$/$2y$ with a two-digit cost
                        and 53 characters; $argon2i/d/id with its m, t, p
                        parameters, salt and hash; md5-crypt $1$, sha256-crypt
                        $5$ or sha512-crypt $6$ with a 22, 43 or 86 character
                        hash; passlib $scrypt$ with ln, r, p, salt and hash) or
                        a three-segment JWT whose header is base64url JSON
                        opening with an "alg", "typ", "kid" or "cty" member
                        (eyJhbGciOi, eyJ0eXAiOi, eyJraWQiOi or eyJjdHkiOi). A
                        value that merely starts with '$2' or 'eyJ', such as
                        eyJohnathan.doe.x, is not refused. Best effort, not a
                        guarantee; see the provider obligation in the README.
                      anyOf:
                        - pattern: ^\$2[abxy]?\$[0-9]{2}\$[./A-Za-z0-9]{53}$
                        - pattern: >-
                            ^\$argon2(?:id|i|d)\$(?:v=[0-9]{1,4}\$)?m=[0-9]{1,10},t=[0-9]{1,10},p=[0-9]{1,3}\$[A-Za-z0-9+/]{8,}\$[A-Za-z0-9+/]{16,}$
                        - pattern: >-
                            ^\$[156]\$(?:rounds=[0-9]{1,9}\$)?[./A-Za-z0-9]{1,16}\$(?:[./A-Za-z0-9]{22}|[./A-Za-z0-9]{43}|[./A-Za-z0-9]{86})$
                        - pattern: >-
                            ^\$scrypt\$ln=[0-9]{1,2},r=[0-9]{1,3},p=[0-9]{1,3}\$[A-Za-z0-9+/.]{8,}\$[A-Za-z0-9+/.]{16,}$
                        - pattern: >-
                            ^eyJ(?:hbGciOi|0eXAiOi|raWQiOi|jdHkiOi)[A-Za-z0-9_-]*\.[A-Za-z0-9_-]{2,}\.[A-Za-z0-9_-]*$
              request_id:
                type: string
                minLength: 1
                maxLength: 128
                pattern: ^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$
                description: >-
                  An optional provider correlation id, echoed back. It is not an
                  idempotency key. Refuses an exact-shape JWT or a bare 40, 64
                  or 128 character hex digest; a UUID is accepted.
                not:
                  description: >-
                    refused_text plus secret_hex_digest and secret_encoded, for
                    request_id and username.
                  anyOf:
                    - description: >-
                        A line feed anywhere, refused with `not` beside every
                        anchored pattern.
                      pattern: \n
                    - description: >-
                        Exactly 40, 64 or 128 hex characters (SHA-1, SHA-256,
                        SHA-512) and nothing else. Refused in username and
                        request_id, where such a value is almost certainly a
                        credential hash; a 39 or 41 character hex string, a
                        short hex word such as 'deadbeef' or a UUID is accepted.
                        Not refused in account_id: a hex digest of an internal
                        id is a common pseudonymous account id and not a secret
                        under.
                      pattern: ^(?:[0-9A-Fa-f]{40}|[0-9A-Fa-f]{64}|[0-9A-Fa-f]{128})$
                    - description: >-
                        Exact shapes only: a complete modular-crypt password
                        hash (bcrypt $2a$/$2b$/$2x$/$2y$ with a two-digit cost
                        and 53 characters; $argon2i/d/id with its m, t, p
                        parameters, salt and hash; md5-crypt $1$, sha256-crypt
                        $5$ or sha512-crypt $6$ with a 22, 43 or 86 character
                        hash; passlib $scrypt$ with ln, r, p, salt and hash) or
                        a three-segment JWT whose header is base64url JSON
                        opening with an "alg", "typ", "kid" or "cty" member
                        (eyJhbGciOi, eyJ0eXAiOi, eyJraWQiOi or eyJjdHkiOi). A
                        value that merely starts with '$2' or 'eyJ', such as
                        eyJohnathan.doe.x, is not refused. Best effort, not a
                        guarantee; see the provider obligation in the README.
                      anyOf:
                        - pattern: ^\$2[abxy]?\$[0-9]{2}\$[./A-Za-z0-9]{53}$
                        - pattern: >-
                            ^\$argon2(?:id|i|d)\$(?:v=[0-9]{1,4}\$)?m=[0-9]{1,10},t=[0-9]{1,10},p=[0-9]{1,3}\$[A-Za-z0-9+/]{8,}\$[A-Za-z0-9+/]{16,}$
                        - pattern: >-
                            ^\$[156]\$(?:rounds=[0-9]{1,9}\$)?[./A-Za-z0-9]{1,16}\$(?:[./A-Za-z0-9]{22}|[./A-Za-z0-9]{43}|[./A-Za-z0-9]{86})$
                        - pattern: >-
                            ^\$scrypt\$ln=[0-9]{1,2},r=[0-9]{1,3},p=[0-9]{1,3}\$[A-Za-z0-9+/.]{8,}\$[A-Za-z0-9+/.]{16,}$
                        - pattern: >-
                            ^eyJ(?:hbGciOi|0eXAiOi|raWQiOi|jdHkiOi)[A-Za-z0-9_-]*\.[A-Za-z0-9_-]{2,}\.[A-Za-z0-9_-]*$
              status:
                enum:
                  - complete
                  - partial
                  - pending
                description: >-
                  complete: final; nothing is still running. A lane that failed
                  or missed its 10 s deadline stays listed in
                  incomplete_sources, and confidence is lower. partial: a
                  recommendation exists and at least one lane is still running
                  or did not settle (see incomplete_sources). pending: nothing
                  usable before the deadline; no recommendation yet, poll or
                  wait for the webhook.
              recommendation:
                enum:
                  - allow
                  - step_up
                  - review
                description: Advisory only. The provider decides and enforces.
              confidence:
                enum:
                  - low
                  - medium
                  - high
                  - unavailable
                description: >-
                  Ordinal confidence in the recommendation under the current
                  heuristic policy. It is not a probability.
              risk:
                type: object
                additionalProperties: false
                required:
                  - score
                  - band
                  - recommendation
                  - confidence
                  - policy_version
                  - policy_basis
                  - reasons
                  - coverage
                description: >-
                  the one risk decision for this assessment. score is 0 (safe)
                  to 100 (risky): the sum of the weights of the reasons that
                  fired, clamped to 0..100, from hand-set versioned weights.
                  Every served answer with a recommendation carries it, and
                  there the top-level recommendation equals risk.recommendation.
                  block is true from the workspace's block threshold
                  (block_threshold), off by default. It names no source or
                  provider.
                properties:
                  score:
                    type: integer
                    minimum: 0
                    maximum: 100
                  band:
                    enum:
                      - low
                      - medium
                      - high
                      - critical
                    description: low 0-29, medium 30-59, high 60-84, critical 85-100.
                  recommendation:
                    enum:
                      - allow
                      - step_up
                      - review
                    description: Advisory only. The provider decides and enforces.
                  block:
                    type: boolean
                    description: >-
                      true when the workspace's block threshold is set and score
                      reached it. A provider hook can deny the account creation
                      on it; the provider decides and enforces. It does not
                      change recommendation. It is false while blocking is off,
                      the default, and a body from before the flag existed omits
                      it: read absent as false.
                  block_threshold:
                    type: integer
                    minimum: 1
                    maximum: 100
                    description: >-
                      The block threshold this answer used: block is true
                      exactly when score is at least this value. Absent while
                      blocking is off. NoResponse sets it per workspace on
                      request, at or above the review threshold.
                  confidence:
                    enum:
                      - low
                      - medium
                      - high
                    description: >-
                      How much of the planned evidence answered; it says nothing
                      about risk.
                  policy_version:
                    type: string
                    minLength: 1
                    maxLength: 64
                    pattern: ^[a-z0-9][a-z0-9._-]{0,63}(\+t[1-9][0-9]{0,8})?$
                    description: >-
                      Version of the hand-authored heuristic weights that
                      produced the recommendation, for example 'risk-2026-10.7'.
                      A workspace threshold override adds a +t<N> suffix, e.g.
                      'risk-2026-10.7+t3'.
                    not:
                      description: >-
                        A line feed anywhere, refused with `not` beside every
                        anchored pattern.
                      pattern: \n
                  policy_basis:
                    const: heuristic_unvalidated
                  reasons:
                    type: array
                    maxItems: 32
                    description: >-
                      Every reason that fired, highest weight first. The weights
                      sum to score before clamping.
                    items:
                      type: object
                      additionalProperties: false
                      required:
                        - code
                        - weight
                      properties:
                        code:
                          enum:
                            - no_digital_footprint
                            - voip_number
                            - disposable_email
                            - new_email
                            - spam_reports
                            - fraud_flag
                            - identity_mismatch
                            - country_mismatch
                            - proxy_ip
                            - seen_before
                            - shared_ip
                            - many_recent_accounts
                            - established_accounts
                            - aged_identity
                            - breach_name_match
                            - breach_cooccurrence
                            - breach_name_mismatch
                            - breach_phone_mismatch
                            - recent_password_exposure
                            - credential_list_exposure
                            - abuse_ecosystem_member
                            - no_breach_history
                            - automation_fast_submit
                            - client_clock_skew
                            - bot_or_automation
                            - auth_email_verified
                            - auth_phone_verified
                            - auth_mfa_recent
                            - auth_new_session
                            - auth_new_account
                            - auth_impersonated
                            - context_timezone_mismatch
                            - context_locale_mismatch
                            - context_line_country_mismatch
                            - prior_abuse_link
                            - test_scenario
                            - shared_api_key
                          description: >-
                            A risk reason from the reviewed list.
                            old_breach_history and consistent_identity were
                            replaced by the breach codes (aged_identity,
                            breach_name_match, breach_cooccurrence and the
                            mismatches) and are refused. test_scenario appears
                            only on an assessment made with a test key
                            (nrk_test_), which the deterministic simulator
                            answers: its weight is the scenario the magic email
                            or phone chose, and 0 for any other identifier. A
                            live assessment never carries it. shared_api_key is
                            an account reason, never an assessment one: it
                            appears only in the risk of GET
                            /v1/accounts/{account_id} and the account an
                            assessment carries, when a key your account creation
                            gate issued to the account
                            (issued_credential.sha256) was used from many IP
                            addresses or countries within 24 hours (POST
                            /v1/key_usage/batches).
                        weight:
                          type: integer
                          minimum: -100
                          maximum: 100
                        identifier:
                          enum:
                            - email
                            - username
                            - phone
                            - name
                            - ip
                            - context
                          description: >-
                            The submitted identifier or bounded client context a
                            reason concerns; absent when it concerns the whole
                            assessment. Context is a claimed, untrusted hint and
                            never a device fingerprint.
                  summary:
                    type: object
                    additionalProperties: false
                    properties:
                      phone:
                        type: object
                        additionalProperties: false
                        properties:
                          line_type:
                            enum:
                              - mobile
                              - voip
                              - landline
                              - toll_free
                              - other
                          country:
                            type: string
                            pattern: ^[A-Z]{2}$
                            not:
                              pattern: \n
                          report_count:
                            type: integer
                            minimum: 0
                            description: >-
                              Highest report count any source gave for the
                              number.
                          carrier:
                            type: string
                            minLength: 1
                            maxLength: 128
                            description: >-
                              Carrier-network metadata from privately weighted
                              sources; not upstream provider attribution.
                      email:
                        type: object
                        additionalProperties: false
                        properties:
                          disposable:
                            type: boolean
                          accounts_found:
                            type: integer
                            minimum: 0
                            description: Accounts found for the email.
                          breach:
                            type: object
                            additionalProperties: false
                            required:
                              - found
                            description: >-
                              Breach facts for the email. Replaces the boolean
                              breached.
                            properties:
                              found:
                                type: boolean
                              breach_count:
                                type: integer
                                minimum: 0
                                description: Distinct breach tables the value appears in.
                              first_year:
                                type: integer
                                minimum: 1970
                                maximum: 2100
                                description: Year of the oldest dated table.
                              last_year:
                                type: integer
                                minimum: 1970
                                maximum: 2100
                                description: Year of the newest dated table.
                              exposed:
                                type: array
                                maxItems: 11
                                items:
                                  enum:
                                    - email
                                    - username
                                    - name
                                    - password
                                    - password_hash
                                    - phone
                                    - address
                                    - dob
                                    - ip
                                    - payment
                                    - security_qa
                                  description: >-
                                    A kind of data a breach table held next to
                                    the identifier. password means a plaintext
                                    password was present; NoResponse never
                                    stores it and never says what it was.
                                    password_hash means a hash, salt or token
                                    was present. A value, never: the schema has
                                    no member for one.
                                description: >-
                                  The union of data kinds the matching tables
                                  held, never the values.
                              in_credential_lists:
                                type: boolean
                                description: >-
                                  The value is in a credential_list or
                                  stealer_log table.
                              recent_password_exposure:
                                type: boolean
                                description: >-
                                  A plaintext password sat next to the value in
                                  a table dated two years ago or less, or the
                                  value is in a stealer_log table.
                              truncated:
                                type: boolean
                            allOf:
                              - if:
                                  properties:
                                    truncated:
                                      const: true
                                  required:
                                    - truncated
                                then:
                                  properties:
                                    found:
                                      const: true
                              - if:
                                  properties:
                                    found:
                                      const: false
                                  required:
                                    - found
                                then:
                                  not:
                                    anyOf:
                                      - required:
                                          - first_year
                                      - required:
                                          - last_year
                                      - required:
                                          - exposed
                      username:
                        type: object
                        additionalProperties: false
                        properties:
                          accounts_found:
                            type: integer
                            minimum: 0
                            description: Accounts found for the username.
                          breach:
                            type: object
                            additionalProperties: false
                            required:
                              - found
                            description: Breach facts for the username.
                            properties:
                              found:
                                type: boolean
                              breach_count:
                                type: integer
                                minimum: 0
                                description: Distinct breach tables the value appears in.
                              first_year:
                                type: integer
                                minimum: 1970
                                maximum: 2100
                                description: Year of the oldest dated table.
                              last_year:
                                type: integer
                                minimum: 1970
                                maximum: 2100
                                description: Year of the newest dated table.
                              exposed:
                                type: array
                                maxItems: 11
                                items:
                                  enum:
                                    - email
                                    - username
                                    - name
                                    - password
                                    - password_hash
                                    - phone
                                    - address
                                    - dob
                                    - ip
                                    - payment
                                    - security_qa
                                  description: >-
                                    A kind of data a breach table held next to
                                    the identifier. password means a plaintext
                                    password was present; NoResponse never
                                    stores it and never says what it was.
                                    password_hash means a hash, salt or token
                                    was present. A value, never: the schema has
                                    no member for one.
                                description: >-
                                  The union of data kinds the matching tables
                                  held, never the values.
                              in_credential_lists:
                                type: boolean
                                description: >-
                                  The value is in a credential_list or
                                  stealer_log table.
                              recent_password_exposure:
                                type: boolean
                                description: >-
                                  A plaintext password sat next to the value in
                                  a table dated two years ago or less, or the
                                  value is in a stealer_log table.
                              truncated:
                                type: boolean
                            allOf:
                              - if:
                                  properties:
                                    truncated:
                                      const: true
                                  required:
                                    - truncated
                                then:
                                  properties:
                                    found:
                                      const: true
                              - if:
                                  properties:
                                    found:
                                      const: false
                                  required:
                                    - found
                                then:
                                  not:
                                    anyOf:
                                      - required:
                                          - first_year
                                      - required:
                                          - last_year
                                      - required:
                                          - exposed
                      ip:
                        type: object
                        additionalProperties: false
                        description: >-
                          Facts about the submitted IP from the offline database
                          and this workspace's own recent assessments. Every
                          member is optional; absent makes no claim.
                        properties:
                          country:
                            type: string
                            pattern: ^[A-Z]{2}$
                            not:
                              description: >-
                                A line feed anywhere, refused with `not` beside
                                every anchored pattern.
                              pattern: \n
                            description: ISO 3166-1 alpha-2 country of the address.
                          type:
                            enum:
                              - residential
                              - hosting
                              - vpn
                              - proxy
                              - tor
                              - mobile
                              - unknown
                            description: The address's network type.
                          seen_in_workspace:
                            type: integer
                            minimum: 0
                            description: >-
                              Assessments in this workspace with the same IP in
                              the last 24 hours, this one included. A count
                              only.
                      consistency:
                        type: object
                        additionalProperties: false
                        description: >-
                          Cross-identifier agreement, computed from facts only.
                          Every member is optional; absent makes no claim.
                        properties:
                          name:
                            enum:
                              - match
                              - partial
                              - mismatch
                              - unknown
                            description: >-
                              The submitted name against breach names and
                              caller-ID names.
                          phone:
                            enum:
                              - match
                              - partial
                              - mismatch
                              - unknown
                            description: >-
                              The submitted phone against numbers found next to
                              the email in breach records.
                          ip:
                            enum:
                              - match
                              - partial
                              - mismatch
                              - unknown
                            description: >-
                              The submitted IP against IPs found next to the
                              email or username in breach records.
                          country:
                            enum:
                              - consistent
                              - mismatch
                              - unknown
                            description: >-
                              IP country, phone country, breach countries and
                              policy_context.region together.
                    description: >-
                      A few typed facts per identifier. Every fact is optional:
                      absent means the evidence did not answer and makes no
                      claim, while false or 0 is a definite answer. Lanes that
                      do not exist yet leave their members absent.
                  coverage:
                    type: object
                    additionalProperties: false
                    required:
                      - answered
                      - failed
                      - pending
                    description: Sources by state, never by name.
                    properties:
                      answered:
                        type: integer
                        minimum: 0
                        description: Sources that gave a definite answer.
                      failed:
                        type: integer
                        minimum: 0
                        description: Sources that could not answer.
                      pending:
                        type: integer
                        minimum: 0
                        description: Sources still being asked.
                  details:
                    type: object
                    additionalProperties: false
                    description: >-
                      Detailed view only (response_mode=detailed, which needs
                      the detailed scope); a standard answer never carries it.
                      Merged observations: no provider, source, origin, raw
                      breach record, value or score.
                    properties:
                      phone_names:
                        type: array
                        maxItems: 32
                        items:
                          type: object
                          additionalProperties: false
                          required:
                            - value
                            - seen_by
                          properties:
                            value:
                              type: string
                              minLength: 1
                              maxLength: 128
                            seen_by:
                              type: integer
                              minimum: 1
                      breaches:
                        type: array
                        maxItems: 50
                        items:
                          type: object
                          additionalProperties: false
                          required:
                            - name
                            - kind
                            - matched_on
                          description: >-
                            One breach table that matched, detailed view only.
                            No member carries a record, value, password or hash.
                          properties:
                            name:
                              type: string
                              minLength: 1
                              maxLength: 128
                              not:
                                description: >-
                                  A line feed anywhere, refused with `not`
                                  beside every anchored pattern.
                                pattern: \n
                            domain:
                              type: string
                              minLength: 3
                              maxLength: 253
                              pattern: >-
                                ^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,63}$
                              not:
                                description: >-
                                  A line feed anywhere, refused with `not`
                                  beside every anchored pattern.
                                pattern: \n
                              description: >-
                                The breached site's domain, lower case. Absent
                                when the table has none (a credential list, for
                                example).
                            category:
                              type: string
                              pattern: ^[a-z0-9_]{1,64}$
                              not:
                                description: >-
                                  A line feed anywhere, refused with `not`
                                  beside every anchored pattern.
                                pattern: \n
                              description: >-
                                The table's category from its name, lower case
                                (social, gaming, combolist...).
                            kind:
                              enum:
                                - site_breach
                                - credential_list
                                - stealer_log
                                - scrape
                                - hacking_forum
                                - abuse_service
                                - darkweb_site
                              description: >-
                                Who is in the table: site_breach, a site's own
                                users; credential_list, a combolist or
                                compilation; stealer_log, malware or botnet
                                victims; scrape; hacking_forum, a criminal
                                hacking, cracking or carding community;
                                abuse_service, the customers of DDoS-for-hire,
                                account generators, dump or card shops, darknet
                                markets, stalkerware or breach-lookup services;
                                darkweb_site, an onion site of unknown purpose.
                            year:
                              type: integer
                              minimum: 1970
                              maximum: 2100
                              description: A breach table's date year.
                            month:
                              type: integer
                              minimum: 1
                              maximum: 12
                              description: Absent when only the year is known.
                            matched_on:
                              enum:
                                - email
                                - username
                                - ip
                              description: >-
                                The submitted identifier a breach table matched
                                on. The phone is never a breach selector, and
                                the name is never looked up.
                            exposed:
                              type: array
                              maxItems: 11
                              items:
                                enum:
                                  - email
                                  - username
                                  - name
                                  - password
                                  - password_hash
                                  - phone
                                  - address
                                  - dob
                                  - ip
                                  - payment
                                  - security_qa
                                description: >-
                                  A kind of data a breach table held next to the
                                  identifier. password means a plaintext
                                  password was present; NoResponse never stores
                                  it and never says what it was. password_hash
                                  means a hash, salt or token was present. A
                                  value, never: the schema has no member for
                                  one.
                        description: The matching breach tables, newest first, at most 50.
                      breach_names:
                        type: array
                        maxItems: 32
                        description: >-
                          Names found next to the identifiers in breach records,
                          merged, with the number of distinct tables each was
                          seen in.
                        items:
                          type: object
                          additionalProperties: false
                          required:
                            - value
                            - seen_in
                          properties:
                            value:
                              type: string
                              minLength: 1
                              maxLength: 128
                            seen_in:
                              type: integer
                              minimum: 1
                allOf:
                  - if:
                      properties:
                        block:
                          const: true
                      required:
                        - block
                    then:
                      required:
                        - block_threshold
              signals:
                type: array
                maxItems: 256
                items:
                  type: object
                  additionalProperties: false
                  required:
                    - type
                    - identifier
                    - outcome
                    - source_id
                    - freshness
                  properties:
                    type:
                      type: string
                      minLength: 1
                      maxLength: 64
                      pattern: ^[a-z][a-z0-9_]{0,63}$
                      description: >-
                        The producer emits only registered, active types with a
                        registered identifier kind and outcome.
                      not:
                        description: >-
                          A line feed anywhere, refused with `not` beside every
                          anchored pattern.
                        pattern: \n
                    identifier:
                      enum:
                        - email
                        - username
                        - phone
                        - ip
                      description: >-
                        Which submitted identifier a signal concerns. ip is a
                        selector of breach_exposure only.
                    outcome:
                      enum:
                        - found
                        - not_found
                        - inconclusive
                        - blocked
                        - unavailable
                      description: >-
                        Per-signal outcome. A failure is never not_found: a
                        source that timed out, was blocked or errored reports
                        blocked, unavailable or inconclusive with a reason, and
                        is listed in incomplete_sources.
                    source_id:
                      type: string
                      minLength: 1
                      maxLength: 64
                      pattern: ^[a-z0-9][a-z0-9_.-]{0,63}$
                      description: >-
                        Opaque, workspace-scoped projection of the source that
                        produced a signal. It remains stable for this workspace
                        while the projection key is unchanged, but never
                        identifies an upstream provider, feed, breach table or
                        source record.
                      not:
                        description: >-
                          A line feed anywhere, refused with `not` beside every
                          anchored pattern.
                        pattern: \n
                    reason:
                      enum:
                        - timed_out
                        - rate_limited
                        - blocked
                        - source_error
                        - unavailable
                        - deferred
                        - insufficient_evidence
                      description: >-
                        Why a signal or source did not produce a definite
                        found/not_found. timed_out means the source missed the
                        request deadline; a continuation may still settle it.
                        deferred means the (source, identifier) pair is
                        async-only and was not attempted on the synchronous
                        path; a continuation settles it.
                    evidence_ref:
                      type: string
                      pattern: ^evr_[0-9A-HJKMNP-TV-Z]{26}$
                      description: >-
                        Opaque pointer to evidence NoResponse holds for this
                        signal. It never encodes the evidence itself (no breach
                        value, credential or page body).
                      not:
                        description: >-
                          A line feed anywhere, refused with `not` beside every
                          anchored pattern.
                        pattern: \n
                    observed_at:
                      type: string
                      format: date-time
                      description: When the evidence was first observed.
                    last_checked_at:
                      type: string
                      format: date-time
                      description: When the source was last queried for this identifier.
                    freshness:
                      enum:
                        - fresh
                        - stale
                        - unknown
                      description: >-
                        Freshness class of the evidence behind a signal. unknown
                        whenever no evidence was obtained.
                    enrichment:
                      type: object
                      additionalProperties: false
                      required:
                        - fields
                      properties:
                        fields:
                          type: object
                          minProperties: 1
                          additionalProperties: false
                          properties:
                            phone:
                              type: string
                              maxLength: 8192
                            name:
                              type: string
                              maxLength: 8192
                            carrier:
                              type: string
                              maxLength: 8192
                            line_type:
                              type: string
                              maxLength: 8192
                            entity_type:
                              type: string
                              maxLength: 8192
                            country_code:
                              type: string
                              maxLength: 8192
                            country:
                              type: string
                              maxLength: 8192
                            state:
                              type: string
                              maxLength: 8192
                            city:
                              type: string
                              maxLength: 8192
                            location:
                              type: string
                              maxLength: 8192
                            national_format:
                              type: string
                              maxLength: 8192
                            job_title:
                              type: string
                              maxLength: 8192
                            company_name:
                              type: string
                              maxLength: 8192
                            email:
                              type: string
                              maxLength: 8192
                            website:
                              type: string
                              maxLength: 8192
                            first_call_at:
                              type: string
                              maxLength: 8192
                            last_call_at:
                              type: string
                              maxLength: 8192
                            matched_name:
                              type: string
                              maxLength: 8192
                            alternate_names:
                              type: array
                              maxItems: 1024
                              items:
                                type:
                                  - string
                                  - number
                                  - boolean
                                  - object
                                  - array
                            name_candidates:
                              type: array
                              maxItems: 1024
                              items:
                                type:
                                  - string
                                  - number
                                  - boolean
                                  - object
                                  - array
                            timezones:
                              type: array
                              maxItems: 1024
                              items:
                                type:
                                  - string
                                  - number
                                  - boolean
                                  - object
                                  - array
                            emails:
                              type: array
                              maxItems: 1024
                              items:
                                type:
                                  - string
                                  - number
                                  - boolean
                                  - object
                                  - array
                            websites:
                              type: array
                              maxItems: 1024
                              items:
                                type:
                                  - string
                                  - number
                                  - boolean
                                  - object
                                  - array
                            locations:
                              type: array
                              maxItems: 1024
                              items:
                                type:
                                  - string
                                  - number
                                  - boolean
                                  - object
                                  - array
                            social_profiles:
                              type: array
                              maxItems: 1024
                              items:
                                type:
                                  - string
                                  - number
                                  - boolean
                                  - object
                                  - array
                            report_count:
                              type: integer
                              minimum: 0
                            tag_count:
                              type: integer
                              minimum: 0
                            total_calls:
                              type: integer
                              minimum: 0
                            calls_60_days:
                              type: integer
                              minimum: 0
                            reports_60_days:
                              type: integer
                              minimum: 0
                            searches_60_days:
                              type: integer
                              minimum: 0
                            comment_count:
                              type: integer
                              minimum: 0
                            names_count:
                              type: integer
                              minimum: 0
                            spam_report_count:
                              type: integer
                              minimum: 0
                      description: >-
                        Only present for a found phone signal. Curated facts
                        about the number, not raw upstream documents and never
                        the provider's identity, scores or verdicts; follows
                        normal record retention/deletion.
                  allOf:
                    - if:
                        properties:
                          outcome:
                            const: found
                        required:
                          - outcome
                      then:
                        required:
                          - evidence_ref
                          - observed_at
                          - last_checked_at
                        properties:
                          freshness:
                            enum:
                              - fresh
                              - stale
                        not:
                          required:
                            - reason
                        description: >-
                          A definite presence: evidence exists, so its freshness
                          is known.
                    - if:
                        properties:
                          outcome:
                            const: not_found
                        required:
                          - outcome
                      then:
                        required:
                          - last_checked_at
                        not:
                          anyOf:
                            - required:
                                - reason
                            - required:
                                - evidence_ref
                        description: >-
                          A definite absence. Carries no failure reason: a
                          timeout, block or error is never encoded as not_found.
                    - if:
                        properties:
                          outcome:
                            enum:
                              - inconclusive
                              - blocked
                              - unavailable
                        required:
                          - outcome
                      then:
                        required:
                          - reason
                    - if:
                        properties:
                          outcome:
                            enum:
                              - blocked
                              - unavailable
                        required:
                          - outcome
                      then:
                        properties:
                          freshness:
                            const: unknown
                        not:
                          anyOf:
                            - required:
                                - evidence_ref
                            - required:
                                - observed_at
                        description: >-
                          No evidence was obtained, so there is nothing observed
                          and nothing to reference.
                    - if:
                        required:
                          - enrichment
                      then:
                        properties:
                          identifier:
                            const: phone
                          outcome:
                            const: found
                description: >-
                  Detailed view only (response_mode=detailed, which needs the
                  detailed scope): a standard answer omits signals[], and a
                  detailed one always carries it, possibly empty. At most one
                  signal per (type, source_id, identifier).
              incomplete_sources:
                type: array
                maxItems: 256
                items:
                  type: object
                  additionalProperties: false
                  required:
                    - lane
                    - reason
                  description: >-
                    One lane that did not settle, and why. It names a lane,
                    never a source: the (source, identifier) pairs behind it
                    stay internal. A lane is listed once. A lane that missed the
                    10 s lane deadline is timed_out, never not_found.
                  properties:
                    lane:
                      enum:
                        - accounts
                        - phone
                        - breach
                        - ip
                      description: >-
                        An evidence lane: accounts (account presence for email
                        and username), phone, breach and ip.
                    reason:
                      enum:
                        - timed_out
                        - rate_limited
                        - blocked
                        - source_error
                        - unavailable
                        - deferred
                      description: >-
                        Why a lane did not settle. insufficient_evidence is a
                        settled verdict (an inconclusive signal), never a reason
                        to list a lane as incomplete. deferred means the lane is
                        async-only and still running; a continuation settles it.
                        timed_out means the lane missed its deadline.
                description: >-
                  The lanes that did not settle, each listed once with a reason;
                  never a source. In a detailed view a lane is listed exactly
                  when one of its signals did not settle; a standard view
                  carries no signals to match.
              policy_version:
                type: string
                minLength: 1
                maxLength: 64
                pattern: ^[a-z0-9][a-z0-9._-]{0,63}(\+t[1-9][0-9]{0,8})?$
                description: >-
                  Version of the hand-authored heuristic weights that produced
                  the recommendation, for example 'risk-2026-10.7'. A workspace
                  threshold override adds a +t<N> suffix, e.g.
                  'risk-2026-10.7+t3'.
                not:
                  description: >-
                    A line feed anywhere, refused with `not` beside every
                    anchored pattern.
                  pattern: \n
              policy_basis:
                const: heuristic_unvalidated
              assessment_version:
                type: integer
                minimum: 1
                maximum: 1000
                description: >-
                  Monotonic revision of this assessment. 1 on the synchronous
                  answer; each material change while the assessment is served
                  (an async continuation settling a source, a change of
                  recommendation, confidence or status) increments it. Expiry
                  does not increment it: an expired assessment is gone, not
                  revised, and the expiry webhook carries the last served
                  version.
              created_at:
                type: string
                format: date-time
                description: >-
                  When the assessment was created. Fixed for the life of the
                  assessment: every revision carries the same created_at.
              updated_at:
                type: string
                format: date-time
              expires_at:
                type: string
                format: date-time
                description: >-
                  After this instant the assessment is no longer served: GET
                  /v1/assessments/{assessment_id} answers 404 and it leaves the
                  account history. It is created_at plus the workspace's
                  retention period at creation (default 365 days, at most 365).
                  Fixed per record: a later async revision never extends it, and
                  a new assessment for the same account never renews an older
                  one. If the workspace later shortens retention, the effective
                  expiry becomes created_at + min(retention at creation, current
                  retention).
              assessment_url:
                type: string
                maxLength: 64
                pattern: ^/v1/assessments/asm_[0-9A-HJKMNP-TV-Z]{26}$
                description: >-
                  Server-relative path of the authoritative assessment, GET
                  /v1/assessments/{assessment_id}.
                not:
                  description: >-
                    A line feed anywhere, refused with `not` beside every
                    anchored pattern.
                  pattern: \n
              timing:
                type: object
                additionalProperties: false
                required:
                  - deadline_ms
                  - elapsed_ms
                properties:
                  deadline_ms:
                    type: integer
                    minimum: 50
                    maximum: 3000
                    description: The budget the server applied to the synchronous answer.
                  elapsed_ms:
                    type: integer
                    minimum: 0
                    maximum: 600000
                    description: >-
                      Server time from HTTP ingress to this revision of the
                      assessment.
              auth_context:
                type: object
                additionalProperties: false
                required:
                  - provider
                  - issuer
                  - verified
                  - transport
                description: >-
                  The identity fields of the auth context the assessment was
                  made with, echoed for the workspace's own correlation: the
                  request's auth_context, or the one a hosted provider hook
                  (POST /hooks/{integration_id}) built, with transport
                  provider_hook and its hook_point. Present exactly when the
                  request carried an auth_context, and the same on every
                  revision of the assessment. Values are as the request or the
                  hook sent them; tokens, timestamps, roles and scopes are not
                  echoed, and the echo does not change the score.
                properties:
                  provider:
                    type: string
                    pattern: ^[a-z0-9][a-z0-9._-]{1,31}$
                    description: The provider slug the context named.
                  issuer:
                    type: string
                    maxLength: 256
                    pattern: ^https://[^\s]+$
                    description: The issuer the context named.
                  subject:
                    type: string
                    maxLength: 256
                    pattern: ^[A-Za-z0-9._:@/|+=~-]{1,256}$
                    description: >-
                      The subject the context named; absent when it named none
                      (a pre_registration hook).
                  session_id:
                    type: string
                    maxLength: 256
                    pattern: ^[A-Za-z0-9._:@/|+=~-]{1,256}$
                    description: >-
                      The session identifier the context named, when it named
                      one.
                  organization_id:
                    type: string
                    maxLength: 256
                    pattern: ^[A-Za-z0-9._:@/|+=~-]{1,256}$
                    description: >-
                      The organization identifier the context named, when it
                      named one.
                  verified:
                    type: boolean
                    description: >-
                      The verified flag the context carried. A provider_hook
                      context is always false.
                  transport:
                    type: string
                    enum:
                      - backend
                      - browser
                      - provider_hook
                    description: >-
                      Where the context was derived: backend (also when the
                      request named no transport), browser, or provider_hook for
                      a hosted provider hook.
                  hook_point:
                    type: string
                    enum:
                      - pre_registration
                      - post_registration
                      - pre_login
                      - post_login
                      - token_issuance
                    description: >-
                      The provider event a provider_hook context was sent for;
                      absent for any other transport.
                if:
                  properties:
                    transport:
                      const: provider_hook
                then:
                  required:
                    - hook_point
                  properties:
                    verified:
                      const: false
                else:
                  not:
                    required:
                      - hook_point
            allOf:
              - if:
                  properties:
                    status:
                      const: complete
                  required:
                    - status
                then:
                  required:
                    - recommendation
                  properties:
                    incomplete_sources:
                      items:
                        properties:
                          reason:
                            not:
                              const: deferred
                      description: >-
                        A complete assessment may list lanes that failed or
                        timed out, never one still running.
                  not:
                    required:
                      - assessment_url
              - if:
                  properties:
                    status:
                      const: partial
                  required:
                    - status
                then:
                  required:
                    - recommendation
                  properties:
                    incomplete_sources:
                      minItems: 1
              - if:
                  properties:
                    status:
                      const: pending
                  required:
                    - status
                then:
                  required:
                    - assessment_url
                  not:
                    anyOf:
                      - required:
                          - recommendation
                      - required:
                          - risk
                  properties:
                    confidence:
                      const: unavailable
                    incomplete_sources:
                      minItems: 1
              - if:
                  properties:
                    confidence:
                      const: unavailable
                  required:
                    - confidence
                then:
                  properties:
                    recommendation:
                      const: review
              - if:
                  properties:
                    risk:
                      required:
                        - details
                  required:
                    - risk
                then:
                  required:
                    - signals
        next_cursor:
          type: string
          minLength: 1
          maxLength: 256
          pattern: ^[A-Za-z0-9_-]+$
          description: >-
            Opaque 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.
          not:
            description: >-
              A line feed anywhere, refused with `not` beside every anchored
              pattern.
            pattern: \n
        retention_days:
          type: integer
          minimum: 1
          maximum: 365
          default: 365
          description: >-
            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.
    Problem:
      title: Problem details error
      description: >-
        RFC 9457 problem-details error body returned by every non-2xx API
        response, extended with a stable machine code and request id.
      type: object
      additionalProperties: false
      required:
        - type
        - title
        - status
        - detail
        - code
        - request_id
      properties:
        type:
          type: string
          format: uri-reference
        title:
          type: string
        status:
          type: integer
          minimum: 400
          maximum: 599
        detail:
          type: string
        instance:
          type: string
          format: uri-reference
        code:
          type: string
        request_id:
          type: string
          minLength: 1
        invalid_params:
          type: array
          items:
            type: object
            additionalProperties: false
            required:
              - field
              - reason
            properties:
              field:
                type: string
                minLength: 1
              reason:
                type: string
                minLength: 1
              example:
                type: string
                minLength: 1
  responses:
    AssessmentList:
      description: One page of the account's unexpired assessments.
      headers:
        Cache-Control:
          schema:
            type: string
            const: no-store
          required: true
        X-Request-ID:
          description: The request correlation id, 32 lowercase hexadecimal characters.
          schema:
            type: string
            pattern: ^[0-9a-f]{32}$
            not:
              pattern: \n
          required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/AssessmentList'
          examples:
            page:
              value:
                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
    InvalidHistoryQuery:
      description: >-
        The body does not match the assessment query schema, or the cursor fails
        its MAC, belongs to another workspace or account, or has expired.
      content:
        application/problem+json:
          schema:
            allOf:
              - $ref: '#/components/schemas/Problem'
              - properties:
                  status:
                    const: 400
                  code:
                    enum:
                      - invalid_request
                      - invalid_cursor
      headers:
        Cache-Control:
          schema:
            type: string
            const: no-store
          required: true
        X-Request-ID:
          description: The request correlation id, 32 lowercase hexadecimal characters.
          schema:
            type: string
            pattern: ^[0-9a-f]{32}$
            not:
              pattern: \n
          required: true
    Unauthorized:
      description: No API key, or one that is malformed, unknown, revoked or expired.
      headers:
        Cache-Control:
          schema:
            type: string
            const: no-store
          required: true
        WWW-Authenticate:
          schema:
            type: string
            const: Bearer realm="noresponse-assessments"
          required: true
        X-Request-ID:
          description: The request correlation id, 32 lowercase hexadecimal characters.
          schema:
            type: string
            pattern: ^[0-9a-f]{32}$
            not:
              pattern: \n
          required: true
      content:
        application/problem+json:
          schema:
            allOf:
              - $ref: '#/components/schemas/Problem'
              - properties:
                  status:
                    const: 401
                  code:
                    enum:
                      - unauthorized
    WorkspaceForbidden:
      description: >-
        The API key is valid but may not use this operation: it lacks the
        operation's scope, or its workspace is not entitled or is suspended.
      headers:
        Cache-Control:
          schema:
            type: string
            const: no-store
          required: true
        X-Request-ID:
          description: The request correlation id, 32 lowercase hexadecimal characters.
          schema:
            type: string
            pattern: ^[0-9a-f]{32}$
            not:
              pattern: \n
          required: true
      content:
        application/problem+json:
          schema:
            allOf:
              - $ref: '#/components/schemas/Problem'
              - properties:
                  status:
                    const: 403
                  code:
                    enum:
                      - workspace_forbidden
          examples:
            missingScope:
              value:
                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
    PayloadTooLarge:
      description: The body exceeds 32768 bytes. Refused before parsing.
      headers:
        Cache-Control:
          schema:
            type: string
            const: no-store
          required: true
        X-Request-ID:
          description: The request correlation id, 32 lowercase hexadecimal characters.
          schema:
            type: string
            pattern: ^[0-9a-f]{32}$
            not:
              pattern: \n
          required: true
      content:
        application/problem+json:
          schema:
            allOf:
              - $ref: '#/components/schemas/Problem'
              - properties:
                  status:
                    const: 413
                  code:
                    enum:
                      - payload_too_large
    UnsupportedMediaType:
      description: Content-Type is not application/json.
      headers:
        Cache-Control:
          schema:
            type: string
            const: no-store
          required: true
        X-Request-ID:
          description: The request correlation id, 32 lowercase hexadecimal characters.
          schema:
            type: string
            pattern: ^[0-9a-f]{32}$
            not:
              pattern: \n
          required: true
      content:
        application/problem+json:
          schema:
            allOf:
              - $ref: '#/components/schemas/Problem'
              - properties:
                  status:
                    const: 415
                  code:
                    enum:
                      - unsupported_media_type
    RateLimited:
      description: >-
        The workspace's rate or concurrency limit is exhausted. Retry-After says
        when to retry; the provider applies its own fallback meanwhile.
      headers:
        Cache-Control:
          schema:
            type: string
            const: no-store
          required: true
        Retry-After:
          description: >-
            Whole seconds to wait before polling or retrying. Required on 202,
            429 and 503.
          schema:
            type: string
            pattern: >-
              ^(?:[1-9]|[1-9][0-9]|[1-9][0-9]{2}|[12][0-9]{3}|3[0-5][0-9]{2}|3600)$
            description: Whole decimal seconds; wait at least this long.
          required: true
        X-Request-ID:
          description: The request correlation id, 32 lowercase hexadecimal characters.
          schema:
            type: string
            pattern: ^[0-9a-f]{32}$
            not:
              pattern: \n
          required: true
      content:
        application/problem+json:
          schema:
            allOf:
              - $ref: '#/components/schemas/Problem'
              - properties:
                  status:
                    const: 429
                  code:
                    enum:
                      - rate_limited
          examples:
            limited:
              value:
                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
    ServiceUnavailable:
      description: >-
        The assessment could not be admitted at all (overload, shutdown or a
        dependency down). An assessment that was admitted answers partial or
        pending instead of 503.
      headers:
        Cache-Control:
          schema:
            type: string
            const: no-store
          required: true
        Retry-After:
          description: >-
            Whole seconds to wait before polling or retrying. Required on 202,
            429 and 503.
          schema:
            type: string
            pattern: >-
              ^(?:[1-9]|[1-9][0-9]|[1-9][0-9]{2}|[12][0-9]{3}|3[0-5][0-9]{2}|3600)$
            description: Whole decimal seconds; wait at least this long.
          required: true
        X-Request-ID:
          description: The request correlation id, 32 lowercase hexadecimal characters.
          schema:
            type: string
            pattern: ^[0-9a-f]{32}$
            not:
              pattern: \n
          required: true
      content:
        application/problem+json:
          schema:
            allOf:
              - $ref: '#/components/schemas/Problem'
              - properties:
                  status:
                    const: 503
                  code:
                    enum:
                      - service_unavailable
  securitySchemes:
    tenantBearer:
      type: http
      scheme: bearer
      description: >-
        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.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.