Prostor Docs
Public API

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

От нуля до первого ответа модели за несколько минут: ключ, base URL, curl, OpenAI SDK, стоимость запроса и баланс.

Prostor API — это один HTTP-эндпоинт к моделям: chat completions, Responses, изображения, видео и эмбеддинги. Один ключ, один общий баланс в кредитах, OpenAI-совместимый контракт.

Формально API повторяет форму OpenRouter: у нас есть GET /v1/models с ценами, GET /v1/credits, GET /v1/key и GET /v1/generation, а тела запросов и ответов — те же, что у OpenAI. Поэтому существующая интеграция с OpenAI или OpenRouter обычно заводится подменой base URL и ключа, без правок кода.

Base URL

text
https://api.prostor.ai/v1

Держите base URL и ключ в переменных окружения — все примеры ниже рассчитывают на это:

bash
export PROSTOR_API_BASE_URL="https://api.prostor.ai/v1"
export PROSTOR_API_KEY="pak_pr_v1_..."

Как получить ключ

Ключ создаётся в личном кабинете: Профиль → API-токены → «Создать токен». Задайте название, при необходимости ограничьте разрешения (scopes) и лимит расхода на токен — и сразу скопируйте значение pak_pr_v1_.... Там же можно посмотреть свои ключи и отозвать любой из них.

Ключ внешнего API всегда начинается с pak_pr_v1_. Полное значение показывается ровно один раз при создании; дальше в системе хранится только его хэш. Потеряли — создайте новый и отзовите старый. Токен привязан к вашему аккаунту и тратит его баланс.

Заметка

Если раздела «API-токены» в профиле ещё нет — самообслуживание пока не включено в вашем аккаунте. Напишите в поддержку, и мы выдадим ключ вручную (лимиты, scopes и список моделей настраиваются на нашей стороне).

Важно

Ключ pak_pr_v1_... — это доступ к вашему балансу. Никогда не кладите его в браузерный бандл, мобильное приложение, публичный репозиторий или в конфиг фронтенда: любой, кто его достанет, будет тратить ваши кредиты. Вызывайте Prostor API только со своего бэкенда. При утечке немедленно отзовите ключ в разделе «API-токены».

Первый вызов

Проверьте, что ключ работает

GET /v1/models возвращает модели, доступные именно вашему ключу, вместе с ценами. Это же первый шаг любой интеграции: не хардкодьте ID моделей — берите их отсюда. Набор моделей зависит от ключа (allowed_models) и со временем меняется.

bash
curl -s "$PROSTOR_API_BASE_URL/models" \
  -H "Authorization: Bearer $PROSTOR_API_KEY" | jq '.data[] | {id, name, category}'

Каждый элемент data[] содержит id (его и передавайте в model), name, category (text | image | video | embeddings | …), architecture, pricing и блок prostor с ценой в кредитах.

Если ключ неверный — 401. Если баланс нулевой — 402 insufficient_credits: этот эндпоинт требует положительного баланса. Баланс при этом всегда можно прочитать через GET /v1/credits, он работает и при нуле.

Сделайте первый chat-запрос

Подставьте id из предыдущего шага вместо <model-id-from-/v1/models>:

bash
curl -s "$PROSTOR_API_BASE_URL/chat/completions" \
  -H "Authorization: Bearer $PROSTOR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "<model-id-from-/v1/models>",
    "messages": [
      {"role": "user", "content": "Скажи привет в одну строку."}
    ],
    "max_tokens": 256
  }' | jq .

Ответ — обычный OpenAI-совместимый объект с choices[0].message.content.

Незнакомый model дает 404 model_not_found с сообщением unknown model: X — call GET /v1/models for the models this key can use. Это не сбой провайдера и повторять запрос бессмысленно: исправьте ID.

Посмотрите, сколько это стоило

Стоимость возвращается в самом ответе, в блоке usage:

json
{
  "usage": {
    "prompt_tokens": 24,
    "completion_tokens": 61,
    "total_tokens": 85,
    "cost": 0.02,
    "cost_details": {
      "billed_credits": 2,
      "markup_included": true
    },
    "is_estimated": false,
    "interrupted": false
  }
}

usage.cost — это сумма, которую списали с вас, в долларах. usage.cost_details.billed_credits — то же самое в кредитах, целым числом; именно эта величина ушла с баланса. Курс фиксированный: 100 кредитов = $1 (credits_per_usd в /v1/models и /v1/credits).

То же число дублируется в заголовке ответа:

bash
curl -s -D - -o /dev/null "$PROSTOR_API_BASE_URL/chat/completions" \
  -H "Authorization: Bearer $PROSTOR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"<model-id-from-/v1/models>","messages":[{"role":"user","content":"ping"}],"max_tokens":16}' \
  | grep -i -E 'x-request-id|x-prostor-cost-credits'
