> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.beatapi.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.beatapi.io/_mcp/server.

# API сравнения цен

> Сравнение цены BeatAPI для одной конфигурации модели с публичными ценами других платформ на ту же конфигурацию, без API-ключа.

# API сравнения цен

`POST /v1/price-comparisons` сравнивает цену BeatAPI для одной опубликованной тарифной спецификации с публичными ценами, которые другие платформы указывают для той же спецификации. API-ключ не нужен, вызов не тарифицируется.

Сравнение нейтральное. BeatAPI ранжируется по тем же правилам, что и любая другая платформа, и если другая платформа дешевле, ответ прямо это показывает: `beatapi_position` равно `not_lowest`.

## Быстрый старт

```bash
curl https://api.beatapi.io/v1/price-comparisons \
  -H "Content-Type: application/json" \
  -d '{"model":"Nano Banana Pro"}'
```

Если передать только `model`, обычная конфигурация модели сравнивается со всеми платформами, для которых сохранена цена этой спецификации. Добавьте `spec`, чтобы выбрать другую конфигурацию, и `providers`, чтобы выбрать платформы.

## Запрос

| Поле        | Тип       |                Обязательно | Описание                                                                                                                                                                          |
| ----------- | --------- | -------------------------: | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `model`     | string    | Да, если не передан `spec` | Отображаемое имя модели (`Nano Banana Pro`), slug её страницы, общий префикс её ID спецификаций или один ID спецификации. Регистр не учитывается, точки и дефисы взаимозаменяемы. |
| `spec`      | string    |                        Нет | Один ID спецификации этой модели из `GET /v1/pricing`, например `nano-banana-pro-4k`. Без него сравнивается обычная конфигурация.                                                 |
| `providers` | string\[] |                        Нет | ID платформ для сравнения, не более 20. Без него участвуют все платформы, для которых сохранена цена этой спецификации, включая BeatAPI.                                          |

`model` и `spec` — не длиннее 200 символов каждое. Если `model` пусто, модель ищется по `spec`.

### Обычная конфигурация

Без `spec` одна конфигурация выбирается по её форме и никогда — по тому, какая платформа выигрывает:

* Текстовые модели — входные токены.
* Видеомодели — первая спецификация 720p без референсного видео и без режима «видео в видео».
* Модели изображений — первая обычная спецификация изображения, например `nano-banana-pro-1k`.

Если `model` сам является ID спецификации, сравнивается эта спецификация.

### ID спецификаций

ID спецификаций берутся из анонимного прайс-листа: у каждой записи `data.groups[].specs[]` в `GET https://api.beatapi.io/v1/pricing` есть `id`. Каждый ответ сравнения также возвращает `available_specs` модели.

### ID платформ

ID платформ пишутся строчными буквами, как в `quotes[].provider`; `beatapi` — это BeatAPI. Если передан `providers`, сравниваются только перечисленные платформы, поэтому включите `beatapi`, чтобы BeatAPI участвовал в ранжировании. Перечисленная платформа без цены для этой спецификации возвращается как `pending_verification`. ID, которого нет в таблице сравнения, отклоняется с `400`.

## Ответ

Успешный вызов возвращает `200` с результатом в `data` — та же оболочка, что у `GET /v1/pricing`. Ответ не кешируется (`Cache-Control: no-store`).

В примере ниже использованы цены, проверенные 2026-11-11. Цены, даты и значение `data_version` со временем меняются; актуальные цифры получайте вызовом эндпоинта.

```bash
curl https://api.beatapi.io/v1/price-comparisons \
  -H "Content-Type: application/json" \
  -d '{"model":"Nano Banana Pro","spec":"nano-banana-pro-1k","providers":["beatapi","atlascloud","fal","google","higgsfield","wavespeed"]}'
```

