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

# Create an instance

> Create a Conversation instance with a slug, label, and optional config. Organization API keys only.



## OpenAPI

````yaml POST /api/v1/conversation-instances
openapi: 3.1.0
info:
  title: Nexio API
  version: '1.0'
  description: |
    The Nexio public API. Submit runs to configured engines and read their
    results, hold conversations with configured assistants, make authorized
    reads over the planes and families of a connected system of record, and
    manage webhooks and environments.

    Six engine types are registered: comparison, matching, entity_analysis,
    diligence, triage, and opportunity.

    Every route under /api/v1/ requires `Authorization: Bearer <key>`, except
    inbound event ingest (`POST /api/v1/events/ingest/{source_key}`), which
    authenticates each request against its ingest source instead: an
    HMAC-SHA256 signature for `nexio` and `github` sources, or a shared
    authentication code for an `ams360_ons` source. Error
    bodies share the `Error` schema. Call the API from servers only: it sends
    no CORS headers.
  contact:
    email: support@usenexio.com
    url: https://docs.usenexio.com
servers:
  - url: https://api.usenexio.com
    description: >-
      Nexio API. Sandbox or live is chosen by the API key's environment, not by
      the host.
security:
  - BearerAuth: []
tags:
  - name: EngineManagement
    description: >-
      Create, configure, version and manage engines. An engine is a
      configuration of one registered engine type.
  - name: Engines
    description: Engine-scoped endpoints for submitting runs and retrieving results.
  - name: Runs
    description: Retrieve and reconcile submitted runs.
  - name: Records
    description: >-
      Typed, authorized reads over the registered planes and families of a
      connected system of record, and governed writes to the action ledger. The
      generic family read is the core contract.
  - name: Graph
    description: >-
      The organization's data graph: a read-only map of connections and the
      derivations scheduled on them. Node kinds are a closed registry of 16; the
      API serves 14.
  - name: Environments
    description: >-
      The live environment and up to 5 sandbox environments in your org.
      Organization keys only.
  - name: Webhooks
    description: >-
      Manage webhook endpoints that receive terminal run events (run.completed,
      run.failed, run.cancelled) and run corrections (run.superseded).
  - name: Events
    description: >-
      Send inbound events to your organization's event log through an ingest
      source. Source kinds are nexio, github and ams360_ons; a nexio source
      sends event types from your own vocabulary.
  - name: Converse
    description: The raw stateless conversational model turn (caller-owned state).
  - name: Conversations
    description: >-
      Conversation instances (orchestrators over engines) and their managed
      conversations, turns, annotations, evals, and exports.
  - name: Platform
    description: Service health. No key needed.
