Адрес
/api/v1
Тела запросов и ответов в JSON, авторизации нет. Ключ активации и Session передавайте только в теле запроса, не в URL и не в логах.
Лимит с одного IP: 20 запусков активации в минуту. Сверх лимита ответ 429 с заголовком Retry-After в секундах. Опрос статуса не ограничен.
1. Запуск активации
POST /api/v1/activations
Idempotency-Key: order-12345
Content-Type: application/json
{"code": "CSR-PLUS-...", "session": "<текст страницы chatgpt.com/api/auth/session целиком>"}
Idempotency-Key необязателен, но передавайте его: латиница, цифры, . _ : -, до 80 символов, удобно взять номер заказа. Повтор с тем же Idempotency-Key и тем же ключом вернёт уже созданную операцию, вторая оплата не запустится. Без заголовка повтор получит 409 cdk_not_available, пока первая операция идёт.
Ответ 202 с операцией (формат ниже). Активация идёт в фоне, обычно 1-3 минуты.
2. Статус операции
GET /api/v1/activations/{id}
Опрашивайте раз в 5 секунд, пока status не станет конечным. ID операции открывает её статус и почту аккаунта, не публикуйте его.
{
"id": "3f0c...",
"status": "subscription_active",
"error_code": "",
"step": 4,
"plan": "plus",
"email": "buyer@example.com",
"masked_email": "b***r@example.com",
"action_url": "",
"created_at": 1791349622,
"updated_at": 1791349701
}
Статусы
| status | Что значит |
|---|---|
subscription_active | Готово, подписка включена. Ключ израсходован. |
failed | Не получилось, причина в error_code. Ключ не списан, его можно использовать снова. |
already_active | На аккаунте уже есть платная подписка. Списания не было, ключ не списан, его можно активировать на другом аккаунте. |
review | Оплата могла пройти, результат проверяется вручную. Не запускайте повторно, ключ заблокирован до проверки. |
requires_action | Платёж ждёт подтверждения покупателем: отдайте ему ссылку из action_url и продолжайте опрос. |
| остальные | created, validating, redeeming, payment_pending, verifying_subscription и другие: идёт работа, ждите. |
error_code
Заполнен при failed, review и already_active, в остальных статусах пустой.
| error_code | Что делать |
|---|---|
gpt_session_invalid | Session устарела. Попросите покупателя заново скопировать страницу и запустите с новым Idempotency-Key. |
unsupported_session_shape | В Session не хватает данных. Нужна страница целиком, а не только токен. |
session_or_account | Приходит со статусом review: аккаунт не принял оплату. Списания не было, но ключ ждёт ручной проверки. Обратитесь к продавцу ключа с ID операции. |
gpt_plan_already_active | Приходит со статусом already_active. Ключ можно активировать на другом аккаунте. |
payment_declined | Платёж отклонён. Повторите позже с новым Idempotency-Key. |
payment_cancelled | Платёж отменён. Можно повторить. |
service_busy | Сервис занят. Повторите через 2-5 минут. |
manual_review | Идёт ручная проверка (статус review). Обратитесь к продавцу ключа с ID операции. |
service_unavailable | Временный сбой. Повторите позже, при повторении обратитесь к продавцу ключа с ID операции. |
Ошибки запроса
Ответ с HTTP-ошибкой содержит {"detail": "код"}. Операция при этом не создаётся, ключ не тратится.
| HTTP | detail | Причина |
|---|---|---|
| 400 | invalid_idempotency_key | Нет заголовка Idempotency-Key или в нём лишние символы. |
| 400 | cdk_not_registered | Ключ не найден. Проверьте, что скопирован целиком. |
| 409 | cdk_not_available | Ключ уже использован, отозван или сейчас активируется. |
| 409 | idempotency_key_conflict | Этот Idempotency-Key уже занят другой операцией. Возьмите новый. |
| 422 | session_must_be_json, session_token_required, unsupported_session_shape | Session не того формата: нужна страница chatgpt.com/api/auth/session целиком. |
| 422 | список полей | Не хватает полей в теле или лишние поля. Допустимы только code и session. |
| 404 | job_not_found | Операции с таким ID нет. |
| 429 | too_many_requests | Превышен лимит запусков с вашего IP. Повторите через Retry-After секунд. |
Пример на curl
curl -s -X POST /api/v1/activations \ -H "Idempotency-Key: order-12345" \ -H "Content-Type: application/json" \ --data @activation.json curl -s /api/v1/activations/$JOB_ID
В activation.json: {"code": "...", "session": "..."}. Session передаётся строкой: текст страницы как есть, с экранированием кавычек по правилам JSON.