```json
{
  "data": {
    "status": "ready",
    "model": "Nano Banana Pro",
    "spec": {
      "id": "nano-banana-pro-1k",
      "label": "1 image · 1K",
      "label_zh": "1 张图片 · 1K",
      "category": "image",
      "unit": "image"
    },
    "available_specs": ["nano-banana-pro-1k", "nano-banana-pro-2k", "nano-banana-pro-4k"],
    "questions": [],
    "quotes": [
      {
        "provider": "beatapi",
        "status": "quoted",
        "provider_model_id": "Nano Banana Pro",
        "amount": "0.05",
        "currency": "USD",
        "quote_kind": "fixed",
        "matched_configuration": "1 image · 1K",
        "source_urls": ["https://api.beatapi.io/v1/pricing", "https://beatapi.io/nano-banana-pro-api"],
        "checked_at": "2026-11-11T10:00:00Z",
        "expires_at": null,
        "freshness_status": "fresh",
        "rank_eligible": true,
        "exclusion_reason": null
      },
      {
        "provider": "atlascloud",
        "status": "quoted",
        "provider_model_id": "google/nano-banana-pro/text-to-image",
        "amount": "0.14",
        "currency": "USD",
        "quote_kind": "estimate",
        "matched_configuration": "1k · 1:1 · 1 张 · 文生图 · 不开 web/image search · thinking 默认",
        "source_urls": ["https://www.atlascloud.ai/models/google/nano-banana-pro/text-to-image"],
        "checked_at": "2026-11-11T08:59:27Z",
        "expires_at": "2026-12-11T08:59:27Z",
        "freshness_status": "fresh",
        "rank_eligible": false,
        "exclusion_reason": "Estimated by the provider's calculator, not a fixed price."
      },
      {
        "provider": "fal",
        "status": "quoted",
        "provider_model_id": "fal-ai/nano-banana-pro",
        "amount": "0.15",
        "currency": "USD",
        "quote_kind": "fixed",
        "matched_configuration": "Nano Banana Pro text-to-image resolution=1K, no web search",
        "source_urls": ["https://fal.ai/models/fal-ai/nano-banana-pro"],
        "checked_at": "2026-11-11T08:50:26Z",
        "expires_at": "2026-12-11T08:50:26Z",
        "freshness_status": "fresh",
        "rank_eligible": true,
        "exclusion_reason": null
      },
      {
        "provider": "google",
        "status": "quoted",
        "provider_model_id": "gemini-3-pro-image",
        "amount": "0.1344",
        "currency": "USD",
        "quote_kind": "formula",
        "matched_configuration": "gemini-3-pro-image text-to-image 1K 1:1, Standard paid tier, 1 output image",
        "source_urls": ["https://ai.google.dev/gemini-api/docs/pricing#gemini-3-pro-image"],
        "checked_at": "2026-11-11T08:50:17Z",
        "expires_at": "2026-12-11T08:50:17Z",
        "freshness_status": "fresh",
        "rank_eligible": true,
        "exclusion_reason": null
      },
      {
        "provider": "higgsfield",
        "status": "unsupported_configuration",
        "amount": null,
        "currency": "USD",
        "source_urls": ["https://open.higgsfield.ai/pricing"],
        "checked_at": "2026-11-11T08:48:09Z",
        "expires_at": "2026-12-11T08:48:09Z",
        "freshness_status": "fresh",
        "rank_eligible": false,
        "exclusion_reason": "The provider does not offer this model or configuration."
      },
      {
        "provider": "wavespeed",
        "status": "quoted",
        "provider_model_id": "google/nano-banana-pro/text-to-image",
        "amount": "0.126",
        "currency": "USD",
        "quote_kind": "fixed",
        "matched_configuration": "1k · 1:1 · 1 张 · 文生图 · 不开 web/image search",
        "source_urls": ["https://wavespeed.ai/models/google/nano-banana-pro/text-to-image"],
        "checked_at": "2026-11-11T08:52:36Z",
        "expires_at": "2026-12-11T08:52:36Z",
        "freshness_status": "fresh",
        "rank_eligible": true,
        "exclusion_reason": null
      }
    ],
    "summary": {
      "winner_providers": ["beatapi"],
      "lowest_amount": "0.05",
      "ranking_scope": ["beatapi", "wavespeed", "google", "fal"],
      "excluded_providers": ["atlascloud", "higgsfield"],
      "coverage_complete": true,
      "beatapi_position": "lowest",
      "conclusion": "beatapi has the lowest price of 4 verified providers at $0.05.",
      "benchmarks": {
        "provider_count": 4,
        "mean_scope": ["beatapi", "wavespeed", "google", "fal"],
        "mean_amount": "0.1151",
        "second_provider_amount": "0.126",
        "second_provider_providers": ["wavespeed"],
        "lowest_below_second_percentage": "60.32",
        "lowest_below_mean_percentage": "56.56"
      }
    },
    "data_version": "quotes-684-1794391200",
    "generated_at": "2026-11-11T10:00:00Z"
  }
}
```

Как цифры этого примера получаются из цен:

* Ранжируются четыре цены — 0.05, 0.126, 0.1344 и 0.15. Оценка от `atlascloud` и неподдерживаемая конфигурация у `higgsfield` перечислены, но не ранжируются.
* Минимальная цена — 0.05 (`beatapi`). Второе место — 0.126 (`wavespeed`). (0.126 − 0.05) ÷ 0.126 = 60.32%.
* Среднее — (0.05 + 0.126 + 0.1344 + 0.15) ÷ 4 = 0.1151. (0.1151 − 0.05) ÷ 0.1151 = 56.56%.

