Быстрый старт
От нуля до первого ответа модели за несколько минут: ключ, 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
https://api.prostor.ai/v1Держите base URL и ключ в переменных окружения — все примеры ниже рассчитывают на это:
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) и со временем меняется.
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>:
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:
{
"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).
То же число дублируется в заголовке ответа:
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'X-Request-Id: ...
X-Prostor-Cost-Credits: 5X-Request-Id (он же X-Generation-Id) — идентификатор генерации: цитируйте его в баг-репортах и передавайте в GET /v1/generation?id=..., чтобы позже перечитать статус, токены и списание. X-Prostor-Cost-Credits приходит только когда списание больше нуля и не приходит на стриминге (там цена еще не известна к моменту отправки заголовков — смотрите usage в финальном чанке).
Обратите внимание на округление: списывается целое число кредитов с округлением вверх до целого. Поэтому крошечный запрос стоит минимум 1 кредит ($0.01), а не долю цента. Подробности — в разделе про тарификацию.
Проверьте баланс
curl -s "$PROSTOR_API_BASE_URL/credits" \
-H "Authorization: Bearer $PROSTOR_API_KEY" | jq .{
"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:
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_creditsJavaScript / TypeScript:
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, ключ, генерации, идемпотентность, лимиты |