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

# Create a scan

> Launch a new penetration test scan against the specified targets. For retry-safe at-most-once creation, send an Idempotency-Key and reuse the exact same key and request after a lost or ambiguous response. The key is optional for backward compatibility, retained for 24 hours, and cannot be reused with a different actor, operation, or payload. A terminal response is replayed only after the caller still passes current target/resource authorization; revoked access returns a fresh 403/404 without exposing the receipt. Use a new key only for a deliberate new attempt.



## OpenAPI

````yaml /openapi.json post /scans
openapi: 3.1.0
info:
  title: Strix API
  version: 1.0.0
  description: >-
    Public REST API for the Strix autonomous penetration testing platform.
    Manage scans, vulnerabilities, assets, schedules, API tokens, and webhooks.
servers:
  - url: /api/v1
    description: Strix v1 API
security:
  - BearerAuth: []
tags:
  - name: Scans
    description: Launch, monitor, and manage security scans.
  - name: Vulnerabilities
    description: View and triage discovered vulnerabilities.
  - name: Assets
    description: Domains and repositories registered for scanning.
  - name: Schedules
    description: Recurring scan schedules (Pro plan).
  - name: Search
    description: Search across issues, pentests, PR reviews, chats, assets and schedules.
  - name: Tokens
    description: Manage API tokens for authentication.
  - name: Webhooks
    description: Configure webhook subscriptions for real-time event notifications.
  - name: Organization
    description: Workspace configuration for the authenticated organization.
  - name: Members
    description: Manage organization members and roles.
  - name: Invitations
    description: List and revoke organization invitations.
  - name: PR Reviews
    description: Automated security review of pull requests.
  - name: Connectors
    description: Network connectors for scanning internal/private targets.
  - name: Knowledge
    description: >-
      Organization knowledge base: documents, policies, and repo profiles that
      steer the agent.
  - name: Uploads
    description: Upload source/code/documentation archives for whitebox scans.
  - name: Integrations
    description: Third-party integrations (GitLab, Bitbucket, ticketing).
  - name: Chat
    description: Conversational agent sessions.
  - name: Analytics
    description: Aggregate dashboard analytics.
  - name: Test Users
    description: >-
      Per-domain test accounts (with optional MFA) the agent authenticates as
      during scans.
  - name: License
    description: Self-hosted license state, entitlements, and aggregate usage.
  - name: Supply Chain
    description: >-
      SBOM inventory, supply-chain findings, scans, and policy for connected
      repositories.
  - name: CLI
    description: >-
      Device authorization endpoints that let the Strix CLI and coding agents
      sign in and receive an API token.
  - name: Billing
    description: Credit balance, agent-payable top-ups, and automatic top-up settings.
  - name: Workspaces
    description: List, create, and switch workspaces.
  - name: Asset Discovery
    description: >-
      Passive reconnaissance runs that map the organization's external attack
      surface, and the discovered-asset inventory they fill.
  - name: Containers
    description: >-
      Container registries, tracked images, image scans, findings, and SBOM
      components.
  - name: Run Logs
    description: Persisted engine logs and the diagnostics bundle of a self-hosted install.
paths:
  /scans:
    post:
      tags:
        - Scans
      summary: Create a scan
      description: >-
        Launch a new penetration test scan against the specified targets. For
        retry-safe at-most-once creation, send an Idempotency-Key and reuse the
        exact same key and request after a lost or ambiguous response. The key
        is optional for backward compatibility, retained for 24 hours, and
        cannot be reused with a different actor, operation, or payload. A
        terminal response is replayed only after the caller still passes current
        target/resource authorization; revoked access returns a fresh 403/404
        without exposing the receipt. Use a new key only for a deliberate new
        attempt.
      operationId: createScan
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateScanRequest'
      responses:
        '200':
          description: Scan created successfully.
          headers:
            Idempotency-Key:
              $ref: '#/components/headers/IdempotencyKeyResponse'
            Idempotency-Replayed:
              $ref: '#/components/headers/IdempotencyReplayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateScanResponse'
        '400':
          $ref: '#/components/responses/IdempotencyBadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/PaymentRequired'
        '403':
          $ref: '#/components/responses/TierLimitError'
        '409':
          $ref: '#/components/responses/IdempotencyConflictOrInProgress'
        '500':
          $ref: '#/components/responses/IdempotencyInternalOrAbandoned'
        '503':
          $ref: '#/components/responses/IdempotencyOutcomeUnknown'
      security:
        - BearerAuth:
            - scans:write