### Поля верхнего уровня

| Поле               | Описание                                                                                                   |
| ------------------ | ---------------------------------------------------------------------------------------------------------- |
| `status`           | `needs_clarification`, `ready`, `partial` или `unavailable` (см. ниже).                                    |
| `model`            | Сравненная модель — под тем именем, что в прайс-листе.                                                     |
| `model_candidates` | Только при `needs_clarification` — модели, которые можно отправить в `model`, не более 10.                 |
| `spec`             | Что сравнивалось — `id`, `label`, `label_zh`, `category` и `unit`. При `needs_clarification` равно `null`. |
| `available_specs`  | Все ID спецификаций модели — для повторного вызова со `spec`.                                              |
| `questions`        | Что отправить дальше, если запрос неоднозначен; иначе пусто.                                               |
| `quotes`           | По одной записи на платформу — сначала `beatapi`, остальные по ID.                                         |
| `summary`          | Ранжирование и четыре метрики. При `needs_clarification` равно `null`.                                     |
| `data_version`     | Меняется при любом изменении сохранённых цен. Сравнивайте его между вызовами, но не разбирайте.            |
| `generated_at`     | Когда рассчитан ответ, в UTC.                                                                              |

| `status`              | Значение                                                                                                                                                                  |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `needs_clarification` | Модель не распознана или подходит несколько моделей. `quotes` пусто, `summary` равно `null`; отправьте одну из `model_candidates`.                                        |
| `ready`               | Для каждой перечисленной платформы есть окончательный ответ по спецификации.                                                                                              |
| `partial`             | Хотя бы одна цена имеет статус `pending_verification`, `source_conflict`, `stale` или `incomplete_price`. Ранжирование охватывает только цены, которые можно ранжировать. |
| `unavailable`         | Сравнивать нечего. Обрабатывайте как ответ без ранжирования.                                                                                                              |

### Единицы

| `spec.unit` | Каждая сумма — это цена                                                                        |
| ----------- | ---------------------------------------------------------------------------------------------- |
| `image`     | Одного изображения этой спецификации.                                                          |
| `video`     | Одного целого видео той длительности, что указана в названии спецификации, а не одной секунды. |
| `1M_tokens` | Одного миллиона токенов этой спецификации, например входных токенов.                           |

Все суммы указаны в USD и передаются десятичными строками, поэтому малая цена никогда не округляется до нуля. `null` означает, что надёжной цены нет; `"0"` означало бы бесплатно.

### Цены

| Поле                        | Описание                                                                                                                                                                                 |
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `provider`                  | ID платформы.                                                                                                                                                                            |
| `status`                    | `quoted`, `stale`, `incomplete_price`, `unsupported_configuration`, `no_public_price`, `source_conflict` или `pending_verification`.                                                     |
| `provider_model_id`         | Собственное имя модели или эндпоинта на платформе, если известно.                                                                                                                        |
| `amount`                    | Полная цена за одну единицу или `null`.                                                                                                                                                  |
| `quote_kind`                | `fixed` (опубликованная цена), `formula` (рассчитана по опубликованным ставкам) или `estimate` (оценка калькулятора).                                                                    |
| `matched_configuration`     | Конфигурация, для которой прочитана цена, в том виде, как она записана при проверке.                                                                                                     |
| `note`                      | Необязательное примечание, например множитель по времени суток для цены BeatAPI.                                                                                                         |
| `source_urls`               | Публичные страницы, с которых прочитана цена.                                                                                                                                            |
| `checked_at` / `expires_at` | Когда цена проверена и когда она перестаёт ранжироваться (через 30 дней). Цена BeatAPI читается в реальном времени, поэтому её `checked_at` — время вызова, а `expires_at` равно `null`. |
| `freshness_status`          | `fresh`, `stale` или `unknown`.                                                                                                                                                          |
| `rank_eligible`             | Участвует ли цена в ранжировании.                                                                                                                                                        |
| `exclusion_reason`          | Почему цена перечислена, но не ранжируется; `null`, если ранжируется.                                                                                                                    |

Цена ранжируется, только если у неё есть сумма, она проверена за последние 30 дней, точно соответствует спецификации и не является оценкой. Все остальные цены остаются в `quotes` со своим `exclusion_reason`, так что видно, кто исключён и почему.

