spicyapiДокументация
Разработка с API
Основное содержимое

Расчёт цены и совместимость протоколов

Как узнать точную цену запроса до оплаты, отправить его ровно по этой цене, не заплатить дважды после потерянного ответа и как тарифицируются совместимые API для текста и видео.

Расчёт стоимости для конкретного запроса

Расчёт стоимости (quote) сообщает цену одного конкретного запроса ещё до того, как вы заплатите. Он бесплатный, не создаёт задачу и не резервирует средства. После этого вы отправляете тот же самый запрос вместе с расчётом, и его примут только по той цене, которую вам показали.

Команды ниже рассчитаны на терминал macOS или Linux, в котором SPICY_API_KEY задан так, как описано в Быстром старте. MODEL_ID_FROM_CATALOG — это заполнитель: подставьте вместо него значение model из актуального каталога (GET /api/v1/models), а все поля input берите из схемы этой модели.

Сохраните запрос, который собираетесь отправить

Создайте файл request.json и запишите в него ровно те model, input и необязательный callBackUrl, которые будете отправлять:

request.json
{
  "model": "MODEL_ID_FROM_CATALOG",
  "input": { "prompt": "A cinematic night portrait" }
}

Запросите цену

curl https://api.spicyapi.ai/api/v1/jobs/quote \
  -H "Authorization: Bearer $SPICY_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @request.json
{
  "code": 200,
  "msg": "success",
  "data": {
    "quoteId": "QUOTE_ID_FROM_RESPONSE",
    "model": "MODEL_ID_FROM_CATALOG",
    "estimatedCost": "0.008",
    "maxCharge": "0.008",
    "currency": "USD",
    "quantity": "1",
    "unit": "per_image",
    "expiresAt": "2026-09-17T10:05:00Z"
  },
  "request_id": "req_01k3m8x9q2z4v7n5p6r8s0t1w2"
}

Суммы приходят в долларах США, в виде десятичных чисел, записанных строкой. maxCharge — это максимум, который может стоить этот запрос; сейчас он всегда равен estimatedCost. quantity и unit показывают, что именно считается, например секунды видео. Покажите сумму и expiresAt тому, кто одобряет расход.

Расчёт стоимости проходит те же проверки, что и настоящая отправка, поэтому ошибка может прийти уже на этом шаге: 400 (входные данные не соответствуют схеме модели), 40201 (на балансе недостаточно средств), 40202 (достигнут лимит расходов ключа или квота платформы) или 403 (этому ключу нельзя пользоваться этой моделью).

Отправьте тот же запрос вместе с расчётом

В течение пяти минут отправьте в createTask тот же запрос без изменений, добавив к нему два поля: quoteId из расчёта и expectedCost, равный estimatedCost из расчёта. Этот шаг стоит денег.

submit.json
{
  "model": "MODEL_ID_FROM_CATALOG",
  "input": { "prompt": "A cinematic night portrait" },
  "quoteId": "QUOTE_ID_FROM_RESPONSE",
  "expectedCost": "0.008"
}
SPICY_IDEMPOTENCY_KEY="$(uuidgen)"   # один раз на каждую новую задачу; повторно — только для переотправки этого же запроса

curl https://api.spicyapi.ai/api/v1/jobs/createTask \
  -H "Authorization: Bearer $SPICY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $SPICY_IDEMPOTENCY_KEY" \
  --data-binary @submit.json

В ответ придёт обычное подтверждение 202 Accepted о принятой задаче, как в Быстром старте. Расчёт стоимости не заменяет Idempotency-Key: отправляйте и то и другое.

Расчёт стоимости привязан кОн перестаёт действовать, если
Вашему аккаунту и API-ключу, которым его запросилиВы отправляете запрос другим ключом
Точным значениям model, input и callBackUrlМеняется хотя бы одно из них — даже один символ промпта. Порядок полей и пробелы значения не имеют
Цене на момент расчётаПрошло пять минут или изменилась цена

40901 означает, что расчёт больше не соответствует запросу

Изменённые входные данные, другой API-ключ, истёкший расчёт, изменившаяся цена или expectedCost, который не совпадает с расчётом, — всё это выглядит одинаково: запрос не принимается с кодом 40901, и ничего не списывается. Запросите расчёт и подтвердите цену заново. Не убирайте quoteId и expectedCost, чтобы протолкнуть запрос без согласованной цены.

POST /api/v1/jobs/stream, нативный текстовый поток, принимает расчёт стоимости точно так же; см. Текст и потоковые ответы.

Если ответ потерялся

Если отправка завершилась по таймауту или соединение оборвалось, вы не знаете, принят ли запрос. Для createTask, retry и POST /v1/videos действуйте так:

  1. Отправьте исходный запрос ещё раз с исходным Idempotency-Key и тем же API-ключом. Вам вернётся исходная задача в её текущем состоянии, и второй раз с вас не спишут.
  2. Не создавайте ещё одну задачу с новым ключом. Новый ключ означает новую генерацию и новое списание.
  3. Повтор уже принятого запроса действует и после того, как срок расчёта стоимости истёк. Срок расчёта ограничивает только приём запроса, а не задачу, которая при этом приёме была создана.
  4. 409 не означает «задача не создана». Либо запрос изменился (это новая единица работы, и ей нужен новый ключ), либо его отправили другим API-ключом того же аккаунта (отправьте его исходным ключом). См. Идемпотентность.
  5. Итоговую сумму узнавайте по полям cost и settled в recordInfo.

