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

# Update API key scopes

> Admin or owner with current membership. Only scopes may be changed. Rotation preserves scopes exactly.



## OpenAPI

````yaml /openapi.yaml patch /mgmt/v1/api-keys/{id}
openapi: 3.1.0
info:
  title: CarHub API
  version: '2026-10-04'
  summary: >-
    Automotive AI as a service — 23 inference endpoints, one asynchronous
    contract.
  description: >
    CarHub exposes automotive computer-vision and pricing models as plain HTTP
    endpoints.

    Every model is priced and rate-limited on its own — nothing requires
    adopting the rest.


    ## Two API surfaces


    | Surface | Prefix | Authentication |

    |---|---|---|

    | Inference (the product) | `/v1/…` | API key — `Authorization: Bearer
    chk_live_…` / `chk_stg_…` / `chk_test_…` |

    | Management (the dashboard) | `/mgmt/v1/…` | Short-lived JWT —
    `Authorization: Bearer <jwt>` |


    ## Everything is a job


    Every inference endpoint is `POST` and **asynchronous by default**: it
    answers `202` with a

    [`Job`](#/components/schemas/Job) in status `queued`. Collect the result by
    polling

    `GET /v1/jobs/{id}` or by subscribing to `job.succeeded`, `job.partial`, and
    `job.failed` webhooks.


    Fast endpoints additionally accept `?wait=true`, which holds the connection
    until the job

    settles (30 s ceiling) and answers `200` with the same `Job` object in
    status `succeeded`.

    Video, 360 and bundle endpoints reject `wait` with `400 wait_not_supported`
    — their work

    outlives any reasonable request timeout.


    ## Inputs


    Every endpoint accepts two request encodings for the same operation:


    * `multipart/form-data` — the binary directly in the request (`image`,
    `audio`, `video` or
      `images[]` depending on the endpoint). Simplest path, capped at 10 MB per file.
    * `application/json` — `{"input_ref": "upl_…"}` (or `input_refs` for
    multi-asset endpoints)
      referencing an upload created through `POST /v1/uploads`. Required for videos and batches.

    Endpoint parameters are identical in both encodings.


    ## Idempotency


    Send `Idempotency-Key` on any `POST`. A replayed key returns the original
    response and never

    bills twice; reusing a key with a different payload is a `409
    idempotency_key_reuse`.


    ## Test mode


    Keys prefixed `chk_test_` run the entire pipeline — auth, rate limiting, job
    lifecycle,

    ledger, signed webhooks — against a fixture backend instead of a GPU. Test
    jobs carry

    `livemode: false` and draw on a separate, freely rechargeable test credit
    balance.

    Drive the fixture backend per request with `X-Carhub-Test-Scenario`.
  termsOfService: https://trycarhub.com/terms
  contact:
    name: CarHub API support
    url: https://docs.trycarhub.com
    email: api@trycarhub.com
  license:
    name: Proprietary
    identifier: LicenseRef-CarHub-Commercial
servers:
  - url: https://api.trycarhub.com
    description: Production (EU)
security:
  - ApiKeyAuth: []
tags:
  - name: A — Understand the vehicle
    description: >-
      Identity, attributes and a clean capture — everything downstream reads
      from here.
  - name: B — Damage & condition
    description: Find it, then grade it, so your own rules can act on the result.
  - name: C — Parts
    description: >-
      Turns "there is damage" into "there is damage on this component" — what
      makes every downstream estimate defensible.
  - name: D — Money
    description: Valuation and repair cost, computed from what was actually observed.
  - name: E — Image production
    description: >-
      Exposed as raw infrastructure, not a batch retouching service. Call it per
      asset, in your own pipeline.
  - name: Jobs
    description: Status, results and history of asynchronous work.
  - name: Uploads
    description: Presigned storage for videos and batches.
  - name: Management
    description: >-
      Organisation, API keys, usage, billing and outgoing webhooks. JWT
      authenticated.
  - name: Internal
    description: Inbound callbacks from the inference plane. Never called by customers.
externalDocs:
  description: CarHub developer documentation
  url: https://docs.trycarhub.com
paths:
  /mgmt/v1/api-keys/{id}:
    patch:
      tags:
        - Management
      summary: Update API key scopes
      description: >-
        Admin or owner with current membership. Only scopes may be changed.
        Rotation preserves scopes exactly.
      operationId: updateApiKeyScopes
      parameters:
        - $ref: '#/components/parameters/ApiKeyId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - scopes
              properties:
                scopes:
                  type: array
                  items:
                    type: string
      responses:
        '200':
          description: Updated key, without secret
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiKey'
        '400':
          description: Invalid scopes or unsupported request fields
        '403':
          description: Administrator membership required
        '404':
          description: No such key in the authenticated organisation
      security:
        - BearerJWT: []
components:
  parameters:
    ApiKeyId:
      name: id
      in: path
      required: true
      description: API key identifier (not the secret).
      schema:
        type: string
        pattern: ^key_[1-9A-HJ-NP-Za-km-z]{8,32}$
  schemas:
    ApiKey:
      type: object
      description: An organisation API key. The secret is never returned after creation.
      required:
        - id
        - object
        - name
        - prefix
        - livemode
        - is_staging
        - scopes
        - created
        - last_used_at
        - revoked_at
      properties:
        is_staging:
          type: boolean
          default: false
          description: >-
            Staging classification. Requires live mode and uses the
            organisation's shared live credits.
        id:
          type: string
          examples:
            - key_9TbR3xLm
        object:
          type: string
          const: api_key
        name:
          type: string
          examples:
            - Production — vehicle worker
        prefix:
          type: string
          description: Readable head of the key, enough to identify it in your logs.
          examples:
            - chk_live_a1b2
        livemode:
          type: boolean
        scopes:
          type: array
          description: >-
            Normalized scopes. Empty grants no business access. Wildcard grants
            no SDK permission. SDK write implies SDK read; storage write implies
            storage read.
          items:
            type: string
        created:
          $ref: '#/components/schemas/Timestamp'
        created_by:
          type:
            - string
            - 'null'
          description: >-
            User who created the key, kept for audit. Revoking that user does
            not affect the key.
          examples:
            - usr_5KpL2wQx
        last_used_at:
          oneOf:
            - $ref: '#/components/schemas/Timestamp'
            - type: 'null'
        revoked_at:
          oneOf:
            - $ref: '#/components/schemas/Timestamp'
            - type: 'null'
        expires_at:
          description: >-
            Scheduled expiry, when the key was minted with one. Null for a
            perpetual key.
          oneOf:
            - $ref: '#/components/schemas/Timestamp'
            - type: 'null'
        rotates_at:
          description: >-
            End of the grace period of a rotated key: after this instant the
            previous secret stops working. Null when the key was never rotated.
          oneOf:
            - $ref: '#/components/schemas/Timestamp'
            - type: 'null'
    Timestamp:
      type: integer
      format: int64
      description: Epoch seconds, UTC.
      examples:
        - 1755300000
  securitySchemes:
    ApiKeyAuth:
      type: http
      scheme: bearer
      bearerFormat: CarHub API key
      description: >
        Organisation API key, sent as `Authorization: Bearer chk_live_…`.


        * `chk_live_…` — production inference, live credits, `livemode: true`,
        `is_staging: false`.

        * `chk_stg_…` — real inference classified as staging, the same live
        credits, `livemode: true`, `is_staging: true`.

        * `chk_test_…` — identical pipeline against the fixture backend, test
        credits,
          `livemode: false`.

        Keys are stored hashed; only the prefix (`chk_live_a1b2…`) is ever
        displayed again. A key

        may be scoped to a subset of endpoint families — calling outside its
        scopes is a `403`.
    BearerJWT:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >
        Short-lived JWT issued by the CarHub auth service (Better Auth),
        verified against its

        JWKS. Claims: `sub` (user), `org_id` (active organisation) and `role`

        (`owner` | `admin` | `member` | `billing_manager`). Used by the
        dashboard for `/mgmt/v1/…` only — it is never

        accepted on `/v1/…`.

````

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