components:
  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: false
      description: >-
        Opaque caller-generated key for at-most-once billable scan creation; use
        a high-entropy value such as a UUID. Reuse the exact same key only when
        retrying the exact same request. Completed keys are retained for at
        least 24 hours; an unfinished accepted worker receipt may be held longer
        until its downstream queue horizon is safely reconciled. A completed
        failure is terminal for that key. Keyed terminal responses echo
        Idempotency-Key and set Idempotency-Replayed to true only when returning
        a stored outcome.
      schema:
        type: string
        minLength: 1
        maxLength: 200
        pattern: ^[A-Za-z0-9][A-Za-z0-9._:/=-]{0,199}$
  schemas:
    CreateScanRequest:
      type: object
      description: >-
        At least one target (domain_ids, repository_ids, upload_ids, or
        internal_targets) should be provided.
      properties:
        cloud_connection_ids:
          type: array
          items:
            type: string
          description: >-
            Cloud connections this run may read. If you omit this field, the run
            uses the connections that apply to its targets. A connection with
            empty `applies_to_domain_ids` and `applies_to_repository_ids`
            applies to every run. A connection with values in those lists
            applies only to a run that targets one of the listed domains or
            repositories. Send an empty array for no cloud connections.
        concerns:
          description: >-
            Free-text security concerns to prioritize, for example `IDOR on the
            invoices API`.
          type: string
        connector_id:
          description: >-
            ID of a network connector that gives the agent access to a private
            network. Use `listConnectors` to find it.
          type: string
        context:
          description: >-
            Free-text background about the target that helps the agent, for
            example architecture notes or recent changes.
          type: string
        credentials:
          description: >-
            Test accounts the agent logs in with during the scan. Stored
            encrypted and never returned. Prefer saved test users where
            available.
          type: array
          items:
            type: object
            properties:
              username:
                type: string
              password:
                type: string
              notes:
                type: string
              mfa_method:
                type: string
                enum:
                  - none
                  - totp
                  - email_otp
                  - magic_link
                description: Multi-factor method for authenticated scans.
              totp_secret:
                type: string
                description: Base32 TOTP secret, used when mfa_method is `totp`.
              mfa_email:
                type: string
                format: email
                description: >-
                  Inbox to read one-time codes / magic links from, used when
                  mfa_method is `email_otp` or `magic_link`.
              login_url:
                type: string
                format: uri
                description: Login page URL for this credential set.
            required:
              - username
              - password
        domain_ids:
          description: UUIDs of verified domains to test. Use `listDomains` to find them.
          type: array
          items:
            type: string
            format: uuid
        domain_paths:
          type: object
          additionalProperties:
            type: array
            items:
              type: string
          description: Map of domain ID to specific paths to scan.
        engagement_type:
          type: string
          enum:
            - code_review
            - live_test
            - internal_infra
            - compliance_pentest
          description: >-
            Which engagement type this run is. When omitted, source-only scopes
            infer `code_review`, domain scopes infer `live_test`, and internal
            targets infer `internal_infra`.
        focus:
          description: >-
            Free-text areas of the target to test first, for example `the
            checkout flow`.
          type: string
        headers:
          description: >-
            Custom HTTP headers the agent sends on every request, for example an
            API key header. Stored encrypted and never returned.
          type: array
          items:
            type: object
            properties:
              name:
                type: string
              value:
                type: string
              notes:
                type: string
            required:
              - name
              - value
        internal_targets:
          description: >-
            Hosts or URLs inside a private network to test through the
            connector, for example `http://10.0.0.5:8080`.
          type: array
          items:
            type: string
        knowledge_resource_pins:
          type: array
          maxItems: 100
          items:
            $ref: '#/components/schemas/RunKnowledgeResourcePin'
          description: >-
            Provider resources selected for this run in addition to
            organization-wide pins.
        max_budget_usd:
          type: number
          exclusiveMinimum: 0
          maximum: 1000000
          description: >-
            Self-hosted only: stop the pentest gracefully once total LLM spend
            reaches this amount (USD). Omit for no limit.
        budget_policy:
          type: string
          enum:
            - stop
            - pause
          description: >-
            Self-hosted only: what happens when `max_budget_usd` is reached.
            `pause` parks every agent before its next model call until an
            operator resumes the scan with a higher limit or stops it (see `POST
            /scans/{scanId}/budget`); a paused scan waits with no deadline.
            `stop` ends the run at the limit. Defaults to `pause`. Ignored
            without `max_budget_usd`.
        model_config_id:
          type: string
          format: uuid
          description: >-
            Self-hosted only: run the scan with a named model config from
            Settings → LLM Models instead of the default assignment.
        notification_emails:
          type: array
          items:
            type: string
            format: email
          description: >-
            Extra addresses to CC on the completion email. Validated only when
            notify_on_completion is true.
        notify_on_completion:
          type: boolean
          description: Email the scan creator when the pentest finishes.
        org_knowledge_enabled:
          description: >-
            When true, the agent uses the organization knowledge base during the
            scan.
          type: boolean
        repository_branches:
          type: object
          additionalProperties:
            type: string
          description: Map of repository ID to branch name.
        repository_ids:
          description: >-
            UUIDs of connected repositories to test. Use `listRepositories` to
            find them.
          type: array
          items:
            type: string
            format: uuid
        scan_tier:
          type: string
          enum:
            - lite
            - standard
            - ultra
          description: >-
            Scan tier that sets how deep the pentest goes and which model
            quality it uses. The tier changes the credit price (lite ×0.3,
            standard ×0.75, ultra ×1). Defaults to ultra. Not applicable on
            self-hosted deployments, for organizations with raw model selection,
            and for organizations on the Enterprise plan.
        test_user_ids:
          type: array
          items:
            type: string
            format: uuid
          description: >-
            Saved test users to authenticate with. The server resolves their
            secrets. Each test user must cover one of the scan's domains. Use
            `getScanTemplate` to get the IDs of a previous scan.
        title:
          type: string
          maxLength: 120
          description: >-
            Custom scan title. When you set a title, the server does not
            generate one. The server trims the value.
        upload_ids:
          type: array
          items:
            type: string
          description: >-
            Completed upload IDs to attach. A repository upload can be the sole
            target of a code review or provide white-box context for a domain
            pentest.
    CreateScanResponse:
      type: object
      properties:
        scan_id:
          type: string
          format: uuid
        title:
          type: string
        status:
          $ref: '#/components/schemas/ScanStatus'
      required:
        - scan_id
        - title
        - status
    RunKnowledgeResourcePin:
      type: object
      additionalProperties: false
      properties:
        connection_id:
          type: string
          minLength: 1
          description: Organization cloud connection that owns the resource.
        page_id:
          type: string
          minLength: 1
          description: Provider-specific opaque resource identifier.
        label:
          type: string
          minLength: 1
          maxLength: 200
        url:
          type:
            - string
            - 'null'
          format: uri
        guidance:
          type: string
          maxLength: 500
          description: >-
            Optional context: what the resource holds and when Strix should read
            it.
      required:
        - connection_id
        - page_id
        - label
        - url
    ScanStatus:
      type: string
      enum:
        - pending
        - running
        - completed
        - failed
        - cancelled
    ErrorResponse:
      type: object
      properties:
        detail:
          type: string
          description: Human-readable explanation of the error.
        code:
          type: string
          description: >-
            Stable machine-readable error code. `insufficient_scope` means the
            token does not hold the scope that this endpoint requires.
        required_scope:
          $ref: '#/components/schemas/ApiV1Scope'
          description: >-
            Scope that the caller must add to the token. Returned with the
            `insufficient_scope` code.
        docs:
          type: string
          format: uri
          description: Documentation page that explains how to resolve the error.
        hint:
          type: string
          description: >-
            One instruction that resolves the error. For `insufficient_scope`, a
            CLI session gets the `strix cloud session scopes set full` or `strix
            cloud login --scope-profile full` command, and an API token gets the
            settings page where the user creates a token with the scope. When
            the owner's role cannot hold the scope, the hint asks for a role
            change instead.
      required:
        - detail
    InvalidIdempotencyKeyError:
      type: object
      properties:
        detail:
          type: string
        code:
          const: invalid_idempotency_key
        terminal:
          const: true
      required:
        - detail
        - code
        - terminal
    ScanCreditPaywallResponse:
      type: object
      description: >-
        Returned with status 402 when the workspace has no credits for the
        request. No scan or chat turn starts and no credits are consumed. The
        body leads with a credit purchase sized to this request: open
        `checkout_url` when present, otherwise create one with
        `topup_options[0]`.
      properties:
        detail:
          type: string
          description: >-
            Human-readable explanation with the short recovery instruction (how
            many credits to buy, at what price, and where). When `plan_trial` is
            present, the text also mentions the Cloud plan trial as a separate
            offer.
        requiredTier:
          type: string
        code:
          type: string
          enum:
            - scan_credit_limit_reached
            - chat_credit_limit_reached
        reason:
          type: string
          description: >-
            Why automatic top-up did not refill the wallet, when the
            organization has it on. `chat_cap_reached` means the per-chat limit
            stopped the purchase. Lift it for that chat with `PUT
            /chat/{chatId}/auto-topup-limit`. `monthly_cap_reached` means the
            monthly cap stopped it.
          enum:
            - disabled
            - not_needed
            - exceeds_max_topup
            - monthly_cap_reached
            - chat_cap_reached
            - no_customer
            - no_payment_method
            - not_configured
            - charge_in_progress
            - authentication_required
            - charge_failed
        hint:
          type: string
          description: >-
            Short recovery instruction: buy `credits_to_buy` credits at
            `checkout_url` (or the dashboard billing page when no checkout could
            be created), then retry.
        checkout_url:
          type: string
          format: uri
          description: >-
            Hosted checkout for exactly `credits_to_buy` credits, already
            created for this caller. The user pays in the browser and the
            credits are granted when the payment completes. Present only when
            the caller could have created it through `POST /billing/checkout`
            itself (token with `billing:write`, not asset-scoped, admin role for
            personal tokens) and the checkout provider answered.
        credits_to_buy:
          type: integer
          description: >-
            Credits this request is short by, rounded up and clamped to the
            top-up bounds. Falls back to the dashboard default when the request
            could not be estimated.
        price_usd:
          type: number
          description: Price of `credits_to_buy` credits in US dollars.
        topup_url:
          type: string
          format: uri
          description: The dashboard billing page where a user can buy credits.
        topup_options:
          type: array
          description: >-
            Ways to add credits, in the order a headless caller should try them:
            a hosted checkout link for `credits_to_buy` credits first, then the
            opt-in agent-wallet payment, then a balance check.
          items:
            type: object
            properties:
              method:
                type: string
                enum:
                  - GET
                  - POST
              path:
                type: string
                description: The API path, relative to the API root.
              body:
                type: object
                description: >-
                  The JSON request body to send, already filled in with
                  `credits_to_buy`.
                additionalProperties: true
              cli:
                type: string
                description: The matching Strix CLI command.
              description:
                type: string
            required:
              - method
              - path
              - cli
              - description
        plan_trial:
          type: object
          description: >-
            The Cloud plan trial, offered separately from the credit purchase.
            Present only when the workspace has not subscribed before, can still
            start the trial, and checkout would grant this buyer the trial. The
            plan includes PR security reviews and does not include scan credits.
          properties:
            plan:
              type: string
              enum:
                - strix_cloud
              description: The `product` value for `POST /api/v1/billing/checkout`.
            trial_days:
              type: integer
              description: Maximum length of the free trial in days.
            includes:
              type: string
              description: What the plan includes.
            adds_scan_credits:
              type: boolean
              enum:
                - false
              description: >-
                Always false: subscribing does not add scan credits, so it does
                not clear this 402.
            method:
              type: string
              enum:
                - POST
            path:
              type: string
              description: The API path, relative to the API root.
            cli:
              type: string
              description: The matching Strix CLI command.
            url:
              type: string
              format: uri
              description: The dashboard billing page where a user can start the trial.
            description:
              type: string
          required:
            - plan
            - trial_days
            - includes
            - adds_scan_credits
            - method
            - path
            - cli
            - url
            - description
        required_credits:
          type: integer
          description: Total credits the request needs.
        available_credits:
          type: integer
          description: Credits currently in the workspace wallet.
      required:
        - detail
        - code
        - hint
        - credits_to_buy
        - price_usd
        - topup_url
        - topup_options
    TierLimitErrorResponse:
      type: object
      properties:
        detail:
          type: string
        requiredTier:
          type: string
        code:
          type: string
      required:
        - detail
    IdempotencyKeyConflictError:
      type: object
      properties:
        detail:
          type: string
        code:
          const: idempotency_key_conflict
        terminal:
          const: true
      required:
        - detail
        - code
        - terminal
    IdempotencyRequestInProgressError:
      type: object
      properties:
        detail:
          type: string
        code:
          const: idempotency_request_in_progress
        retry_safe:
          const: true
        terminal:
          const: false
      required:
        - detail
        - code
        - retry_safe
        - terminal
    IdempotencyAcceptedResponseUnavailableError:
      type: object
      description: >-
        The scan reached durable acceptance, but the endpoint resource needed to
        reconstruct its original response was removed. The launch is terminal
        and must not be repeated with a new key.
      properties:
        detail:
          type: string
        code:
          const: idempotency_accepted_response_unavailable
        terminal:
          const: true
        scan_id:
          type: string
          format: uuid
      required:
        - detail
        - code
        - terminal
        - scan_id
    IdempotencyAttemptAbandonedError:
      type: object
      description: >-
        The prior attempt did not reach durable acceptance. This key is
        terminal; a deliberate new attempt requires a new key.
      properties:
        detail:
          type: string
        code:
          const: idempotency_attempt_abandoned
        terminal:
          const: true
        scan_id:
          type: string
          format: uuid
      required:
        - detail
        - code
        - terminal
        - scan_id
    IdempotencyOutcomeUnknownError:
      type: object
      properties:
        detail:
          type: string
        code:
          const: idempotency_outcome_unknown
        retry_safe:
          const: true
        terminal:
          const: false
        scan_id:
          type: string
          format: uuid
      required:
        - detail
        - code
        - retry_safe
        - terminal
        - scan_id
    ApiV1Scope:
      type: string
      enum:
        - scans:read
        - scans:write
        - vulnerabilities:read
        - vulnerabilities:write
        - dependencies:read
        - schedules:read
        - schedules:write
        - assets:read
        - assets:write
        - organizations:read
        - organizations:write
        - members:read
        - members:write
        - invitations:read
        - invitations:write
        - webhooks:read
        - webhooks:write
        - tokens:write
        - audit:read
        - pr_reviews:read
        - pr_reviews:write
        - connectors:read
        - connectors:write
        - knowledge:read
        - knowledge:write
        - uploads:write
        - integrations:read
        - integrations:write
        - chat:read
        - chat:write
        - scans:message
        - analytics:read
        - llm:read
        - llm:write
        - test_users:read
        - test_users:write
        - discovery:read
        - discovery:write
        - license:read
        - supply_chain:read
        - supply_chain:write
        - billing:read
        - billing:write
        - containers:read
        - containers:write
        - logs:read
  headers:
    IdempotencyKeyResponse:
      description: Echoes the caller's Idempotency-Key on keyed operation responses.
      schema:
        type: string
    IdempotencyReplayed:
      description: >-
        `true` when this response was replayed from the durable receipt; `false`
        on the original keyed response.
      schema:
        type: string
        enum:
          - 'true'
          - 'false'
    IdempotencyRetryAfter:
      description: >-
        Minimum seconds to wait before retrying the exact request with the same
        Idempotency-Key.
      schema:
        type: integer
        minimum: 1
  responses:
    IdempotencyBadRequest:
      description: Bad request, including a malformed Idempotency-Key.
      headers:
        Idempotency-Key:
          $ref: '#/components/headers/IdempotencyKeyResponse'
        Idempotency-Replayed:
          $ref: '#/components/headers/IdempotencyReplayed'
      content:
        application/json:
          schema:
            oneOf:
              - $ref: '#/components/schemas/ErrorResponse'
              - $ref: '#/components/schemas/InvalidIdempotencyKeyError'
    Unauthorized:
      description: Missing or invalid API token.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    PaymentRequired:
      description: >-
        Out of credits. The body leads with a credit purchase sized to the
        request (`checkout_url` when the caller may buy credits, otherwise the
        API, CLI, or dashboard steps), then retry the request.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ScanCreditPaywallResponse'
    TierLimitError:
      description: Plan or credit limit reached.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/TierLimitErrorResponse'
    IdempotencyConflictOrInProgress:
      description: >-
        The key is bound to a different request (terminal), the exact matching
        request is still in progress (retry-safe), or an accepted launch can no
        longer reconstruct its original endpoint resource (terminal; do not
        launch again).
      headers:
        Idempotency-Key:
          $ref: '#/components/headers/IdempotencyKeyResponse'
        Idempotency-Replayed:
          $ref: '#/components/headers/IdempotencyReplayed'
        Retry-After:
          $ref: '#/components/headers/IdempotencyRetryAfter'
      content:
        application/json:
          schema:
            oneOf:
              - $ref: '#/components/schemas/IdempotencyKeyConflictError'
              - $ref: '#/components/schemas/IdempotencyRequestInProgressError'
              - $ref: >-
                  #/components/schemas/IdempotencyAcceptedResponseUnavailableError
    IdempotencyInternalOrAbandoned:
      description: >-
        Internal server error, or a reconciled attempt that did not reach
        durable acceptance. An `idempotency_attempt_abandoned` response is
        terminal for this key; use a new key only for a deliberate new launch.
      headers:
        Idempotency-Key:
          $ref: '#/components/headers/IdempotencyKeyResponse'
        Idempotency-Replayed:
          $ref: '#/components/headers/IdempotencyReplayed'
      content:
        application/json:
          schema:
            oneOf:
              - $ref: '#/components/schemas/ErrorResponse'
              - $ref: '#/components/schemas/IdempotencyAttemptAbandonedError'
    IdempotencyOutcomeUnknown:
      description: >-
        The outcome is still being reconciled. Retry the exact request with the
        same key after Retry-After; do not generate a new key.
      headers:
        Idempotency-Key:
          $ref: '#/components/headers/IdempotencyKeyResponse'
        Idempotency-Replayed:
          $ref: '#/components/headers/IdempotencyReplayed'
        Retry-After:
          $ref: '#/components/headers/IdempotencyRetryAfter'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/IdempotencyOutcomeUnknownError'
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: >-
        API token obtained from the Tokens endpoint or CLI device login. Include
        as `Authorization: Bearer <token>`. Requests made with a managed CLI
        session also include `X-Strix-Workspace: <organization_id>` to pin a
        process to the workspace it started in; recovery endpoints report the
        current workspace after a concurrent switch.

````

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