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

# Web Search

> Search the live web and get ranked results — optionally with each page's text, the most relevant excerpts and an AI-written summary — in a single synchronous call. The response is returned directly: there is no `request_id` to poll, no webhook and no job status. The amount charged is returned in `cost`.

Search the live web and get ranked results in a single call — optionally with each page's clean text, the passages most relevant to your query, and an AI-written summary. Built for AI agents, RAG pipelines and research tools that need fresh, citable sources.

> [!NOTE]
>
> **Synchronous.** Results come back in the response body. There is no `request_id` to poll, no webhook and no job status — `request_id` in the response is only an identifier for support. The amount charged is returned in `cost`.

### Modes

| `mode` | Use it for | `summary` |
| - | - | - |
| `quick` | Lowest latency and price — autocomplete, agent tool calls, fact lookups | Not available (422) |
| `balanced` (default) | Better-ranked results for research and RAG | Available |

### Getting page content with the results

Leave `include` out to get only `url`, `title` and whatever metadata the page exposes (`published_at`, `author`, `image`). Add any of these to `include` to get page content in the same call:

* **`text`** — the page as clean text. `true` returns up to 20,000 characters; `{"max_length": 5000}` sets your own cap (1–100,000).
* **`excerpts`** — the passages most relevant to your `query`. `{"query": "..."}` steers them towards a different question.
* **`summary`** — an AI-written summary of each result (`balanced` mode only). `{"query": "..."}` focuses it on a question.

Optional fields are **omitted** from a result when the page does not provide them — check for presence rather than `null`.

### Filters

* **`only_domains`** — up to 50 bare hostnames (`deapi.ai`, `docs.deapi.ai`). No scheme, path, port or wildcard.
* **`country`** — ISO 3166-1 alpha-2 code (`US`, `DE`, `PL`) to bias results towards a country.
* **`published_after`** / **`published_before`** — ISO 8601 dates; `published_before` cannot be earlier than `published_after`.

### Example

```bash theme={null}
curl -X POST "https://api.deapi.ai/api/v2/web/search" \
  -H "Authorization: Bearer $DEAPI_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "FLUX.2 image model release",
    "mode": "balanced",
    "limit": 3,
    "include": {
      "text": { "max_length": 2000 },
      "excerpts": true,
      "summary": { "query": "What is new in this model?" }
    }
  }'
```

```json Response theme={null}
{
  "request_id": "dc260284-883c-44be-b61b-ef82a3486a50",
  "cost": 0.012,
  "results": [
    {
      "url": "https://bfl.ai/blog/flux-2",
      "title": "FLUX.2: Frontier Visual Intelligence | Black Forest Labs",
      "published_at": "2025-11-25T15:11:07+00:00",
      "image": "https://bfl.ai/api/og/blog/flux-2",
      "text": "FLUX.2: Frontier Visual Intelligence ...",
      "excerpts": ["FLUX.2 is designed for real-world creative workflows ..."],
      "summary": "FLUX.2 introduces several major enhancements ..."
    }
  ]
}
```

### Pricing

| Component | Price |
| - | - |
| `quick` search, up to 10 results | 0.0048 USD |
| `balanced` search, up to 10 results | 0.0084 USD |
| Each result above 10 (`limit` 11–25) | +0.0012 USD |
| `summary` | +0.0012 USD per result (counted from `limit`) |
| `text`, `excerpts` | Included |