paths:
  /api/v1/conversation-instances:
    post:
      tags:
        - Conversations
      summary: Create a Conversation instance
      description: |
        Creates a Conversation instance: the configured object of the
        Conversations family, an orchestrator over engines. Its versioned
        config declares the model policy, the `engines` access allowlist
        (`"*"` or an explicit list of engine slugs/ids the instance may read
        through pack tools), tools, components, `data_sources`, limits,
        guardrail policy, eval policy, and retention. Omitting `config`
        creates the instance with the platform default config; a supplied
        config is validated and rejected with per-field issues
        (`invalid_instance_config`). Unknown body fields are rejected.
        Organization API keys only: every scoped key is refused with
        `403 insufficient_capability`.
      operationId: createConversationInstance
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - slug
                - label
              additionalProperties: false
              properties:
                slug:
                  type: string
                  minLength: 3
                  maxLength: 50
                  pattern: ^[a-z0-9][a-z0-9-]*[a-z0-9]$
                label:
                  type: string
                  minLength: 1
                  description: 1 to 100 UTF-8 bytes.
                description:
                  type: string
                  description: At most 500 UTF-8 bytes.
                config:
                  allOf:
                    - $ref: '#/components/schemas/ConversationInstanceConfigWrite'
                  description: Full instance config; defaults applied when omitted.
      responses:
        '201':
          description: The created instance.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConversationInstance'
        '400':
          description: |
            `invalid_request`: the body is not JSON, carries an unknown field,
            is over 1 MiB, or a field fails its rule (slug, label, description).
            `invalid_instance_config`: `config` failed validation; `details`
            lists `[{path, message}]`. A `config` of `null` fails this way; omit
            the field to get the default config.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/OrganizationKeyRequired'
        '409':
          description: >-
            An instance with this slug already exists
            (`instance_slug_conflict`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/AuthUnavailable'
        '504':
          $ref: '#/components/responses/RequestTimeout'
components:
  schemas:
    ConversationInstanceConfigWrite:
      type: object
      additionalProperties: false
      description: |
        Full configured-assistant policy. Every configured assistant uses
        `gpt-6-sol`; the config has no model selector. The retired
        `model_policy.default_model` and `model_policy.deep_model` fields are
        rejected with `invalid_instance_config` on create, update, and
        publish. Other sections define prompts, tools, data sources, access,
        limits, guardrails, evals, and retention.

        A config document is the complete instance config. The twelve
        sections below are required and must not be null; `attachments` is
        optional (absent means the instance takes no attachments). Unknown
        fields at any level are rejected with `invalid_instance_config`, with
        two exceptions kept for old configs: a top-level `data_scope` object
        is read as a one-entry `data_sources` list, and
        `retention.thread_days` is read as `retention.conversation_days`.
        When both spellings are sent, the current one wins, so either
        `data_sources` or `data_scope` must be present.
        See /conversations/configuration for what each field does.
      required:
        - model_policy
        - system_prompt
        - engines
        - tools
        - components
        - access
        - limits
        - guardrails
        - evals
        - retention
        - annotations
      anyOf:
        - required:
            - data_sources
        - required:
            - data_scope
      properties:
        data_scope:
          type: object
          deprecated: true
          description: >-
            Legacy spelling of one `data_sources` entry. Read as a one-entry
            `data_sources` list when `data_sources` is absent, and ignored when
            it is present.
        model_policy:
          type: object
          additionalProperties: false
          required:
            - max_tokens
          properties:
            max_tokens:
              type: integer
              minimum: 0
              maximum: 8192
              description: >-
                Maximum output tokens for each model call in a turn (a turn with
                tool rounds makes several calls; `limits.max_turn_output_tokens`
                bounds the whole turn). 0 selects the platform default of 1024.
        system_prompt:
          type: string
          description: The instance's instructions.
        engines:
          description: >-
            The engine allowlist. The string `*` allows every engine the calling
            principal may see; an array lists engine slugs or IDs. An empty
            array allows none. Array entries must be non-blank and unique.
          oneOf:
            - type: string
              enum:
                - '*'
            - type: array
              uniqueItems: true
              items:
                type: string
                pattern: \S
        tools:
          type: object
          additionalProperties: false
          required:
            - platform_packs
            - client_tools
          properties:
            platform_packs:
              type: array
              uniqueItems: true
              description: Declaring `platform.write` also requires `platform.read`.
              items:
                type: string
                enum:
                  - platform.read
                  - platform.write
            client_tools:
              type: array
              items:
                type: object
                additionalProperties: false
                required:
                  - name
                  - effect
                properties:
                  name:
                    type: string
                    maxLength: 64
                    pattern: ^[a-zA-Z0-9_-]+$
                    description: >-
                      At most 64 characters, unique within the instance, and
                      must not contain `__`.
                  description:
                    type: string
                  input_schema:
                    type:
                      - object
                      - 'null'
                    description: >-
                      JSON Schema for the tool's input. It must be an object
                      that compiles as a JSON Schema. Absent or null means no
                      input schema.
                  effect:
                    type: string
                    enum:
                      - read
                      - write
                      - outbound
                      - destructive
                  requires_confirmation:
                    type: boolean
                    description: >-
                      Always `true` in effect for `write`, `outbound` and
                      `destructive` tools; sending `false` for one of them is
                      rejected.
        components:
          type: array
          description: No two entries may share the same `component` and `version`.
          items:
            type: object
            additionalProperties: false
            required:
              - component
              - version
            properties:
              component:
                type: string
                pattern: \S
                description: Must not be blank.
              version:
                type: integer
                minimum: 1
              props_schema:
                type:
                  - object
                  - 'null'
                description: >-
                  JSON Schema for the component's props. Absent or null means no
                  props schema.
        data_sources:
          type: array
          minItems: 1
          description: |
            At least one grounding surface. Each entry declares exactly one
            form: an inline `sources` list (at least one key, with optional
            `notes`), or a `ref` to a stored data scope with no `sources` and
            no `notes` (blank `notes` is accepted).
          items:
            type: object
            additionalProperties: false
            properties:
              sources:
                type: array
                description: >-
                  Data-access keys, compared after trimming. Each must be one of
                  `engines`, `runs`, `run_payloads`, `metrics`, `catalog`,
                  `connections`, `webhooks`, `feedback`, `team`.
                items:
                  type: string
                  pattern: \S
              notes:
                type: string
              ref:
                type: string
                pattern: \S
            oneOf:
              - required:
                  - ref
                properties:
                  sources:
                    maxItems: 0
                  notes:
                    type: string
                    pattern: ^\s*$
                    description: Absent or blank. A reference entry with notes answers 400.
              - required:
                  - sources
                properties:
                  sources:
                    minItems: 1
                not:
                  required:
                    - ref
        access:
          type: object
          additionalProperties: false
          required:
            - personas
          properties:
            personas:
              type: array
              minItems: 1
              description: At least one persona. `"*"` allows any persona.
              items:
                type: string
                pattern: \S
        limits:
          type: object
          additionalProperties: false
          required:
            - max_tool_rounds
            - max_turn_output_tokens
            - max_history_messages
          properties:
            max_tool_rounds:
              type: integer
              minimum: 1
              maximum: 50
            max_turn_output_tokens:
              type: integer
              minimum: 1
              maximum: 128000
            max_history_messages:
              type: integer
              minimum: 1
              maximum: 100
        guardrails:
          type: object
          additionalProperties: false
          required:
            - refusal_domains
            - escalation_rules
            - output_checks
          properties:
            refusal_domains:
              type: array
              items:
                $ref: '#/components/schemas/ConversationGuardrailRule'
            escalation_rules:
              type: array
              items:
                $ref: '#/components/schemas/ConversationGuardrailRule'
            output_checks:
              type: array
              items:
                $ref: '#/components/schemas/ConversationGuardrailRule'
        evals:
          type: object
          additionalProperties: false
          required:
            - on_regression
          properties:
            on_regression:
              type: string
              enum:
                - block
                - warn
        retention:
          type: object
          additionalProperties: false
          description: Needs `conversation_days` or its legacy spelling `thread_days`.
          anyOf:
            - required:
                - conversation_days
            - required:
                - thread_days
          properties:
            conversation_days:
              type:
                - integer
                - 'null'
              minimum: 1
              description: A positive number of days. Null selects the platform default.
            thread_days:
              type:
                - integer
                - 'null'
              minimum: 1
              deprecated: true
              description: >-
                Legacy spelling of `conversation_days`, read as it when
                `conversation_days` is absent and ignored when it is present.
        annotations:
          type: object
          additionalProperties: false
          required:
            - enabled
          properties:
            enabled:
              type: boolean
              description: >-
                Recorded with the config. The annotation routes do not check it
                today.
        attachments:
          type:
            - object
            - 'null'
          additionalProperties: false
          description: >-
            Optional upload policy. Absent or null means the instance takes no
            attachments.
          properties:
            enabled:
              type:
                - boolean
                - 'null'
              description: Null is read as `false`.
            max_files_per_message:
              type:
                - integer
                - 'null'
              minimum: 0
              maximum: 10
              description: 0 or null selects the default of 5.
            max_bytes_per_file:
              type:
                - integer
                - 'null'
              format: int64
              minimum: 0
              maximum: 39321600
              description: 0 or null selects the platform ceiling of 39,321,600 bytes.
            accepted_media_types:
              type:
                - array
                - 'null'
              description: >-
                Narrows the platform's accepted types. Empty or null means every
                type the platform accepts. Entries must be non-empty, unique and
                on the platform allowlist. A container type (`message/rfc822`,
                `application/zip`) needs `unwrap_archives: true`.
              uniqueItems: true
              items:
                type: string
                minLength: 1
            unwrap_archives:
              type:
                - boolean
                - 'null'
              description: Null is read as `false`.
            retention_days:
              type:
                - integer
                - 'null'
              minimum: 1
              description: >-
                A positive number of days. Null follows the conversation's own
                retention.
    ConversationInstance:
      type: object
      description: >
        A Conversation instance: the configured object of the Conversations

        family, an orchestrator over engines. Its versioned config declares

        the engine access allowlist and data sources alongside model policy,

        tools, guardrails, evals, and retention. `managed_by` records who

        governs the instance (`org` or `platform`); `follows_canonical` marks

        a platform-managed follower whose effective config resolves from the
        platform-managed instance it follows (followers expose no local config).
      required:
        - id
        - slug
        - label
        - description
        - status
        - group_key
        - managed_by
        - follows_canonical
        - created_at
        - updated_at
      properties:
        id:
          type: string
          format: uuid
        slug:
          type: string
        label:
          type: string
        description:
          type: string
        status:
          type: string
          enum:
            - active
            - archived
        group_key:
          type: string
          description: |
            Key of the instance's semantic group within the organization, or
            an empty string when ungrouped. Same semantics as the engine
            `group_key`.
        managed_by:
          type: string
          enum:
            - org
            - platform
        follows_canonical:
          type: boolean
        config:
          $ref: '#/components/schemas/ConversationInstanceConfig'
          description: The live draft config; omitted on listings and for followers.
        config_hash:
          type: string
          description: >-
            Content hash of the live draft config. Omitted on listings and for
            followers, like `config`.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    Error:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: string
          description: >
            Stable snake_case error identifier. Safe to match programmatically.

            New codes are added over time; treat an unknown code by its HTTP
            status.


            Known codes include:

            `invalid_request`, `invalid_input`, `unauthorized`,

            `auth_unavailable`, `rate_limited`, `missing_run_id`,

            `invalid_run_id`, `run_not_found`, `invalid_offerings`,

            `missing_input`, `queue_unreachable`, `engine_not_found`,

            `engine_slug_conflict`, `engine_archived`, `instance_not_found`,

            `instance_slug_conflict`, `instance_archived`,

            `instance_follows_canonical`, `instance_not_published`,

            `invalid_engine_type`, `validation_error`, `webhook_not_found`,

            `webhook_limit_exceeded`, `invalid_url`, `invalid_events`,

            `invalid_description`, `invalid_auth_token`,

            `missing_endpoint_id`, `invalid_endpoint_id`,

            `missing_delivery_id`, `invalid_delivery_id`,

            `delivery_not_found`, `delivery_not_resendable`,

            `insufficient_capability`, `engine_version_required`,

            `engine_version_exact_required`, `engine_version_not_found`,

            `engine_version_invalid_format`,

            `engine_version_draft_requires_sandbox_key`,

            `engine_version_none_released`, `test_scenario_sandbox_only`,

            `test_scenario_forbidden`, `test_scenario_exact_version_required`,

            `test_scenario_version_not_supported`, `invalid_test_scenario`,

            `request_bound_exceeded`, `run_cap_exceeded`,

            `scoped_key_required`, `engine_binding_forbidden`,

            `request_timeout`, `internal_error`, `idempotency_key_reused`,

            `invalid_idempotency_key`, `acting_principal_mismatch`,

            `run_requires_acting_principal`, `environment_slug_invalid`,

            `environment_slug_reserved`, `environment_slug_taken`,

            `environment_name_invalid`, `environment_limit_reached`,

            `environment_live_immutable`, `environment_not_found`,

            `environment_in_use`, `environment_operation_failed`,

            `list_environments_failed`, `engine_release_unservable`,

            `engine_config_hash_inconsistent`,

            `engine_config_hash_unavailable`,

            `engine_config_version_unavailable`,

            `engine_version_resolve_failed`,

            `engine_config_version_load_failed`,

            `engine_version_publish_mismatch`,

            `engine_version_schema_change_requires_major`,

            `engine_config_hash_missing`, `engine_config_changed`,

            `invalid_engine_config`, `cold_start_gate_not_met`,

            `cold_start_gate_failed`, `cold_start_gate_regressed`,

            `cancel_run_failed`, `event_id_reused`, `invalid_event_id`,

            `missing_event_id`, `invalid_event_type`, `invalid_payload`,

            `reason_text_too_long`, `reason_taxonomy_version_unknown`,

            `invalid_rating`, `missing_comment`, `invalid_target`,

            `invalid_time_on_task`, `scoped_annotation_required`,

            `missing_instance_slug`, `invalid_instance_config`,

            `invalid_eval_waiver`, `instance_config_hash_missing`,

            `config_changed_during_publish`,

            `scenario_set_changed_during_publish`,

            `conversation_eval_regressed`,

            `conversation_eval_execution_failed`,

            `conversation_eval_gate_unavailable`, `publish_failed`,

            `conversation_not_found`, `conversation_archived`,

            `invalid_cursor`, `message_not_found`, `invalid_turn_request`,

            `message_too_long`, `invalid_tool_result`, `invalid_confirmation`,

            `invalid_edit_target`, `turn_in_progress`, `pending_turn`,

            `turn_state_conflict`, `confirmation_environment_unpinned`,

            `instance_config_missing`, `instance_config_invalid`,

            `instance_model_unavailable`, `guardrail_evaluation_failed`,

            `guardrail_config_invalid`, `invalid_conversation_history`,

            `streaming_unsupported`, `converse_unavailable`, `provider_error`,

            `provider_unavailable`, `unknown_model`, `too_many_messages`,

            `too_many_tools`, `invalid_max_tokens`, `invalid_message_role`,

            `invalid_message`, `invalid_content_block`, `invalid_tool`,

            `attachments_not_enabled`, `attachments_unavailable`,

            `attachment_rejected`, `attachment_too_large`,

            `attachments_too_large`, `too_many_attachments`,

            `attachment_not_accepted`, `attachment_not_found`,

            `attachment_changed`, `attachment_read_failed`,

            `attachment_member_delete`, `attachment_not_reservable`,

            `invalid_offset`, `invalid_turn_id`, `invalid_comment`,

            `invalid_reason`, `invalid_feedback_key`, `turn_not_found`,

            `annotation_not_found`, `annotation_not_promotable`,

            `invalid_eval_scenario`, `conversation_eval_scenario_not_found`,

            `conversation_eval_scenario_cap`,

            `conversation_eval_run_not_found`,

            `conversation_eval_baseline_not_found`,

            `conversation_eval_unavailable`,

            `instance_version_invalid_format`, `instance_version_not_found`,

            `document_class_not_open`, `presign_failed`,

            `markets_directory_unavailable`, `book_unavailable`,

            `book_connection_ambiguous`, `identity_unmapped`,

            `identity_needs_review`, `identity_suspended`, `identity_stale`,

            `scope_unavailable`, `assertion_invalid`, `assertion_stale`,

            `cursor_filter_mismatch`, `cursor_expired`,

            `action_schema_unknown`, `action_payload_invalid`,

            `action_out_of_scope`, `action_list_too_large`,

            `overlay_read_only`, `unsupported_node_type`,

            `acting_principal_required`, `action_denied`,

            `appetite_read_denied`, `approval_required`,

            `catalog_access_denied`, `catalog_connection_ambiguous`,

            `create_webhook_failed`, `dataset_denied`, `delivery_id_reused`,

            `document_type_not_servable`, `document_unclassified`,

            `egress_manifest_version_mismatch`,

            `egress_manifest_version_required`, `event_type_not_allowed`,

            `event_type_reserved`, `execution_confirm_required`,

            `execution_prohibited`, `ingest_source_disabled`,

            `ingest_source_misconfigured`, `ingest_source_not_found`,

            `invalid_acting_assertion`, `invalid_active`,

            `invalid_credentials`, `invalid_payload_mode`,

            `invalid_signature`, `load_run_failed`, `load_solutions_failed`,

            `load_work_items_failed`, `missing_engine_slug`, `not_found`,

            `object_store_unconfigured`, `provider_not_approved`,

            `resolve_retry_exhausted`, `run_lookup_failed`,

            `service_identity_unknown`, `stale_timestamp`, `surface_denied`,

            `unresolved_market_question`, `unsupported_market_filter`.


            The full list with causes and fixes is at

            https://docs.usenexio.com/reference/errors.
        message:
          type: string
          description: Human-readable error message. May change between versions.
        details:
          description: |
            Optional request-specific details. Request-bound failures use the
            `RequestBoundDetails` object. Validation failures may use an array
            of field issues or another documented object.

            `409 environment_in_use` is the one exception to this envelope: it
            carries a top-level `blockers` object (see `EnvironmentInUseError`)
            instead of `details`.
    ConversationGuardrailRule:
      type: object
      additionalProperties: false
      description: >-
        One guardrail rule. A `refusal_domains` rule needs `description`; an
        `escalation_rules` rule needs `condition` and `route`; an
        `output_checks` rule needs `check`. A field that belongs to another
        family is rejected. `scenarios` lists at least one eval scenario ID that
        tests the rule. Rule ids are non-blank and unique across all three
        families.
      required:
        - id
        - scenarios
      properties:
        id:
          type: string
          pattern: \S
        description:
          type: string
        condition:
          type: string
        check:
          type: string
          description: >-
            A regular expression, matched case-insensitively with `.` matching
            newlines. It is not compiled when the config is saved; a pattern
            that does not compile fails every turn with 500
            `guardrail_config_invalid`.
        route:
          type: string
        scenarios:
          type: array
          minItems: 1
          items:
            type: string
            pattern: \S
    ConversationInstanceConfig:
      type: object
      additionalProperties: true
      description: |
        A live configured-assistant draft returned by the API. Current drafts
        use `gpt-6-sol` and expose no model selector. A draft saved by an
        older deployment can still contain retired model keys until its next
        update; publishing it is rejected with `invalid_instance_config`.
      properties:
        model_policy:
          type: object
          additionalProperties: true
          properties:
            max_tokens:
              type: integer
              minimum: 0
              maximum: 8192
              description: >-
                Maximum output tokens for each model call in a turn (a turn with
                tool rounds makes several calls; `limits.max_turn_output_tokens`
                bounds the whole turn). 0 selects the platform default of 1024.
  responses:
    Unauthorized:
      description: Missing or invalid API key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: unauthorized
            message: Missing or invalid API key
    OrganizationKeyRequired:
      description: >-
        This route accepts organization keys only. Every scoped key gets this
        answer, whatever capabilities it holds.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: insufficient_capability
            message: API key does not have permission for this action
    RateLimited:
      description: Rate limit exceeded. Retry after the window resets.
      headers:
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: rate_limited
            message: Rate limit exceeded
    InternalError:
      description: >-
        An internal failure (`internal_error` or an operation-specific code).
        Include the `X-Request-Id` response header value when you contact
        support.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: internal_error
            message: Internal server error
    AuthUnavailable:
      description: |
        `auth_unavailable`: API key authentication was briefly unavailable
        before the route ran. Transient; retry with backoff.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: auth_unavailable
            message: API key authentication is temporarily unavailable
    RequestTimeout:
      description: >-
        `request_timeout`: the 30 second route timeout expired before the
        handler answered.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: request_timeout
            message: Request timed out
  headers:
    RetryAfter:
      description: Whole seconds to wait before retrying, at least 1.
      schema:
        type: integer
        minimum: 1
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: >
        Send the key as `Authorization: Bearer <key>`. Two kinds of key exist.


        Organization keys are issued in the portal (Settings, then API keys),

        each bound to one environment, shaped `nx_<environment slug>_<64 hex>`.
        They carry

        no capabilities and pass every capability check, with one exception:

        routes under /api/v1/records, /api/v1/engines/{id}/opportunities,

        /api/v1/graph and /api/v1/catalog/documents accept an

        organization key only when its environment is `live`, and refuse any

        other with 403 `scoped_key_required`. Revocation takes effect within 60

        seconds.


        Scoped keys are issued by Nexio on request, shaped

        `nxsk_v1_<24 hex key id>_<43 character secret>`. Each is bound to one

        org, one environment, a set of engines and a set of capabilities. A

        malformed, unknown or revoked `nxsk_` key fails with 401 and is never

        retried as an organization key. Revocation takes effect on the next

        request. A scoped key without a route's capability gets 403

        `insufficient_capability`; a scoped key not bound to the engine gets 403

        `engine_binding_forbidden`.


        Key-grantable capabilities: `engines:read`, `runs:write`, `runs:read`,

        `runs:defensibility:read`, `runs:test`, `catalog:read`,

        `catalog:documents:read`, `webhooks:manage`, `conversations:use`,

        `conversations:export`, `records:read`, `records:opportunities:run`,

        `actions:write`, `actions:read`, `graph:read`, `records:analyze`.


        Routes that accept organization keys only (every scoped key gets 403

        `insufficient_capability`): environment management, engine create,

        update, configuration and publish, and conversation instance

        authoring. Each operation description names the capability a scoped

        key needs.

````