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

# Get Key

> Any key of the account. Needs an ADMIN key.

<Note>
  Requires an **ADMIN** key. An API key gets `403` with `code: insufficient_permissions` — see [API Keys](/api-keys).
</Note>

Return one key of the account by its id — the same fields as [Get Current Key](/api/v2/keys/get-current-key).


## OpenAPI

````yaml openapi-v2.json GET /api/v2/keys/{id}
openapi: 3.1.0
info:
  title: deAPI REST API
  description: >-
    Decentralized AI inference API for image generation, video processing, audio
    transcription, and more.


    ## Rate limits


    Two windows can apply to a request: a per-minute one (RPM) and a per-day one
    (RPD). Every

    throttled response — success or 429 — carries the `X-RateLimit-*` headers,
    so you can pace

    traffic without waiting to be rejected. Each header documents itself: see
    `components/headers`,

    or the headers listed on any response. What follows is only what a header
    cannot say about

    itself.


    Windows open on your first request into a bucket and run their full length
    from that second —

    never to a calendar boundary, in any timezone. That is deliberate: a
    boundary every account

    shares is a boundary every account can double up on.


    **The headers describe the pool *this* request landed in, and
    `X-RateLimit-Source` is what

    identifies it — not `X-RateLimit-Limit` alone.** A per-model limit is keyed
    to the model you

    named, so a request that carried no recognised `model` — rejected at
    validation, an unknown

    slug, an empty body — was counted against your tier pool, and it is the tier
    pool the headers

    then describe. The two pools are fully independent: separate minute window,
    separate day,

    separate `X-RateLimit-Daily-Reset`. This is a consequence of rate limiting
    running *before*

    validation, which is what keeps malformed traffic from reaching the rest of
    the API

    uncounted. Compare headers only across responses carrying the same
    `X-RateLimit-Source`.


    **Buckets are shared in ways worth knowing.** API **v1 and v2 count against
    the same bucket**,

    so migrating grants no fresh allowance and mixed traffic behaves as one
    stream. All `*/price`

    and `*/price-calculation` endpoints share a single quote bucket, separate
    from generation.

    Prompt enhancement (`/v2/prompts/enhancements`) has its own bucket as well,
    so heavy prompt

    work no longer eats into your image throughput.


    **Counting is exact in sequence, best-effort in parallel.** Sent one after
    another, your

    requests are counted precisely: the one that crosses the limit is the one
    that gets 429. Sent

    in parallel, a few beyond the limit can slip through, because the counter is
    read and then

    incremented as two steps and requests already in flight are not yet visible
    to one another.

    The excess is bounded by how many of your own requests are in flight at
    once, and it only

    ever runs in your favour — you are never rejected while below your limit. So
    do not treat

    `X-RateLimit-Remaining` as a reservation: it is a snapshot, and a request
    you sent a

    millisecond ago may already have spent what it shows.


    Requests rejected before authentication (HTTP 401) never reach the limiter
    and carry no

    rate-limit headers at all.
  contact:
    name: deAPI Support
    url: https://deapi.ai
    email: support@deapi.ai
  version: 0.0.1
servers:
  - url: https://api.deapi.ai
    description: Production API Server base URL
security:
  - bearerAuth: []
tags:
  - name: Client API v2
    description: Current client endpoints (OpenAI-aligned noun-based paths)
paths:
  /api/v2/keys/{id}:
    get:
      tags:
        - Client API v2
      summary: Get an API key
      description: Any key of the account. Needs an ADMIN key.
      operationId: getApiKey
      parameters:
        - $ref: '#/components/parameters/AcceptHeader'
        - name: id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: The key.
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/ApiKeyResource'
                type: object
        '401':
          description: >-
            Missing, unknown, expired or deactivated key — `code` says which:
            `missing_key`, `invalid_key`, `key_expired` or `key_revoked`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/response_error_default'
        '403':
          $ref: '#/components/responses/InsufficientPermissions'
        '404':
          description: No such key on this account.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/response_error_default'
        '429':
          $ref: '#/components/responses/RateLimitExceeded'
      security:
        - bearerAuth: []
