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

# Page through recorded account decisions

> List retained immutable risk decisions for one account with an authenticated cursor.



## OpenAPI

````yaml /openapi.json get /v1/accounts/{account_id}/decisions
openapi: 3.1.0
info:
  title: NoResponse API
  version: '1'
  description: >-
    The NoResponse API assesses an account creation, 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 that your account creation 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 and, with the `management` scope, create, list and
      revoke the keys of its environment.
  - name: settings
    x-displayName: Settings
    x-group: Settings
    description: >-
      Read and preview environment settings, run evaluations, and publish
      reviewed policy with separate permissions.
  - name: lists
    x-displayName: Lists
    x-group: Lists
    description: >-
      Preview, allow or block accounts that use an email or email domain.
      Publishing changes requires policy authority.
  - name: integrations
    x-displayName: Integrations
    x-group: Integrations
    description: >-
      Hosted endpoints that answer your WorkOS, Auth0 or Supabase 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.
  - name: workspaces
    x-displayName: Workspaces
    x-group: Workspaces
    description: >-
      Manage non-owner team access, read usage and audit events, configure audit
      streams, and export retained account or audit data.
  - name: requests
    x-displayName: Request diagnostics
    x-group: Request diagnostics
    description: Search retained request attempts and summarize their status and latency.
  - name: groups
    x-displayName: Groups
    x-group: Groups
    description: >-
      Screen a group's people: create the group, upload its list of people,
      start screenings and record a decision on each person.
  - name: reviews
    x-displayName: Reviews
    x-group: Reviews
    description: >-
      Investigate accounts with assignments, comments, linked evidence, saved
      filters and recorded resolutions.