Текстовые и потоковые запросы так восстановить нельзя

Ответ на текстовый запрос (/api/v1/jobs/stream и текстовые эндпоинты под /v1 и /v1beta) передаётся вам по мере генерации и нигде не сохраняется. Если снова отправить уже принятый ключ, вместо ответа придёт ошибка: 400, если тело запроса то же, и 409, если другое. Ничего сверх уже списанного не спишется, но потерянный ответ получить нельзя. Чтобы получить ответ ещё раз, отправьте запрос с новым ключом и оплатите его. Какие эндпоинты читают этот заголовок, описано на странице Идемпотентность.

Ориентировочная стоимость — ещё не окончательное списание

estimatedCost — это сумма, которую мы ожидаем списать. Маркер конца текста в потоке говорит лишь о том, что байты перестали приходить. Ни то, ни другое не доказывает, что списание окончательное. Для задач это доказывает settled: true рядом с cost в recordInfo. Текстовые вызовы не возвращают ID задачи: их списание ищите в списке задач того же API-ключа (GET /api/v1/jobs) или в разделе Консоль → Логи и считайте cost окончательным, когда settled равно true.

Расчёт стоимости в официальных инструментах

CLI и MCP-сервер сами получают расчёт стоимости и спрашивают человека перед каждым платным вызовом, так что строить этот шаг самостоятельно не нужно:

  • CLI: spicyapi tasks quote рассчитывает цену запроса; spicyapi tasks create получает расчёт заново, выводит сумму и спрашивает вас, прежде чем создать задачу. См. Стоимость, подтверждение и безопасность.
  • MCP: ассистент может запрашивать расчёты стоимости сколько угодно, но при создании задачи ваш ИИ-клиент спросит вас и покажет цену. См. Стоимость, подтверждение и безопасность.
  • SDK: quoteTask возвращает расчёт стоимости; передайте его quoteId и estimatedCost в createTask или run.

Агент не должен подтверждать за пользователя

Подтверждение нужно для того, чтобы решение принимал человек. Агент, который отвечает на него сам, или клиент, настроенный на автоматическое одобрение, убирает единственную границу расходов на этом пути.

Совместимость для текста и видео

SpicyAPI понимает также форматы OpenAI, Anthropic и Google Gemini для текстовых моделей и формат OpenAI Videos для видео. Полный список эндпоинтов — на странице OpenAPI и список эндпоинтов; запросы, потоки и ошибки для каждого протокола описаны на странице Текст и потоковые ответы.

Базовый URL. Формат OpenAI использует https://api.spicyapi.ai/v1. SDK Anthropic и Google GenAI сами добавляют /v1 или /v1beta, поэтому базовым URL для них указывайте https://api.spicyapi.ai.

Учётные данные. Для всех форматов подходит один и тот же API-ключ в заголовке Authorization: Bearer. Принимаются также заголовок x-api-key, которым пользуется SDK Anthropic, и заголовок x-goog-api-key, которым пользуется SDK Google GenAI. Параметр ?key= в URL не принимается никогда.

Модель. Выбирайте точную модель из актуального каталога. Будут ли работать инструменты (tools), сообщения с изображениями и параметры генерации, зависит от схемы этой модели, а не от выбранного протокола.

Форма ответа. Каждый протокол возвращает собственную оболочку ответа, а не платформенную {code, msg, data, request_id}.

Поля рассуждений

Чат-модели, которые показывают текст своих рассуждений, могут возвращать необязательную строку в message.reasoning_content, а при потоковой передаче — в delta.reasoning_content. Продолжая диалог после вызова инструмента, вы можете сохранить эту строку в соответствующем сообщении ассистента, если актуальная схема модели это поддерживает.

usage.completion_tokens_details.reasoning_tokens показывает долю рассуждений, уже включённую в completion_tokens; не прибавляйте её второй раз. Текст рассуждений и эти сведения о токенах возвращает не каждая модель.

Две особенности, о которых стоит знать заранее

  • Responses требует передавать в input всю переписку целиком. previous_response_id не поддерживается.
  • Videos принимает JSON с полями model, prompt, input_reference, seconds и size, которые сопоставляются с собственными полями модели. Возвращаемый id видео одновременно является ID задачи, который принимает recordInfo. Эндпоинт содержимого видео отвечает перенаправлением HTTP 302 на подписанный URL с коротким сроком действия.

Совместимые API берут цену в момент приёма

quoteId и expectedCost работают только с jobs/createTask и jobs/stream. /v1 и /v1beta берут цену, действующую в момент приёма запроса, и отклоняют эти два поля, поэтому подтвердить цену отдельного вызова на этом пути нельзя. Если процессу нужно подтверждать предел списания, пользуйтесь нативным API задач; чтобы ограничить всё, что может потратить ключ, задайте для него Дневной лимит, Месячный бюджет и Общий лимит — см. Аутентификация.

Пример потокового чата с официальными клиентами OpenAI, Anthropic и Google — в разделе Работа через официальный SDK. CLI и MCP-сервер отправляют нативные задачи и следят за ними; потоковую передачу токенов чата они не выполняют.

На этой странице