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

# Create an API key

> Creates an API key in the signing key's environment and returns its secret once in `key`: store it now. `workspace_id` is your workspace's id, as every key lists it.

The new key can hold only scopes the signing key holds, `management` included (403 `workspace_forbidden` otherwise), and `created_by` is the signing key's prefix. An environment holds at most 100 keys that authenticate (409 `key_limit_reached`). Requires the `management` scope, and acts only in the signing key's own workspace and environment: another workspace and the other environment answer 404.

Not idempotent: a retry after a lost answer creates a second key, which you can list and revoke.



## OpenAPI

````yaml /openapi.json post /v1/workspaces/{workspace_id}/keys
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: >-
      With the `management` scope, read and change your environment's retention,
      decision thresholds, admission and refused sources.
  - 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/workspaces/{workspace_id}/keys:
    post:
      tags:
        - keys
      summary: Create an API key
      description: >-
        Creates an API key in the signing key's environment and returns its
        secret once in `key`: store it now. `workspace_id` is your workspace's
        id, as every key lists it.


        The new key can hold only scopes the signing key holds, `management`
        included (403 `workspace_forbidden` otherwise), and `created_by` is the
        signing key's prefix. An environment holds at most 100 keys that
        authenticate (409 `key_limit_reached`). Requires the `management` scope,
        and acts only in the signing key's own workspace and environment:
        another workspace and the other environment answer 404.


        Not idempotent: a retry after a lost answer creates a second key, which
        you can list and revoke.
      operationId: createKey
      parameters:
        - $ref: '#/components/parameters/WorkspaceId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/KeyRequest'
            examples:
              live:
                value:
                  environment: live
                  scopes:
                    - assess
              test:
                value:
                  environment: test
                  scopes:
                    - assess
                    - history
                    - webhooks
      responses:
        '201':
          $ref: '#/components/responses/KeyCreated'
        '400':
          $ref: '#/components/responses/InvalidControlRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/ControlForbidden'
        '404':
          $ref: '#/components/responses/WorkspaceNotFound'
        '409':
          $ref: '#/components/responses/KeyConflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
      security:
        - tenantBearer: []
      x-codeSamples:
        - lang: curl
          label: cURL
          source: |
            curl --request POST \
              --url 'https://api.noresponse.org/v1/workspaces/tnt_01JA2Z8K6Q4V7W9XBCDEFGHJKM/keys' \
              --header "Authorization: Bearer $NORESPONSE_API_KEY" \
              --header 'Content-Type: application/json' \
              --data '{
              "environment": "live",
              "scopes": [
                "assess"
              ]
            }'
        - 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.keys.create({
                workspaceId: "tnt_01JA2Z8K6Q4V7W9XBCDEFGHJKM",
                body: {
                  environment: "live",
                  scopes: [
                    "assess",
                  ],
                },
              });

              console.log(result);
            }

            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.keys.create(workspace_id="tnt_01JA2Z8K6Q4V7W9XBCDEFGHJKM", environment="live", scopes=[
                    "assess",
                ])

                # Handle response
                print(res)
        - lang: go
          label: Go
          source: "package main\n\nimport(\n\t\"context\"\n\t\"os\"\n\tnoresponse \"github.com/noresponsehq/go/v7\"\n\t\"github.com/noresponsehq/go/v7/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.Keys.Create(ctx, \"tnt_01JA2Z8K6Q4V7W9XBCDEFGHJKM\", components.KeyRequest{\n        Environment: components.KeyEnvironmentLive,\n        Scopes: []components.KeyRequestScope{\n            components.KeyRequestScopeAssess,\n        },\n    })\n    if err != nil {\n        log.Fatal(err)\n    }\n    if res != nil {\n        // handle response\n    }\n}\n"
        - lang: java
          label: Java
          source: |
            package hello.world;

            import java.lang.Exception;
            import java.util.List;
            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.CreateKeyResponse;
            import org.noresponse.models.shared.KeyEnvironment;
            import org.noresponse.models.shared.KeyRequest;
            import org.noresponse.models.shared.KeyRequestScope;

            public class Application {

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

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

                    CreateKeyResponse res = sdk.keys().create()
                            .workspaceId("tnt_01JA2Z8K6Q4V7W9XBCDEFGHJKM")
                            .body(KeyRequest.builder()
                                .environment(KeyEnvironment.LIVE)
                                .scopes(List.of(
                                    KeyRequestScope.ASSESS))
                                .build())
                            .call();

                    if (res.key().isPresent()) {
                        System.out.println(res.key().get());
                    }
                }
            }
        - lang: csharp
          label: C#
          source: >
            using NoResponse;

            using NoResponse.Models.Shared;

            using System;

            using System.Collections.Generic;


            var sdk = new NoResponseClient(apiKey:
            Environment.GetEnvironmentVariable("NORESPONSE_API_KEY"));


            var res = await sdk.Keys.CreateAsync(
                workspaceId: "tnt_01JA2Z8K6Q4V7W9XBCDEFGHJKM",
                body: new KeyRequest() {
                    Environment = KeyEnvironment.Live,
                    Scopes = new List<KeyRequestScope>() {
                        KeyRequestScope.Assess,
                    },
                }
            );


            // handle response
        - 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();

            $body = new Shared\KeyRequest(
                environment: Shared\KeyEnvironment::Live,
                scopes: [
                    Shared\KeyRequestScope::Assess,
                ],
            );

            $response = $sdk->keys->create(
                workspaceId: 'tnt_01JA2Z8K6Q4V7W9XBCDEFGHJKM',
                body: $body

            );

            if ($response->key !== null) {
                // 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.keys.create(workspace_id: 'tnt_01JA2Z8K6Q4V7W9XBCDEFGHJKM',
            body: Models::Shared::KeyRequest.new(
              environment: Models::Shared::KeyEnvironment::LIVE,
              scopes: [
                Models::Shared::KeyRequestScope::ASSESS,
              ]
            ))


            unless res.nil?
              # handle response
            end