Цена BeatAPI — это текущая розничная цена из `GET /v1/pricing`, поэтому изменение цены BeatAPI отражается в следующем сравнении. Цены других платформ проверяются вручную по их публичным страницам.

### Сводка и четыре метрики

| Поле                                        | Описание                                                                                                                                                                                                                |
| ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `winner_providers` / `lowest_amount`        | Минимальная ранжированная цена и все платформы с этой ценой. При равенстве перечисляются все.                                                                                                                           |
| `benchmarks.lowest_below_second_percentage` | Насколько минимальная цена ниже цены на втором месте. Равные цены учитываются, поэтому при общем минимуме получается `"0.00"`. `second_provider_amount` и `second_provider_providers` показывают эту цену и у кого она. |
| `benchmarks.mean_amount`                    | Среднее всех ранжированных цен, включая BeatAPI, по одной цене на платформу (`mean_scope`).                                                                                                                             |
| `benchmarks.lowest_below_mean_percentage`   | Насколько минимальная цена ниже этого среднего.                                                                                                                                                                         |
| `benchmarks.provider_count`                 | Сколько платформ ранжировано.                                                                                                                                                                                           |
| `ranking_scope` / `excluded_providers`      | Ранжированные платформы от самой дешёвой к самой дорогой и перечисленные платформы, которые не ранжируются.                                                                                                             |
| `coverage_complete`                         | `false`, если ответ `partial`.                                                                                                                                                                                          |
| `beatapi_position`                          | `lowest`, `tied_lowest`, `not_lowest`, `insufficient_comparison` или `not_compared`.                                                                                                                                    |
| `conclusion`                                | Одно предложение на английском с итогом.                                                                                                                                                                                |

Проценты — строки с двумя знаками после запятой, рассчитанные по неокруглённым суммам с округлением половины вверх в конце. Метрика равна `null`, если ранжировано меньше двух платформ или её знаменатель равен нулю; `NaN` не бывает. `mean_amount` округляется до 8 знаков после запятой.

| `beatapi_position`        | Значение                                                                       |
| ------------------------- | ------------------------------------------------------------------------------ |
| `lowest`                  | Только у BeatAPI минимальная ранжированная цена.                               |
| `tied_lowest`             | BeatAPI делит минимальную цену хотя бы с одной другой платформой.              |
| `not_lowest`              | Другая платформа дешевле.                                                      |
| `insufficient_comparison` | BeatAPI ранжирован, но других ранжированных платформ нет, сравнивать не с чем. |
| `not_compared`            | BeatAPI не ранжирован, например потому что в `providers` нет `beatapi`.        |

## Если модель неоднозначна

Имя, которому соответствует несколько моделей, возвращает `200` с `needs_clarification`:

```bash
curl https://api.beatapi.io/v1/price-comparisons \
  -H "Content-Type: application/json" \
  -d '{"model":"banana pro"}'
```

```json
{
  "data": {
    "status": "needs_clarification",
    "model_candidates": ["Nano Banana Pro", "Nano Banana Pro Standard"],
    "spec": null,
    "questions": ["Which model do you want to compare? Send one of model_candidates as model."],
    "quotes": [],
    "summary": null,
    "data_version": "quotes-684-1794391200",
    "generated_at": "2026-11-11T10:00:00Z"
  }
}
```

Отправьте одного кандидата без изменений в `model`. Точное имя, slug или ID спецификации всегда важнее частичного совпадения, поэтому `Nano Banana Pro` соответствует одной модели. Имя, которому не соответствует ни одна модель, тоже возвращает `needs_clarification`, но без `model_candidates`.

## Ошибки

Ошибки возвращаются в стандартном [объекте ошибки](/errors). Запрос, который нужно исправить, возвращает `400 bad_request` с сообщением о проблеме:

| Причина                             | `message`                                                                                      |
| ----------------------------------- | ---------------------------------------------------------------------------------------------- |
| Тело запроса — не корректный JSON   | `Invalid price comparison request.`                                                            |
| `spec` не относится к модели        | `spec "nano-banana-2-1k" is not a spec of Nano Banana Pro; see GET /v1/pricing for its specs.` |
| Неизвестная платформа в `providers` | `unknown provider "example".`                                                                  |
| Платформа указана дважды            | `provider "fal" is listed twice.`                                                              |
| `model` или `spec` слишком длинные  | `model and spec must be at most 200 characters.`                                               |
| Больше 20 платформ                  | `providers may list at most 20 entries.`                                                       |

Не отправляйте `400` повторно без изменений. `500 internal_error` означает, что сравнение не удалось рассчитать; повторите один раз, затем обратитесь в поддержку с `request_id`.