Use [Web Search Price](https://docs.deapi.ai/api/v2/web/search-price.md) to get the exact quote for a request body. See also [Pricing](https://docs.deapi.ai/pricing.md).

> [!TIP]
>
> Already have the URLs? Use [Web Contents](https://docs.deapi.ai/api/v2/web/contents.md) to read specific pages instead of searching.


## OpenAPI

````yaml openapi.json POST /api/v2/web/search
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.


    **Not every 429 comes from the request rate.** Creating API keys has its own
    hourly bucket,

    and a key with an IP whitelist has one for calls from addresses it refuses.
    A 429 always

    describes the bucket that actually refused it — `X-RateLimit-Type` names
    that bucket, and

    every other `X-RateLimit-*` header on the response belongs to it. So back
    off on the headers

    you were sent, and do not carry figures from one 429 over to the next.


    **A call refused by a key's IP whitelist does not spend the account's
    request allowance.**

    It is counted against the address it came from instead, on a much tighter
    window — so a

    whitelist cannot be turned against the owner it protects, and being refused
    still does not

    come free.


    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/web/search:
    post:
      tags:
        - Client API v2
      summary: Search the web
      description: >-
        Search the live web and get ranked results — optionally with each page's
        text, the most relevant excerpts and an AI-written summary — in a single
        synchronous call. The response is returned directly: there is no
        `request_id` to poll, no webhook and no job status. The amount charged
        is returned in `cost`.
      operationId: webSearch
      parameters:
        - $ref: '#/components/parameters/AcceptHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebSearchRequestBody'
      responses:
        '200':
          description: Search results.
          headers:
            X-RateLimit-Policy:
              $ref: '#/components/headers/X-RateLimit-Policy'
            X-RateLimit-Source:
              $ref: '#/components/headers/X-RateLimit-Source'
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
            X-RateLimit-Daily-Limit:
              $ref: '#/components/headers/X-RateLimit-Daily-Limit'
            X-RateLimit-Daily-Remaining:
              $ref: '#/components/headers/X-RateLimit-Daily-Remaining'
            X-RateLimit-Daily-Reset:
              $ref: '#/components/headers/X-RateLimit-Daily-Reset'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebSearchResponse'
              examples:
                quick:
                  summary: Quick search
                  value:
                    request_id: ba1e1b58-a12c-4f83-9ec7-572e301fa1c2
                    cost: 0.0048
                    results:
                      - url: >-
                          https://huggingface.co/models?pipeline_tag=text-to-image
                        title: Text-to-Image Models – Hugging Face
                      - url: >-
                          https://fluence.ai/blog/best-open-source-text-to-image-models/
                        title: 12 Best Open Source Image Generation Models (in 2026)
                        published_at: '2026-10-20T08:48:00+00:00'
                        author: Fluence
                with_content:
                  summary: Balanced search with text, excerpts and summary
                  value:
                    request_id: dc260284-883c-44be-b61b-ef82a3486a50
                    cost: 0.012
                    results:
                      - url: https://bfl.ai/blog/flux-2
                        title: >-
                          FLUX.2: Frontier Visual Intelligence | Black Forest
                          Labs
                        published_at: '2025-11-25T15:11:07+00:00'
                        image: https://bfl.ai/api/og/blog/flux-2
                        text: >-
                          FLUX.2: Frontier Visual Intelligence | Black Forest
                          Labs


                          # FLUX.2: Frontier Visual Intelligence


                          November 25, 2025 5 min read ...
                        excerpts:
                          - >-
                            # FLUX.2: Frontier Visual Intelligence


                            FLUX.2 is designed for real-world creative workflows
                            ...
                        summary: >-
                          FLUX.2 introduces several major enhancements for
                          real-world creative workflows: multi-reference support
                          ...
        '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'
        '402':
          $ref: '#/components/responses/KeyLimitExceeded'
        '403':
          $ref: '#/components/responses/AccountSuspended'
        '404':
          description: Not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/response_error_default'
        '422':
          $ref: '#/components/responses/ValidationError'
        '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:
    WebSearchRequestBody:
      type: object
      required:
        - query
      properties:
        query:
          description: What to search for, in natural language or as keywords.
          type: string
          maxLength: 2000
          example: open source text to image models 2026
        mode:
          description: >-
            `quick` is the fastest and cheapest; `balanced` takes a little
            longer, returns better-ranked results and is the only mode that can
            return `summary`. Defaults to `balanced`.
          type: string
          enum:
            - quick
            - balanced
          default: balanced
          example: quick
        limit:
          description: >-
            Maximum number of results. The base price covers up to 10 results;
            every result above 10 adds to the price.
          type: integer
          minimum: 1
          maximum: 25
          default: 10
          example: 5
        include:
          description: >-
            Page content to return with each result. Leave it out to get only
            `url`, `title` and the metadata the page exposes.
          type: object
          additionalProperties: false
          properties:
            text:
              $ref: '#/components/schemas/WebTextOption'
            excerpts:
              $ref: '#/components/schemas/WebExcerptsOption'
            summary:
              allOf:
                - $ref: '#/components/schemas/WebSummaryOption'
              description: >-
                AI-written summary of each result. Only available in `balanced`
                mode — in `quick` mode the request is refused with 422
                (`include.summary`).
        only_domains:
          description: >-
            Return results from these domains only. Bare hostnames such as
            `deapi.ai` or `docs.deapi.ai` — no scheme, path, port or wildcard.
          type: array
          maxItems: 50
          items:
            type: string
            example: deapi.ai
          example:
            - deapi.ai
            - docs.deapi.ai
        country:
          description: >-
            Bias results towards a country. ISO 3166-1 alpha-2 code,
            case-insensitive (e.g. `US`, `DE`, `PL`).
          type: string
          minLength: 2
          maxLength: 2
          example: US
        published_after:
          description: >-
            Only results published on or after this date (ISO 8601 date or
            date-time).
          type: string
          format: date
          example: '2026-01-01'
        published_before:
          description: >-
            Only results published on or before this date (ISO 8601 date or
            date-time). Must not be earlier than `published_after`.
          type: string
          format: date
          example: '2026-11-01'
    WebSearchResponse:
      type: object
      description: Returned directly — there is no `data` envelope and no job to poll.
      properties:
        request_id:
          description: Identifier of this request, useful when contacting support.
          type: string
          format: uuid
          example: ba1e1b58-a12c-4f83-9ec7-572e301fa1c2
        cost:
          description: >-
            What this request was charged, in USD. Matches the amount deducted
            from the balance and reported by the usage endpoints.
          type: number
          format: float
          example: 0.0048
        results:
          type: array
          items:
            $ref: '#/components/schemas/WebSearchResult'
    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
    WebTextOption:
      description: >-
        Return the page as clean text (Markdown-like). `true` uses the default
        length cap of 20,000 characters; an object lets you set your own cap.
        Longer pages are cut at the cap.
      oneOf:
        - type: boolean
        - type: object
          additionalProperties: false
          properties:
            max_length:
              description: Maximum number of characters of text returned per page.
              type: integer
              minimum: 1
              maximum: 100000
              example: 5000
      example:
        max_length: 5000
    WebExcerptsOption:
      description: >-
        Return the passages of the page most relevant to your search (or to
        `query`, if you set one). `true` ranks passages against the search
        query; on the contents endpoint, which has no search query, pass an
        object with `query` to steer the selection.
      oneOf:
        - type: boolean
        - type: object
          additionalProperties: false
          properties:
            query:
              description: What the excerpts should be about.
              type: string
              minLength: 1
              maxLength: 2000
              example: pricing
      example: true
    WebSummaryOption:
      description: >-
        Return a short AI-written summary of each page. `true` writes a general
        summary; an object with `query` focuses the summary on a question.
        Billed per page (see pricing).
      oneOf:
        - type: boolean
        - type: object
          additionalProperties: false
          properties:
            query:
              description: Question or angle the summary should answer.
              type: string
              minLength: 1
              maxLength: 2000
              example: What does this company offer?
      example:
        query: What does this company offer?
    WebSearchResult:
      type: object
      required:
        - url
      description: >-
        One search hit. Every field except `url` is optional and omitted (not
        null) when unavailable.
      properties:
        url:
          description: Page URL.
          type: string
          format: uri
          example: https://deapi.ai/
        title:
          description: Page title. Omitted when the page has none.
          type: string
          example: deAPI - One API for Open Source Generative AI Models
        published_at:
          description: Publication date, when the page exposes one. Omitted otherwise.
          type: string
          format: date-time
          example: '2026-10-20T08:48:00+00:00'
        author:
          description: Author, when the page exposes one. Omitted otherwise.
          type: string
          example: deAPI
        image:
          description: >-
            Representative image (e.g. the Open Graph image), when the page has
            one. Omitted otherwise.
          type: string
          format: uri
          example: https://deapi.ai/images/og/og-deapi.jpg
        text:
          description: >-
            Page text, present when `text` was requested. Cut at `max_length`
            (default 20,000 characters).
          type: string
        excerpts:
          description: Most relevant passages, present when `excerpts` was requested.
          type: array
          items:
            type: string
        summary:
          description: AI-written summary, present when `summary` was requested.
          type: string
    response_error_rate_limit:
      description: Rate limit exceeded response
      properties:
        message:
          description: Error message
          type: string
          example: Too Many Attempts.
      type: object
  headers:
    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
    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-Limit:
      description: >-
        Maximum requests allowed per minute (RPM) — including on a `daily`
        rejection, where the day is reported by the Daily-* pair beside it. On a
        429 whose `X-RateLimit-Type` names a bucket outside the request rate
        (`key-creation`, `ip-not-allowed`) it is that bucket's allowance
        instead, over the window `X-RateLimit-Policy` gives.
      schema:
        type: integer
        example: 3
    X-RateLimit-Remaining:
      description: >-
        Requests left in the window `X-RateLimit-Limit` describes — so on a
        `daily` rejection it is the minute window and can still be non-zero;
        `X-RateLimit-Daily-Remaining` is the one at 0 there.
      schema:
        type: integer
        example: 2
    X-RateLimit-Reset:
      description: >-
        Epoch second at which the window described by `X-RateLimit-Limit`
        refills — the minute (RPM) one unless `X-RateLimit-Type` names another
        bucket. 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-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-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-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.
        `X-RateLimit-Limit`/`-Remaining`/`-Reset`

        describe it, and the Daily-* pair describes the day next to it when one
        applies.


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

        unprefixed trio keeps describing the minute window, so it can be
        non-zero.


        `key-creation` — the hourly cap on keys created over the API (`POST
        /v2/keys`),

        per account and shared by its ADMIN keys, counted separately from the
        request

        rate. The whole `X-RateLimit-*` set describes that bucket and there are
        no

        Daily-* headers, so `Retry-After` can be an hour while your request rate
        is

        barely touched. That is not a contradiction — it is a different bucket.


        `ip-not-allowed` — too many calls from an address your key's IP
        whitelist

        refuses. Counted against that address, never against your account: a
        call from a

        blocked address does not spend your request allowance, which is why it
        cannot be

        used to exhaust it. Fix the whitelist or call from a listed address.


        The buckets are independent, so do not compare figures across responses
        that

        report different types — and do not assume the minute window when a 429
        names

        another one, or you will retry straight into the same refusal.
      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 — the one
        `X-RateLimit-Type` names (up to 60 for minute, 3600 for key-creation,
        86400 for daily). Counted from when that window opened, not to a
        calendar boundary. Sent only on 429.
      schema:
        type: integer
        example: 60
  responses:
    KeyLimitExceeded:
      description: >-
        The API key sending the request has no room left under its own spend
        limit (`limit` / `reset_interval` on the key). Nothing was created and
        nothing was charged — the request is refused before the job exists.
        `resets_at` is when the window starts over and work flows again; it is
        null for a limit that never resets (`reset_interval: none`), and the way
        through then is to raise or remove the limit on the key. The key itself
        stays active — an exhausted limit refuses work, it does not deactivate
        anything, and the account's other keys are unaffected.


        DO NOT confuse `key_limit_exceeded` with `active_key_limit_reached`.
        This one is about MONEY: one key, one window, one ceiling in USD, and it
        is a 402 on the endpoints that spend. `active_key_limit_reached` is
        about the NUMBER of keys an account may keep active at once, and it is a
        422 on POST /v2/keys and PATCH /v2/keys/{id}. They share no field and no
        remedy.


        `limit_used` here and the totals from GET /keys/{id}/usage are different
        questions and will not agree: usage sums what the key spent over the
        period you ask for, this counts what went through the ceiling since the
        current window opened, nothing is counted while a key has no limit, and
        a post-paid request counts at its estimate until the provider reports
        its real cost.
      content:
        application/json:
          schema:
            properties:
              message:
                type: string
                example: >-
                  This API key has reached its spend limit of $100.00. It resets
                  on 2026-10-22T10:00:00+00:00.
              code:
                type: string
                example: key_limit_exceeded
                enum:
                  - key_limit_exceeded
              limit:
                description: The key's ceiling for the window, in USD.
                type: number
                format: float
                example: 100
              used:
                description: Spent against it in the window running now.
                type: number
                format: float
                example: 99.5
              remaining:
                description: What is left of it. Never negative.
                type: number
                format: float
                example: 0.5
              resets_at:
                description: >-
                  When the window starts over. Null for a limit that never
                  resets.
                type:
                  - string
                  - 'null'
                format: date-time
                example: '2026-10-22T10:00:00+00:00'
            type: object
    AccountSuspended:
      description: >-
        The account is suspended. Applies to every endpoint that spends credits
        — generation, transcription and prompt enhancement — and is returned
        before any validation runs, so a suspended account sees this rather than
        a 422 about the body. Price-estimate endpoints are not gated and keep
        working.
      content:
        application/json:
          schema:
            properties:
              message:
                description: >-
                  Human-readable explanation. No `errors` object accompanies
                  this response.
                type: string
                example: >-
                  Client account is suspended. If you believe this is a mistake,
                  contact us.
            type: object
    ValidationError:
      description: >-
        Validation failed. Common errors include: model does not exist, model
        does not support the inference type for this endpoint, the model is not
        available on your plan (it requires a higher tier than your account has
        — upgrade to use it), or invalid request parameters.


        An account without the funds for the request is refused here too,
        reported on the `balance` field and carrying `code:
        insufficient_balance`. It is the one validation failure worth branching
        on: nothing about the request is wrong, so retrying it unchanged
        succeeds once the account is topped up. The code is present only when
        `balance` is the sole failure — a request that is also malformed is not
        a money problem.
      content:
        application/json:
          schema:
            properties:
              message:
                description: General error message
                type: string
                example: The selected model does not support Text To Image.
              code:
                description: >-
                  Only on a refusal for want of funds: `insufficient_balance`.
                  Absent on every other validation failure.
                type: string
                example: insufficient_balance
                enum:
                  - insufficient_balance
              errors:
                description: >-
                  Detailed validation errors by field. A model your plan does
                  not cover is reported on the "model" field with the message
                  "This model is not available on your plan. Please upgrade to
                  access it." Such a model is also omitted from GET /models.
                type: object
                example:
                  model:
                    - >-
                      This model is not available on your plan. Please upgrade
                      to access it.
            type: object
    RateLimitExceeded:
      description: >-
        Rate limit exceeded. `X-RateLimit-Type` says which bucket refused you
        and which bucket the other `X-RateLimit-*` headers describe: the minute
        (RPM) or daily (RPD) request window, or — on a key carrying an IP
        whitelist — `ip-not-allowed`, the separate allowance for calls from an
        address the list refuses. That last one is counted against the calling
        address rather than the account, so being refused from a blocked address
        never spends the owner's request allowance.
      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'
  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.