components:
  parameters:
    WorkspaceId:
      name: workspace_id
      in: path
      required: true
      schema:
        type: string
        pattern: ^[A-Za-z0-9][A-Za-z0-9_.-]{0,122}$
        description: >-
          The workspace id, which is also its live environment's workspace id;
          the test environment's is the same id with:test appended. A workspace
          created through the API is tnt_ and a 26-character ULID.
      description: >-
        The workspace id. A workspace the acting user is not an active member of
        answers 404, as do another workspace than an API key's own, a malformed
        id and a test environment's id.
  schemas:
    KeyRequest:
      title: API key request
      description: >-
        POST /v1/workspaces/{workspace_id}/keys body. Creates an API key in one
        environment of the workspace with the scopes named, and returns its
        secret once. A live key needs the admin or owner role; a test key needs
        developer or above. An API key with the management scope creates keys in
        its own environment with scopes it holds itself. Each scope may appear
        once.
      type: object
      additionalProperties: false
      required:
        - environment
        - scopes
      properties:
        environment:
          enum:
            - live
            - test
          description: >-
            The environment the key belongs to. A live key assesses with live
            sources; a test key answers from the deterministic simulator.
        scopes:
          type: array
          minItems: 1
          maxItems: 7
          uniqueItems: true
          items:
            enum:
              - assess
              - history
              - delete
              - webhooks
              - detailed
              - integrations
              - management
          description: The key's scopes, each at most once.
    Key:
      title: API key
      description: >-
        One API key of a workspace, as the console shows it. A key belongs to
        exactly one environment. Every other field is safe to show.
      type: object
      additionalProperties: false
      required:
        - id
        - workspace_id
        - environment
        - prefix
        - scopes
        - status
        - created_at
      properties:
        id:
          type: string
          pattern: ^[0-7][0-9A-HJKMNP-TV-Z]{25}$
          description: The key's public id, a 26-character ULID.
        workspace_id:
          type: string
          pattern: ^[A-Za-z0-9][A-Za-z0-9_.-]{0,122}$
          description: >-
            The workspace id, which is also its live environment's workspace id;
            the test environment's is the same id with:test appended. A
            workspace created through the API is tnt_ and a 26-character ULID.
        environment:
          enum:
            - live
            - test
          description: >-
            The environment the key belongs to. A live key assesses with live
            sources; a test key answers from the deterministic simulator.
        prefix:
          type: string
          pattern: ^nrk_(live|test)_[0-7][0-9A-HJKMNP-TV-Z]{25}$
          description: >-
            The public start of the credential, nrk_<environment>_<key id>,
            which identifies the key in logs and secret stores without its
            secret.
        scopes:
          type: array
          minItems: 1
          maxItems: 7
          uniqueItems: true
          items:
            enum:
              - assess
              - history
              - delete
              - webhooks
              - detailed
              - integrations
              - management
          description: The key's scopes, each at most once.
        status:
          enum:
            - active
            - expired
            - revoked
          description: >-
            active: the key authenticates. expired: a rotation's overlap window
            has ended (expires_at). revoked: the key was revoked (revoked_at)
            and answers 401.
        created_at:
          type: string
          format: date-time
        created_by:
          type: string
          minLength: 1
          maxLength: 256
          pattern: ^[!-~]{1,256}$
          description: >-
            The external user id of the member who created the key through the
            console, or the prefix (nrk_<environment>_<key id>) of the
            management key that created it. Absent for a key NoResponse issued
            or a rotation made.
        expires_at:
          type: string
          format: date-time
          description: >-
            When a rotated key stops authenticating (POST /v1/keys/rotate).
            Absent for a key with no end.
        revoked_at:
          type: string
          format: date-time
        revoked_by:
          type: string
          minLength: 1
          maxLength: 256
          pattern: ^[!-~]{1,256}$
          description: >-
            The external user id of the member who revoked the key through the
            console, or the prefix of the management key that revoked it. Absent
            when the key is not revoked or NoResponse revoked it.
        key:
          type: string
          pattern: >-
            ^nrk_(live|test)_[0-7][0-9A-HJKMNP-TV-Z]{25}_[A-Za-z0-9_-]{42}[AEIMQUYcgkosw048]$
          description: >-
            The credential, nrk_<environment>_<key id>_<secret>. Present only in
            the 201 answer that created the key.
      $defs:
        key_id:
          type: string
          pattern: ^[0-7][0-9A-HJKMNP-TV-Z]{25}$
          description: The key's public id, a 26-character ULID.
        key_environment:
          enum:
            - live
            - test
          description: >-
            The environment the key belongs to. A live key assesses with live
            sources; a test key answers from the deterministic simulator.
        key_scopes:
          type: array
          minItems: 1
          maxItems: 7
          uniqueItems: true
          items:
            enum:
              - assess
              - history
              - delete
              - webhooks
              - detailed
              - integrations
              - management
          description: The key's scopes, each at most once.
    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:
    KeyCreated:
      description: The key and its secret, shown here once only.
      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/Key'
          examples:
            key:
              value:
                id: 01JA2ZE4K5M6N7P8Q9R0S1T2V3
                workspace_id: tnt_01JA2Z8K6Q4V7W9XBCDEFGHJKM
                environment: live
                prefix: nrk_live_01JA2ZE4K5M6N7P8Q9R0S1T2V3
                scopes:
                  - assess
                status: active
                created_at: '2026-10-23T09:00:00.000Z'
                created_by: user_2abc
                key: >-
                  nrk_live_01JA2ZE4K5M6N7P8Q9R0S1T2V3_N0tARealSecretJustTheShapeOfOneAAAAAAAAAAAA
    InvalidControlRequest:
      description: >-
        The body breaks its schema, or a console credential named no valid
        NR-Acting-User.
      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
    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
    ControlForbidden:
      description: >-
        workspace_forbidden: an API key without the management scope, or any API
        key on a route other than the key and settings routes. role_forbidden: a
        console credential's acting user is an active member whose role does not
        grant the operation.
      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
                      - role_forbidden
    WorkspaceNotFound:
      description: >-
        No such workspace, member, invite, key or environment for the caller. A
        workspace the acting user is not an active member of answers this too,
        as do another workspace and the other environment to an API key, so no
        answer shows which workspaces exist.
      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
    KeyConflict:
      description: >-
        key_limit_reached: the environment already has 100 keys that
        authenticate; revoke one first.
      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: 409
                  code:
                    enum:
                      - key_limit_reached
    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
    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, the accounts whose risk changed and an account's
        history, records enforcements and erases an account; `detailed` adds the
        detailed view; `webhooks` registers, tests, rotates and deletes webhook
        endpoints; `integrations` registers and manages hosted provider
        integrations; `management` creates, lists and revokes the keys of its
        own environment and reads and changes that environment's settings. 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.