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

# Credits and limits: prices, holds, concurrency and rate limits

> What each task costs, how credits are held and charged, and the limits that return 429 or 503.

Every task has a price in credits. The price is held when you submit, charged when the task completes, and released when it fails. Your plan sets how many tasks you can have queued or running at once.

For the live list of engines and prices, call the public capabilities endpoint. It needs no API key:

```bash theme={"theme":"css-variables"}
curl https://api.querying.ai/v1/capabilities
```

Add `?taskType=GEMINI` to read one engine. Aliases such as `GOOGLE_AIO` are accepted. See [Get capabilities](/api-reference/capabilities.md).

## Credits per task

| `taskType` | Credits |
| - | - |
| `CHATGPT` | 1 per answer. Each entry in `payload.followUps` is another answer. |
| `PERPLEXITY`, `BING_COPILOT`, `META_AI` | 1 |
| `GEMINI`, `GOOGLE` (`GOOGLE_AIO`), `AIMODE` (`GOOGLE_AIMODE`), `NAVER_AI_BRIEF`, `NAVER_AI_TAB`, `QWEN`, `DOUBAO` | 1.25 |
| `GOOGLE_SERP`, `NAVER_SERP`, `BING_SEARCH`, `REDDIT` | 1 |
| `COMMERCE_SERP` | 3 |
| `COMMERCE_PRODUCT` | 3 |
| `WEB_SCRAPE`, `WEB_MAP` | 1 |
| `WEB_CRAWL` | 1 per page returned. Holds `maxPages` credits at submit; pages it could not read are not charged. |
| `KEYWORD_VOLUME` | 3 per task (up to 100 keywords) |
| `PROMPT_RESEARCH` | 11 |
| `GEO_SCORE` | 10 per page, plus 5 per image whose text is read (`images.read`, at most 12). Holds 70 at submit; images it could not read are not charged, and an image reused from a reading in the last 90 days (`images.reused`) costs 2. |
| `AI_RENDERING` ([AI Rendering](/research/ai-rendering.md)) | 5 per render, plus 5 per image whose text is read and 2 per image reused from a reading in the last 90 days, at most 12. Holds 65 at submit. A refresh costs the same. |
| Asks of a [Product Lookup](/research/product-lookup.md#pricing) | 10 per product (the product and each competitor) and 5 per shopper prompt, whichever engines are asked. Each ask is an engine task charged its share of that price instead of the engine's price above. |
| Place Lookup (`POST /v1/place-lookup`) | 10 per lookup of the country's default engines: 1 per question in `KR`, 1.25 elsewhere. A lookup of fewer engines pays for the questions it sends. See [Place Lookup](/research/place-lookup.md). |
| `CITATION_ANALYSIS` | Metered by usage, up to the hold. See below. |

| Add-on | Credits |
| - | - |
| `payload.include.analysis` | 2 on top of the engine price, charged only when `analysis.status` is `ok` |
| `payload.include.html` | 0.25 on `CHATGPT`, `PERPLEXITY` and `META_AI`, charged only when `html.status` is `ok`. Free on `GEMINI`, `GOOGLE` and `AIMODE`. |
| `payload.include.citationAnalysis` | A separate `CITATION_ANALYSIS` task, charged by usage |
| Monitor competitor read | 80 credits per 30 days per monitor, split across its runs. See [GEO monitoring](/monitors.md#cost-and-scheduling). |

Prices do not vary by plan; the dollar value of a credit does. Credits can have two decimals, such as `1.25`.

### Citation Analysis metering

A `CITATION_ANALYSIS` task holds `20 + 12 × citations + 80 × ⌈answer characters ÷ 1,000⌉` credits at submit. On completion it is charged `1 + ⌈input tokens ÷ 500⌉ + ⌈output tokens ÷ 100⌉ + 2 × source fetches`, never more than the hold. The rest of the hold is released. See [Citation Analysis](/research/citation-analysis.md).

## Hold, capture and release

**1. Submit: hold**

The task's price (for `WEB_CRAWL`, `GEO_SCORE` and `CITATION_ANALYSIS`, the maximum) moves from your available balance to a hold. If the balance cannot cover it, the submit returns `402 INSUFFICIENT_CREDITS`. The submit response shows `credits` as `0`.

**2. Completed: capture**

The charge is taken from the hold. A terminal poll and the webhook show it in `creditsCharged`.

**3. Failed: release**

The hold returns to your balance. A failed task costs `0`.

A new account receives 500 credits at signup.

## Check your balance

`GET /v1/credits` returns your account's credits. Reading it costs nothing, so a program can check it before each batch. See [Credit balance](/api-reference/credits.md).

```bash theme={"theme":"css-variables"}
curl https://api.querying.ai/v1/credits \
  -H "Authorization: Bearer $QUERYING_API_KEY"
```

```json theme={"theme":"css-variables"}
{
  "success": true,
  "remaining": 1879939,
  "perCycle": 1000000,
  "cycleResetsAt": "2026-11-14T07:37:57.000Z",
  "reserved": 61,
  "plan": "max",
  "topUpBalance": { "credits": 1000000, "nextExpiresAt": "2027-01-19T10:01:57.000Z", "nextCredits": 1000000 }
}
```

* `remaining` is what you can spend now. Tasks you already submitted hold their price in `reserved`, so do not subtract them again.
* `perCycle` is what your plan grants each cycle, and `cycleResetsAt` is when the current cycle ends. Both are `null` without an active plan.
* `topUpBalance` counts the top-up credits within `remaining`, with the date the next of them expire and how many do. It is `null` when you have none. Top-up credits last three months from purchase, carry over renewals, and are spent after your plan's credits.

A sub-account's key gets `403 SUB_ACCOUNT_FORBIDDEN`, because a sub-account spends your credits. See [Sub-accounts](/sub-accounts.md).

## Check your usage

`GET /v1/usage` returns the credits your account was charged over a range of UTC dates, split by day, engine and API key as you choose. Reading it costs nothing. See [Credit usage](/api-reference/usage.md).

```bash theme={"theme":"css-variables"}
curl "https://api.querying.ai/v1/usage?from=2026-10-01&to=2026-10-20&groupBy=engine" \
  -H "Authorization: Bearer $QUERYING_API_KEY"
```

```json theme={"theme":"css-variables"}
{
  "success": true,
  "data": {
    "from": "2026-10-01",
    "to": "2026-10-20",
    "groupBy": ["engine"],
    "credits": 66.25,
    "tasks": 65,
    "rows": [
      { "taskType": "CHATGPT", "credits": 49, "tasks": 49 },
      { "taskType": "GEMINI", "credits": 6.25, "tasks": 5 },
      { "taskType": "PERPLEXITY", "credits": 11, "tasks": 11 }
    ]
  }
}
```

* `from` and `to` are UTC dates, and both days are included. They default to the first day of the current UTC month and today. A range spans at most 366 days.
* `groupBy` takes `day`, `engine` and `key`, separated by commas, and defaults to `day,engine`. A row has the fields of the splits you chose, and a combination with no charge has no row. `credits` and `tasks` at the top add up every row.
* `groupBy=key` shows who spent the credits. A task sent with an API key has `"source": "api"` and an `apiKey` with its `id`, `keyPrefix`, `name` and `subAccountId`. Spend without an API key has `source` set to `monitor` (a monitor's runs), `playground` or `dashboard`, and `apiKey` is `null`.
* Usage adds up what tasks were charged, and a failed task costs `0`. A monitor's competitor read is charged without a task, so it lowers your balance but is not in usage.
* Tasks of your [sub-accounts](/sub-accounts.md) are in your usage, and `apiKey.subAccountId` names the sub-account that owns a key. [`GET /v1/sub-accounts/{id}/usage`](/api-reference/sub-accounts/get-usage) reads one sub-account. A sub-account's key gets `403 SUB_ACCOUNT_FORBIDDEN`.

## Check your queue

`GET /v1/async/status` returns your queued and processing tasks next to the concurrency limit they count against. Reading it costs nothing. See [Queue status](/api-reference/queue-status.md).

```bash theme={"theme":"css-variables"}
curl https://api.querying.ai/v1/async/status \
  -H "Authorization: Bearer $QUERYING_API_KEY"
```

```json theme={"theme":"css-variables"}
{
  "success": true,
  "queuedTasks": 19,
  "processingTasks": 6,
  "priorityBreakdown": [{ "priority": 8, "count": 3 }, { "priority": 1, "count": 16 }],
  "concurrency": { "used": 25, "max": 200 }
}
```

* `concurrency.used` is `queuedTasks` plus `processingTasks`, the two counts that your plan's [concurrency limit](#plan-concurrency) adds together. `max` is that limit, so `max - used` is the room left for new tasks.
* `priorityBreakdown` lists the queued tasks by the `priority` they were submitted with, highest first.
* The counts include the tasks of your sub-accounts, which share your limit. A sub-account's key gets `403 SUB_ACCOUNT_FORBIDDEN` and reads its own task counts at [`GET /stats`](/api-reference/stats).

## Plans

| Plan | Price per month | Credits per month | Concurrent tasks |
| - | - | - | - |
| Free | \$0 | 500 at signup | 2 |
| Basic | \$20 | 8,000 | 50 |
| Pro | \$200 | 170,000 | 200 |
| Scale | \$500 | 480,000 | 500 |
| Max | \$1,000 | 1,000,000 | 1,000 |

Compare plans on the [pricing page](https://querying.ai/en/pricing).

### Plan concurrency

The concurrency limit counts your account's `QUEUED` and `PROCESSING` tasks together. It is not a limit on how fast you submit. A submit that would go over it returns `429 PLAN_CONCURRENCY_LIMIT` with `details.limit`, `details.active` and `Retry-After`. A contract can set a different limit for your account, and a parent account can set one for a [sub-account](/sub-accounts.md).

## Per-key and sub-account limits

| Limit | Set where | When reached |
| - | - | - |
| Daily credit limit on an API key | Manage key in the [dashboard](https://querying.ai/dashboard/keys), 0.01 to 20,000,000 credits | `429 KEY_DAILY_CREDIT_LIMIT` until the next midnight UTC. `Retry-After` counts the seconds to it. |
| `monthlyCreditLimit` on a sub-account | The parent account. See [Sub-accounts](/sub-accounts.md). | `429 SUB_ACCOUNT_CREDIT_LIMIT` |

The key's daily limit counts the hold a task needs, so a task is refused when `used + price` would pass the limit.

## Request rate and backpressure

| Limit | Response |
| - | - |
| 1,200 requests per minute per `Authorization` credential on `/v1/*` | `429` from the edge |
| 6,000 requests per minute per source IP | `429` from the edge |
| One engine's queue is full | `503 QUEUE_BACKPRESSURE` with `Retry-After` |
| Admission is saturated | `503 SERVER_OVERLOADED` with `Retry-After` |
| The global task queue is full | `503 SERVER_OVERLOADED` with `Retry-After` |
| One engine is temporarily not accepting tasks | `503 ENGINE_UNAVAILABLE` with `Retry-After` |

Edge `429`s come before the API and do not carry the JSON error envelope or `Retry-After`. Back off with exponential delay when you get one. A `429` or `503` from the task submit endpoints carries a `Retry-After` header in seconds. Codes and retry advice are in [Errors](/concepts/errors.md).

## Pace large submissions

**1. Batch instead of looping**

One `POST /v1/async/task/batch` with 500 items is one request against the edge limit. For more than your concurrency limit, use `POST /v1/batches`: the server releases items as room frees up. See [Batches and grids](/concepts/bulk-submission.md).

**2. Honor Retry-After**

Wait the number of seconds in `Retry-After` before you resubmit a refused task. Reuse the same `idempotencyKey` so a retry never creates a duplicate.

**3. Sequence dependent work**

Execution order is not guaranteed. Wait for a task to complete before you submit work that depends on its result.

**4. Watch your counts**

[`GET /v1/async/status`](/api-reference/queue-status) returns your queued and processing tasks next to your plan limit, so you can keep them under it. [`GET /stats`](/api-reference/stats) adds the tasks that finished in the last 24 hours.


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