components:
  parameters:
    AcceptHeader:
      name: Accept
      in: header
      required: true
      schema:
        type: string
        default: application/json
        enum:
          - application/json
  schemas:
    ApiKeyResource:
      required:
        - id
        - name
        - preview
        - role
        - status
        - created_at
        - expires_at
        - last_used_at
        - ip_whitelist
        - ip_whitelist_count
        - limit
        - reset_interval
        - limit_used
        - limit_remaining
        - limit_resets_at
      properties:
        id:
          description: >-
            Key id. The secret is never returned here — only once, by `POST
            /api/v2/keys`.
          type: integer
          example: 42
        name:
          type: string
          example: Production backend
        preview:
          description: Key id and the last characters of the secret, for recognising a key.
          type: string
          example: 42|...f3a
        role:
          description: >-
            `api` — inference and the key's own data; `admin` — also account
            billing and key management.
          type: string
          example: api
          enum:
            - api
            - admin
        status:
          type: string
          example: active
          enum:
            - active
            - revoked
            - expired
          description: >-
            `revoked` — disabled in the Dashboard or with `PATCH
            /api/v2/keys/{id}` (`active: false`); `expired` — past `expires_at`.
        created_at:
          type: string
          format: date-time
          example: '2026-09-22T10:00:00+00:00'
        expires_at:
          description: Null when the key does not expire.
          type:
            - string
            - 'null'
          format: date-time
          example: null
        last_used_at:
          type:
            - string
            - 'null'
          format: date-time
          example: '2026-09-22T11:30:00+00:00'
        ip_whitelist:
          $ref: '#/components/schemas/ApiKeyIpWhitelist'
        ip_whitelist_count:
          description: >-
            How many entries the list holds — `0` means the key works from any
            address.
          type: integer
          example: 2
          minimum: 0
        limit:
          $ref: '#/components/schemas/ApiKeySpendLimit'
        reset_interval:
          description: >-
            How often the spend limit starts over. `none` while the key has no
            limit, and for a limit that never resets.
          type: string
          example: monthly
          enum:
            - none
            - daily
            - weekly
            - monthly
        limit_used:
          description: >-
            Spent against the limit in the window running now, in USD. Null when
            the key has no limit — nothing is counted for a key without one. Not
            the same figure as `GET /api/v2/keys/{id}/usage`, which sums what
            the key spent over the period you ask for: this counts only what
            went through the ceiling since the current window opened.
          type:
            - number
            - 'null'
          format: float
          example: 41.25
        limit_remaining:
          description: >-
            What is left of the limit in this window, in USD; null when there is
            no limit. Never negative — a cost settled after the work was
            admitted can put the counter over the ceiling, and the key then
            simply accepts nothing more until the window resets.
          type:
            - number
            - 'null'
          format: float
          example: 58.75
        limit_resets_at:
          description: >-
            When the counter next starts over. Null when the key has no limit,
            and null when it has one that never resets (`reset_interval: none`).
            Windows are anchored on the key's creation instant, not the
            calendar: a key created on the 15th at 13:42 UTC resets on the 15th
            at 13:42.
          type:
            - string
            - 'null'
          format: date-time
          example: '2026-10-22T10:00:00+00:00'
      type: object
    response_error_default:
      properties:
        data:
          description: Information from success endpoint
          type: object
        message:
          description: Error general message
          type: string
        errors:
          description: Information about errors
          type: array
          items: {}
        statusCode:
          description: Status code
          type: integer
        code:
          description: >-
            A stable, machine-readable reason, on the responses that publish
            one. Refused credentials (401): `missing_key` — no Bearer
            credentials arrived at all; `invalid_key` — a key was presented but
            is unknown, carries the wrong secret, or is malformed; `key_expired`
            — past its expiry date; `key_revoked` — deactivated. Refused
            requests: `insufficient_permissions` (403), `ip_not_allowed` (403),
            `active_key_limit_reached` (422), `insufficient_balance` (422),
            `key_limit_exceeded` (402), `rate_limited` (429). Absent wherever a
            response publishes no code, so treat an unknown value as the status
            code alone — the list grows.
          type: string
          enum:
            - missing_key
            - invalid_key
            - key_expired
            - key_revoked
            - insufficient_permissions
            - ip_not_allowed
            - active_key_limit_reached
            - insufficient_balance
            - key_limit_exceeded
            - rate_limited
      type: object
    ApiKeyIpWhitelist:
      description: >-
        The addresses an API key may be used from. An empty list means any
        address, which is what a key carries until a list is set. Entries are
        single IPv4/IPv6 addresses or CIDR ranges of either family, and a key
        with a non-empty list is refused from anywhere else — including a call
        whose address cannot be established. Sending the field replaces the
        whole list; `[]` clears it. A JSON object is refused, as is an entry
        that could never gate anything: a `/0` range (say "any address" with an
        empty list instead) and an IPv4 address written in IPv6 notation such as
        `::ffff:192.0.2.1` (write `192.0.2.1`, the form a caller is matched
        against).
      type: array
      items:
        type: string
        example: 203.0.113.7
      example:
        - 203.0.113.7
        - 198.51.100.0/24
      maxItems: 20
    ApiKeySpendLimit:
      description: >-
        What this key may spend per window, in USD. Null means no limit, which
        is what every key carries until one is set. `0` is a real value and
        means the key accepts no paid work at all. A limit is a ceiling, not a
        reservation: it holds nothing against the account balance, and the
        limits of an account's keys may add up to far more than the account has.
        Sending `null` removes the limit; because nothing is counted for a key
        without one, removing a limit and setting it again inside the same
        window starts the counter from zero.
      type:
        - number
        - 'null'
      format: float
      example: 100
      maximum: 999999.999999
      minimum: 0
    response_error_rate_limit:
      description: Rate limit exceeded response
      properties:
        message:
          description: Error message
          type: string
          example: Too Many Attempts.
      type: object
  responses:
    InsufficientPermissions:
      description: >-
        The API key may not make this call. `insufficient_permissions` — its
        role does not cover this endpoint; account billing and key management
        need an ADMIN key, and the role is fixed when the key is created.
        `ip_not_allowed` — the key carries an IP whitelist and the call did not
        come from an address on it; nothing is created and nothing is charged,
        and the call does not spend the account's request allowance. Keep
        calling from a refused address and the 403 turns into a 429 with
        `X-RateLimit-Type: ip-not-allowed`, counted against that address alone.
      content:
        application/json:
          schema:
            properties:
              message:
                type: string
                example: This API key does not have permission to access this endpoint.
              code:
                type: string
                example: insufficient_permissions
                enum:
                  - insufficient_permissions
                  - ip_not_allowed
            type: object
    RateLimitExceeded:
      description: >-
        Rate limit exceeded. Check X-RateLimit-Type header to determine if
        minute (RPM) or daily (RPD) limit was hit.
      headers:
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Daily-Limit:
          $ref: '#/components/headers/X-RateLimit-Daily-Limit'
        X-RateLimit-Daily-Remaining:
          $ref: '#/components/headers/X-RateLimit-Daily-Remaining'
        X-RateLimit-Type:
          $ref: '#/components/headers/X-RateLimit-Type'
        Retry-After:
          $ref: '#/components/headers/Retry-After'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
        X-RateLimit-Daily-Reset:
          $ref: '#/components/headers/X-RateLimit-Daily-Reset'
        X-RateLimit-Source:
          $ref: '#/components/headers/X-RateLimit-Source'
        X-RateLimit-Policy:
          $ref: '#/components/headers/X-RateLimit-Policy'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/response_error_rate_limit'
  headers:
    X-RateLimit-Limit:
      description: Maximum requests allowed per minute (RPM)
      schema:
        type: integer
        example: 3
    X-RateLimit-Remaining:
      description: Remaining requests in current minute window
      schema:
        type: integer
        example: 2
    X-RateLimit-Daily-Limit:
      description: Maximum requests allowed per day (RPD)
      schema:
        type: integer
        example: 100
    X-RateLimit-Daily-Remaining:
      description: Remaining requests in current day window
      schema:
        type: integer
        example: 95
    X-RateLimit-Type:
      description: >-
        Which limit rejected the request. Sent only on 429. Read it before
        anything else on the response: it decides what the other `X-RateLimit-*`
        headers are counting.


        `minute` — the per-request RPM window. `daily` — the per-request RPD
        window; the Daily-* pair is the one at 0.


        `key-creation` — the hourly cap on keys created over the API (`POST
        /api/v2/keys`), per account and shared by its ADMIN keys. The whole
        `X-RateLimit-*` set describes that bucket and there are no Daily-*
        headers.


        `ip-not-allowed` — too many calls from an address your key's IP
        whitelist refuses. Counted against that address, never against your
        account.
      schema:
        type: string
        example: minute
        enum:
          - minute
          - daily
          - key-creation
          - ip-not-allowed
    Retry-After:
      description: >-
        Seconds until the window that rejected you frees up (60 for minute, up
        to 86400 for daily). Counted from when that window opened, not to a
        calendar boundary. Sent only on 429.
      schema:
        type: integer
        example: 60
    X-RateLimit-Reset:
      description: >-
        Epoch second at which the minute (RPM) window refills. Fixed window —
        the value does not drift as you spend the quota. Describes the same
        window as X-RateLimit-Limit, including on a daily rejection.
      schema:
        type: integer
        example: 1755800460
    X-RateLimit-Daily-Reset:
      description: >-
        Epoch second at which the daily (RPD) window refills — 86400 s after the
        first request that opened this bucket's window, not a calendar midnight.
        Present only when a daily limit applies.
      schema:
        type: integer
        example: 1755846000
    X-RateLimit-Source:
      description: >-
        Where the limit came from, so you know what would change it:

        `tier` — your account tier's rate for this endpoint;

        `fallback` — no rate configured for this tier and endpoint, degraded
        default in force;

        `model` — a per-model override for the model in the request, unaffected
        by your tier

        (only when the request carried a recognised `model`, otherwise the tier
        pool applies);

        `static` — a flat limit outside the tier system, identical for every
        account.


        If you ever see `fallback`, tell us: it means no rate is configured for
        that tier and endpoint.
      schema:
        type: string
        example: tier
        enum:
          - tier
          - fallback
          - model
          - static
    X-RateLimit-Policy:
      description: >-
        Every window that applies, as `<limit>;w=<seconds>` elements. Always
        present on a throttled response, so a single element means there is no
        daily limit — do not infer that from the absence of the Daily-* headers.
        `300;w=60` is minute-only; `3;w=60, 100;w=86400` is both.
      schema:
        type: string
        example: 3;w=60, 100;w=86400
  securitySchemes:
    bearerAuth:
      type: http
      description: >-
        Sanctum personal access token, sent as `Authorization: Bearer <token>`.
        The token is opaque — it carries no claims and no embedded expiry, so do
        not attempt to decode it. Issue and revoke tokens from your account
        dashboard.
      scheme: bearer

````

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