paths:
  /v1/accounts/{account_id}/decisions:
    get:
      tags:
        - accounts
      summary: Page through recorded account decisions
      description: >-
        List retained immutable risk decisions for one account with an
        authenticated cursor.
      operationId: listAccountDecisions
      parameters:
        - $ref: '#/components/parameters/AccountId'
        - name: limit
          in: query
          required: false
          description: Items per page.
          schema:
            type: integer
            minimum: 1
            maximum: 50
            default: 20
        - name: cursor
          in: query
          required: false
          description: next_cursor from the previous page, unchanged.
          schema:
            type: string
            minLength: 1
            maxLength: 256
            pattern: ^[A-Za-z0-9_-]+$
            not:
              pattern: \n
      responses:
        '200':
          $ref: '#/components/responses/AccountDecisionList'
        '400':
          $ref: '#/components/responses/InvalidAccountRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/WorkspaceForbidden'
        '404':
          $ref: '#/components/responses/AccountNotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
      security:
        - tenantBearer: []
      x-codeSamples:
        - lang: curl
          label: cURL
          source: |
            curl --request GET \
              --url 'https://api.noresponse.org/v1/accounts/acct_7f3a9c/decisions?limit=20' \
              --header "Authorization: Bearer $NORESPONSE_API_KEY"
        - 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.accounts.listDecisions({
                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.accounts.list_decisions(account_id="acct_7f3a9c", limit=20)

                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/v12\"\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.Accounts.ListDecisions(ctx, \"acct_7f3a9c\", noresponse.Pointer[int64](20), nil)\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.ListAccountDecisionsResponse;


            public class Application {

                public static void main(String[] args) throws Exception {

                    NoResponse sdk = NoResponse.builder()
                            .apiKey(System.getenv().getOrDefault("NORESPONSE_API_KEY", ""))
                        .build();


                    sdk.accounts().listDecisions()
                            .accountId("acct_7f3a9c")
                            .limit(20L)
                            .callAsStream()
                            .forEach((ListAccountDecisionsResponse 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"));


            ListAccountDecisionsResponse? res = await
            sdk.Accounts.ListDecisionsAsync(
                accountId: "acct_7f3a9c",
                limit: 20
            );


            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;

            $sdk = NoResponse\NoResponseClient::builder()
                ->setSecurity(
                    getenv('NORESPONSE_API_KEY') ?: ''
                )
                ->build();



            $responses = $sdk->accounts->listDecisions(
                accountId: 'acct_7f3a9c',
                limit: 20

            );


            foreach ($responses as $response) {
                $result = $response->result;
                // handle response
            }
        - lang: ruby
          label: Ruby
          source: >
            require 'noresponse'


            Models = ::NoResponse::Models

            s = ::NoResponse::NoResponseClient.new(
              api_key: ENV.fetch('NORESPONSE_API_KEY', '')
            )

            res = s.accounts.list_decisions(account_id: 'acct_7f3a9c', limit:
            20)


            unless res.nil?
              # handle response
            end
components:
  parameters:
    AccountId:
      name: account_id
      in: path
      required: true
      schema:
        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}, its /assessments and its /links. 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 NUL or line feed anywhere, refused with not beside anchored
                patterns. The parser refuses NUL in every request string. This
                guard also closes engines where $ accepts a final line feed.
              pattern: '[\x00\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_-]*$
      description: >-
        The account_id the workspace sends with its assessments, as one path
        segment (percent-encode '|' and ':' if the client requires it). A value
        that does not match the account_id shape answers 400 invalid_request.
  responses:
    AccountDecisionList:
      description: Page through recorded account decisions.
      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/AccountDecisionList'
          examples:
            page:
              value:
                account_id: acct_7f3a9c
                items:
                  - account:
                      schema_version: '1'
                      id: acct_7f3a9c
                      risk:
                        score: 35
                        decision: step_up
                        reasons:
                          - code: proxy_ip
                            direction: raises
                            impact: high
                            identifier: ip
                          - code: new_email
                            direction: raises
                            impact: low
                            identifier: email
                      decisions_by_flow:
                        account_creation: step_up
                        login: step_up
                        purchase: step_up
                      assessment_id: asm_01JA2Z8K6Q4V7W9XBCDEFGHJKM
                      updated_at: '2026-10-14T09:00:00.412Z'
                      risk_version: 3
                    assessment_version: 1
                    policy_version: policy-1
                    overlay_version: 1
                    changed_at: '2026-10-14T09:00:00.412Z'
    InvalidAccountRequest:
      description: >-
        account_id does not match its shape, a query parameter is unknown,
        repeated or out of range, or the cursor fails its MAC, belongs to
        another workspace or account, or has expired. invalid_params names the
        offending parameters, never their values.
      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: 400
                  code:
                    enum:
                      - invalid_request
                      - invalid_cursor
    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
    AccountNotFound:
      description: >-
        The calling workspace has no unexpired assessment with a decision for
        this account_id.
      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: 404
                  code:
                    enum:
                      - not_found
    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
  schemas:
    AccountDecisionList:
      title: Account decision history
      type: object
      additionalProperties: false
      required:
        - account_id
        - items
      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}, its /assessments
            and its /links. 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 NUL or line feed anywhere, refused with not beside anchored
                  patterns. The parser refuses NUL in every request string. This
                  guard also closes engines where $ accepts a final line feed.
                pattern: '[\x00\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: Historical account decision
            description: >-
              The account decision at one recorded risk_version. Its stored
              assessment revision and frozen account inputs are rendered under
              the named immutable overlay version. Later evidence, feedback and
              policy changes never change this decision. Versions predating
              decision-history capture, or whose base assessment has expired or
              been deleted, return 404 rather than reconstructed guesses.
            type: object
            additionalProperties: false
            required:
              - account
              - assessment_version
              - policy_version
              - overlay_version
              - changed_at
            properties:
              account:
                title: Account
                description: >-
                  Body of the 200 answer to GET /v1/accounts/{account_id}: the
                  one current risk of one of the calling workspace's accounts.
                  It is the risk of the account's latest assessment that has a
                  decision (status complete or partial), by created_at and then
                  assessment_id, scored exactly as GET
                  /v1/assessments/{assessment_id} scores that assessment, plus
                  the account's own reason shared_api_key when a key issued to
                  the account was used from many IP addresses or countries (POST
                  /v1/keys/usage). Its assessments are the account's history
                  (GET /v1/accounts/{account_id}/assessments).
                type: object
                additionalProperties: false
                required:
                  - schema_version
                  - id
                  - risk
                  - decisions_by_flow
                  - assessment_id
                  - updated_at
                  - risk_version
                properties:
                  schema_version:
                    const: '1'
                    description: Version of the body shape.
                  id:
                    type: string
                    minLength: 1
                    maxLength: 128
                    pattern: ^[A-Za-z0-9][A-Za-z0-9._:|-]{0,127}$
                    description: The account_id the workspace sends with its assessments.
                    not:
                      description: refused_text plus secret_encoded, for account_id.
                      anyOf:
                        - description: >-
                            A NUL or line feed anywhere, refused with not beside
                            anchored patterns. The parser refuses NUL in every
                            request string. This guard also closes engines where
                            $ accepts a final line feed.
                          pattern: '[\x00\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_-]*$
                  risk:
                    type: object
                    additionalProperties: false
                    required:
                      - score
                      - decision
                      - reasons
                    properties:
                      score:
                        type: integer
                        minimum: 0
                        maximum: 100
                        description: >-
                          0 (safe) to 100 (risky), as risk.score of the
                          assessment.
                      decision:
                        enum:
                          - allow
                          - step_up
                          - review
                          - block
                          - held
                        description: >-
                          The decision for the flow of the assessment this
                          account is served with: on GET
                          /v1/accounts/{account_id}, the flow of the current
                          assessment; inside an assessment, that assessment's
                          flow.
                      reasons:
                        type: array
                        maxItems: 32
                        description: >-
                          Every reason that fired: risk-raising reasons first,
                          then neutral, then risk-lowering, each strongest
                          impact band first and then by code. The policy's
                          numeric weights are kept private, so a reason carries
                          only its direction and impact band.
                        items:
                          type: object
                          additionalProperties: false
                          description: >-
                            One reason that fired. direction is whether it
                            raises or lowers the score, or is neutral
                            (informational, it moves nothing). impact is a
                            coarse band of how much it moves the score: none for
                            a neutral reason, otherwise low, medium or high.
                          required:
                            - code
                            - direction
                            - impact
                          properties:
                            code:
                              enum:
                                - no_digital_footprint
                                - voip_number
                                - disposable_email
                                - new_email
                                - no_email_matches
                                - 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
                                - list_match
                                - young_email_domain
                                - email_domain_no_mx
                                - email_domain_nonexistent
                                - google_account_missing
                                - google_empty_account
                                - google_active_profile
                                - google_aged_account
                                - google_name_match
                                - google_name_mismatch
                                - google_country_match
                                - google_country_mismatch
                                - forum_sanctioned
                                - prior_payment_abuse
                                - ip_history_match
                                - identity_attribute_conflict
                                - impossible_identity_age
                                - breach_shared_ip
                                - nationality_mismatch
                                - minor_identity
                                - reported_account_abuse
                                - breach_city_match
                                - breach_city_mismatch
                              description: >-
                                A risk reason from the reviewed list. new_email
                                is retained only for historical decisions: it
                                never measured email age and is no longer
                                emitted. no_email_matches is neutral and
                                requires explicit, complete no-match answers
                                from supported account and breach searches for
                                the email; unsupported, failed, partial or
                                running searches cannot establish it.
                                no_breach_history is neutral and records only a
                                complete email breach search with no matches,
                                independently of account coverage.
                                no_digital_footprint keeps its existing weight
                                for confirmed absence across the searched
                                account and breach families; no extra age proxy
                                is added. 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. young_email_domain, email_domain_no_mx
                                and email_domain_nonexistent describe the
                                email's domain (the deferred RDAP registration
                                age and the request-time mail answer:
                                email_domain_no_mx means a null MX, or neither
                                an MX nor an address record); a lookup that
                                failed writes nothing and fires none of them.
                                forum_sanctioned and prior_payment_abuse
                                describe the conduct the email's or username's
                                breach rows record: a forum ban, warning or
                                infraction, and recorded chargebacks or many
                                declined payments. ip_history_match means the
                                signup IP is one the email's or username's own
                                breach rows used, from a typed address that is
                                no proxy or hosting network, once the address's
                                own breach search found fewer than twenty
                                people. identity_attribute_conflict means
                                independent breach records and profiles disagree
                                on the birth date, gender or nationality, or the
                                breach gender differs from the submitted first
                                name's usual one; impossible_identity_age means
                                the email address appears in breach records from
                                before, or soon after, the birth date they
                                report, or that birth date is 110 or more years
                                ago; nationality_mismatch means the breach
                                nationality's country differs from three or more
                                of the IP, phone, timezone and locale countries;
                                minor_identity flags a breach birth date under
                                18 years ago. breach_city_match means two or
                                more breach tables give the city of the IP, from
                                a typed address that is no proxy, hosting or
                                mobile network. breach_city_mismatch is neutral:
                                the breach records give one city and the IP
                                country, and the IP is in a different city,
                                under the same conditions; a missing IP city or
                                a name that cannot be compared makes no claim.
                                breach_shared_ip means the signup IP's own
                                breach records hold five or more different
                                people besides the signup, from a typed address
                                that is no proxy or hosting network; one
                                record's emails and usernames are one person.
                                Mobile carrier addresses are not yet detected.
                                test_scenario appears only on an assessment made
                                with a test key (nrk_test_), which the
                                deterministic simulator answers: its impact is
                                the scenario the magic email or phone chose, and
                                none 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/keys/usage). list_match is an account reason
                                too: one of the account's admitted assessments
                                sent an email, or an email of a domain, on the
                                environment's list (GET
                                /v1/workspaces/{workspace_id}/lists/{environment}).
                                It names the entry in list_entry_id; it raises
                                for a block entry and lowers for an allow entry,
                                and it decides the account whatever the score,
                                which it leaves unchanged.
                                reported_account_abuse is an account-only,
                                tenant-local assertion from a known abuse
                                outcome; it is not independently corroborated
                                evidence and is withdrawn by a correction of
                                that report.
                            direction:
                              enum:
                                - raises
                                - lowers
                                - neutral
                            impact:
                              enum:
                                - none
                                - low
                                - medium
                                - high
                            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.
                            list_entry_id:
                              type: string
                              pattern: ^lst_[0-7][0-9A-HJKMNP-TV-Z]{25}$
                              description: >-
                                The list entry a list_match reason applied. No
                                other reason carries it.
                  decisions_by_flow:
                    type: object
                    additionalProperties: false
                    required:
                      - account_creation
                      - login
                      - purchase
                    description: >-
                      The decision for each flow: the account's score under that
                      flow's thresholds. A flow the workspace has not set uses
                      its account_creation thresholds, so the flows differ only
                      where it set them. The flow of the current assessment is
                      held while that flow's admission is held and the
                      assessment's investigation has not completed.
                    properties:
                      account_creation:
                        enum:
                          - allow
                          - step_up
                          - review
                          - block
                          - held
                        description: >-
                          block when the score reached the workspace's block
                          threshold (risk.block of the assessment), otherwise
                          the assessment's recommendation. held only for a flow
                          whose admission is held (settings
                          flows.<flow>.admission), when the account's current
                          assessment was made for that flow and its
                          investigation has not completed (status partial): the
                          final decision arrives as account.risk_changed when
                          the investigation completes, decided by its score, or
                          when the hold's deadline (hold_seconds after the
                          assessment was created) passes first, as the flow's
                          on_expiry action or the decision the evidence so far
                          gives, whichever is stricter. Advisory: the workspace
                          decides and enforces.
                      login:
                        enum:
                          - allow
                          - step_up
                          - review
                          - block
                          - held
                        description: >-
                          block when the score reached the workspace's block
                          threshold (risk.block of the assessment), otherwise
                          the assessment's recommendation. held only for a flow
                          whose admission is held (settings
                          flows.<flow>.admission), when the account's current
                          assessment was made for that flow and its
                          investigation has not completed (status partial): the
                          final decision arrives as account.risk_changed when
                          the investigation completes, decided by its score, or
                          when the hold's deadline (hold_seconds after the
                          assessment was created) passes first, as the flow's
                          on_expiry action or the decision the evidence so far
                          gives, whichever is stricter. Advisory: the workspace
                          decides and enforces.
                      purchase:
                        enum:
                          - allow
                          - step_up
                          - review
                          - block
                          - held
                        description: >-
                          block when the score reached the workspace's block
                          threshold (risk.block of the assessment), otherwise
                          the assessment's recommendation. held only for a flow
                          whose admission is held (settings
                          flows.<flow>.admission), when the account's current
                          assessment was made for that flow and its
                          investigation has not completed (status partial): the
                          final decision arrives as account.risk_changed when
                          the investigation completes, decided by its score, or
                          when the hold's deadline (hold_seconds after the
                          assessment was created) passes first, as the flow's
                          on_expiry action or the decision the evidence so far
                          gives, whichever is stricter. Advisory: the workspace
                          decides and enforces.
                  assessment_id:
                    type: string
                    pattern: ^asm_[0-9A-HJKMNP-TV-Z]{26}$
                    description: The assessment the current risk comes from.
                    not:
                      description: >-
                        A NUL or line feed anywhere, refused with not beside
                        anchored patterns. The parser refuses NUL in every
                        request string. This guard also closes engines where $
                        accepts a final line feed.
                      pattern: '[\x00\n]'
                  updated_at:
                    type: string
                    format: date-time
                    description: updated_at of that assessment's latest revision.
                  risk_version:
                    type: integer
                    minimum: 1
                    description: >-
                      The version of the account's current risk. It increases
                      every time the account's current risk or decisions_by_flow
                      changes, and does not decrease. Of two copies of an
                      account, the one with the higher risk_version is newer.
                      account.risk_changed carries the risk_version that its
                      change made.
                $defs:
                  account_decision:
                    enum:
                      - allow
                      - step_up
                      - review
                      - block
                      - held
                    description: >-
                      block when the score reached the workspace's block
                      threshold (risk.block of the assessment), otherwise the
                      assessment's recommendation. held only for a flow whose
                      admission is held (settings flows.<flow>.admission), when
                      the account's current assessment was made for that flow
                      and its investigation has not completed (status partial):
                      the final decision arrives as account.risk_changed when
                      the investigation completes, decided by its score, or when
                      the hold's deadline (hold_seconds after the assessment was
                      created) passes first, as the flow's on_expiry action or
                      the decision the evidence so far gives, whichever is
                      stricter. Advisory: the workspace decides and enforces.
              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.
              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 policy 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 NUL or line feed anywhere, refused with not beside
                    anchored patterns. The parser refuses NUL in every request
                    string. This guard also closes engines where $ accepts a
                    final line feed.
                  pattern: '[\x00\n]'
              overlay_version:
                type: integer
                const: 1
              changed_at:
                type: string
                format: date-time
              feedback_outcome_id:
                type: string
                pattern: ^out_[0-9A-HJKMNP-TV-Z]{26}$
                description: >-
                  Opaque, server-assigned id of one recorded outcome: 'out_' and
                  a 26-character Crockford base32 ULID. Unique within the
                  workspace.
                not:
                  description: >-
                    A NUL or line feed anywhere, refused with not beside
                    anchored patterns. The parser refuses NUL in every request
                    string. This guard also closes engines where $ accepts a
                    final line feed.
                  pattern: '[\x00\n]'
        next_cursor:
          type: string
          minLength: 1
          maxLength: 256
          pattern: ^[A-Za-z0-9_-]+$
          description: >-
            Opaque, expiring cursor bound to the workspace, environment, account
            and history kind. Absent at the end.
    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
  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. Account, audit and usage data stay within the key's
        environment. Dedicated team scopes apply across the workspace.


        `assess` creates and reads assessments, records outcomes and reports key
        usage. `investigate` reads accounts, assessment history and request
        diagnostics without export or enforcement access. The legacy `history`
        scope also permits account exports, submitted identifiers and
        enforcement reports. `delete` permits account and assessment deletion.


        `evidence` or `detailed` adds detailed merged evidence and submitted
        identifiers where the operation permits them. Neither grants access to
        the underlying resource alone. `exports` permits exports with the
        underlying account or audit scope. `audit` reads audit events and
        `usage` reads usage. `audit_manage` manages audit streams and retention,
        and includes audit-read and export authority.


        `webhooks` manages webhook endpoints. `integrations` manages hosted
        auth-provider integrations. `management` manages keys, settings, lists,
        reviews and policy evaluations in the key's environment. New keys cannot
        exceed the issuer's effective permissions.


        `settings` reads configuration, previews policy and list changes, runs
        evaluations and changes retention. Publishing decision policy or
        changing lists requires `settings` and `policy_publish` together, or the
        legacy `management` scope.


        `groups` creates and reads groups, adds people, starts and cancels
        screenings and records decisions on people, in the key's environment.


        `members` reads the workspace directory. `members_manage` also
        administers non-owner members and invitations. These scopes require a
        live key issued by a current owner with access to both environments.
        They grant access across the workspace. `management` does not grant team
        access. API keys cannot change owners or accept invitations.


        A missing, unknown, revoked or expired key answers 401. A valid key
        without a required scope answers 403.

````

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