text
X-Request-Id: ...
X-Prostor-Cost-Credits: 5

X-Request-Id (он же X-Generation-Id) — идентификатор генерации: цитируйте его в баг-репортах и передавайте в GET /v1/generation?id=..., чтобы позже перечитать статус, токены и списание. X-Prostor-Cost-Credits приходит только когда списание больше нуля и не приходит на стриминге (там цена еще не известна к моменту отправки заголовков — смотрите usage в финальном чанке).

Обратите внимание на округление: списывается целое число кредитов с округлением вверх до целого. Поэтому крошечный запрос стоит минимум 1 кредит ($0.01), а не долю цента. Подробности — в разделе про тарификацию.

Проверьте баланс

bash
curl -s "$PROSTOR_API_BASE_URL/credits" \
  -H "Authorization: Bearer $PROSTOR_API_KEY" | jq .
json
{
  "data": {
    "total_credits": 50.0,
    "total_usage": 12.34
  },
  "prostor": {
    "balance_credits": 3766,
    "balance_usd": 37.66,
    "granted_credits": 5000,
    "spent_credits": 1234,
    "api_usage_credits": 210,
    "api_usage_usd": 2.1,
    "credits_per_usd": 100
  }
}

Кошелек общий с веб-приложением Prostor: total_usage — это все траты по всем поверхностям, а api_usage_* — только та часть, что прошла через этот API.

Drop-in: OpenAI SDK

Отдельный SDK не нужен. Берите официальный клиент OpenAI и меняете base_url — остальное работает как есть.

Python:

python
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["PROSTOR_API_KEY"],
    base_url="https://api.prostor.ai/v1",
)

completion = client.chat.completions.create(
    model="<model-id-from-/v1/models>",
    messages=[{"role": "user", "content": "Скажи привет в одну строку."}],
    max_tokens=256,
)

print(completion.choices[0].message.content)
print(completion.usage.model_dump())  # cost, cost_details.billed_credits

JavaScript / TypeScript:

js
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.PROSTOR_API_KEY,
  baseURL: "https://api.prostor.ai/v1",
});

const models = await client.models.list();
const model = models.data[0].id; // или конкретный id из GET /v1/models

const completion = await client.chat.completions.create({
  model,
  messages: [{ role: "user", content: "Скажи привет в одну строку." }],
  max_tokens: 256,
});

console.log(completion.choices[0]?.message?.content);
console.log(completion.usage); // cost, cost_details.billed_credits

Три вещи, о которых лучше узнать сейчас

Всегда передавайте max_tokens. Перед вызовом мы удерживаем на балансе резерв под худший случай, и если max_tokens не задан, резерв считается по потолку в 8192 выходных токенов. Несколько параллельных запросов без max_tokens могут «съесть» баланс холдами и получить 402 insufficient_credits, хотя реальный расход был бы копеечным. Неиспользованная часть резерва возвращается после ответа, но лимит на момент запроса проверяется по нему.

Явный max_tokens резервируется и форвардится как запрошено — вплоть до жёсткого потолка шлюза (по умолчанию 64000), а реальный предел модели дальше применяет уже провайдер (ответ с finish_reason: "length"). Значение 8192 — это лишь дефолт, который подставляется, только когда max_tokens не передан. Если у вашего ключа выставлен max_output_tokens (см. GET /v1/key), он служит жёстким потолком именно этого ключа. Актуальный достижимый потолок публикуется в GET /v1/models в top_provider.max_completion_tokens. Помните: запрос на 64000 токенов и холд резервирует под 64000 — держите достаточный баланс.

Стриминг stream: true на POST /v1/chat/completions работает, но не дает выигрыша по времени до первого токена: ответ собирается целиком и отдается одним пакетом корректных SSE-кадров в конце генерации. Если вам нужна настоящая пословная выдача — используйте POST /v1/responses, там стрим действительно инкрементальный.

Заметка

Массив models (fallback-список моделей в стиле OpenRouter) не поддерживается: запрос с ним вернет 400 unsupported_parameter. Передавайте одну модель в model, а фолбэк реализуйте на своей стороне. Учтите, что некоторые OpenRouter-обертки подставляют models автоматически.

Что дальше

СтраницаЗачем
Тарификация и кредитыкак считается списание, округление до целого кредита, резервы, флаг is_estimated, стоимость медиа
Ошибкиполный список кодов, HTTP-статусов и что с ними делать (в том числе 429 и Retry-After)
Полный справочник APIвсе эндпоинты: chat, responses, images, video, embeddings, ключ, генерации, идемпотентность, лимиты