999cdk

Публичный API v1

JSON на входе и выходе. API-ключ не нужен — сам код активации служит авторизацией. Кликните на эндпоинт чтобы раскрыть.

POST /api/v1/activate

Запускает асинхронную активацию ChatGPT-ключа (PLUS / GO). Возвращает session-токен для опроса статуса.

Активация ChatGPT — асинхронная: этот вызов резервирует ключ и запускает выдачу, дальше опрашивайте /api/v1/chatgpt/status пока не вернётся completed или failed. Обычно несколько секунд.

Тело запроса

полетипописание
cdk string Код 4×5 символов через дефис, например PLUSX-XXXXX-XXXXX-XXXXX. Регистр не важен.
type "full" | "acc_id" Что именно лежит в поле value.
value string UUID пользователя или JSON session-токен — см. примеры ниже.
session string Опционально. Передайте существующий session-токен вместо cdk+type+value, чтобы продолжить или перезапустить активацию.

Соответствие type / value

типзначение должно бытьпример
acc_id UUID в нижнем регистре, 8-4-4-4-12. c7dadb6d-47d1-4d31-956d-ed73b29b5051
full JSON-строка с полем account.id на верхнем уровне (UUID). {"account":{"id":"c7dadb6d-..."},"user":{...}}

Несоответствие (например type=full с голым UUID или type=acc_id с JSON) → 400, без побочных эффектов.

Пример — type: "acc_id"

Запрос

POST /api/v1/activate HTTP/1.1
Content-Type: application/json

{
  "cdk":   "PLUSX-XXXXX-XXXXX-XXXXX",
  "type":  "acc_id",
  "value": "c7dadb6d-47d1-4d31-956d-ed73b29b5051"
}

Ответ — 200 OK

{
  "ok": true,
  "status": "processing",
  "session": "a1b2c3d4e5f6a7b8c9d0...",
  "message": "Активация начата."
}

Пример — type: "full"

Когда у вас на руках полный JSON session-токен прямо из iOS-приложения. Сервер сам вытащит account.id — вам не нужно его парсить.

Запрос

POST /api/v1/activate HTTP/1.1
Content-Type: application/json

{
  "cdk":  "PLUSX-XXXXX-XXXXX-XXXXX",
  "type": "full",
  "value": "{\"WARNING_BANNER\":\"!!...\",\"account\":{\"id\":\"c7dadb6d-47d1-4d31-956d-ed73b29b5051\"},\"user\":{...}}"
}

Ответ — 200 OK

{
  "ok": true,
  "status": "processing",
  "session": "a1b2c3d4e5f6a7b8c9d0...",
  "message": "Активация начата."
}

Сохраните session — по нему опрашивается статус и возобновляется активация. Страница статуса в вебе — это /?s=<session>.

Коды ответа HTTP

кодсообщениесмысл
200processingКлюч зарезервирован, активация запущена. Опрашивайте статус.
200completedЭтот ключ уже был активирован ранее — вернётся та же session.
400разныеНекорректный запрос: битый JSON, отсутствует поле, неверный формат ключа или несоответствие type/value.
404CDK not foundТакого ключа нет в базе.
409CDK already usedКлюч уже использован ранее. В сообщении может быть email активировавшего.
409CDK is disabledКлюч отключён администратором.
409другой пользователь уже активируетЭтот же ключ сейчас активируется на другой app_user_id. Подождите 2-3 минуты до завершения.
410Этот ключ устарелПродавец пометил эту партию ключей устаревшей. Попросите свежий ключ.
413payload too largeТело запроса больше 128 KB. Подрежьте session-токен.
429too many requests, slow downRate-limit или авто-бан. Подождите и повторите.

cURL

curl -X POST https://999cdk.store/api/v1/activate \
  -H 'Content-Type: application/json' \
  -d '{
        "cdk":   "PLUSX-XXXXX-XXXXX-XXXXX",
        "type":  "acc_id",
        "value": "c7dadb6d-47d1-4d31-956d-ed73b29b5051"
      }'

Python

import requests, time

r = requests.post('https://999cdk.store/api/v1/activate', json={
    'cdk':   'PLUSX-XXXXX-XXXXX-XXXXX',
    'type':  'acc_id',
    'value': 'c7dadb6d-47d1-4d31-956d-ed73b29b5051',
}, timeout=15)
data = r.json()
if not data['ok']:
    raise SystemExit(f"start failed: {data.get('message')}")

session = data['session']
print('started', session)

# Poll until terminal status
deadline = time.time() + 300  # 5 min cap
while time.time() < deadline:
    time.sleep(2)
    s = requests.get(f'https://999cdk.store/api/v1/chatgpt/status?session={session}', timeout=10).json()
    if s.get('status') == 'completed':
        print('activated, expires:', s.get('expires_date'))
        break
    if s.get('status') == 'failed':
        print('failed:', s.get('error'))
        break
else:
    print('timeout, still processing — keep polling later')
GET /api/v1/chatgpt/status

Опрашивает статус ChatGPT-активации по session-токену.

Параметры запроса

полетипописание
session string Session-токен, который вернул /activate.

Запрос

GET /api/v1/chatgpt/status?session=a1b2c3d4e5f6... HTTP/1.1

Ответ — 200 OK (processing)

{
  "ok": true,
  "status": "processing",
  "message": "Активация выполняется…",
  "cdk": "PLUSX-XXXXX-XXXXX-XXXXX",
  "expires_date": null,
  "success_message": null,
  "error": null,
  "created_at": 1781167306
}

Ответ — 200 OK (completed)

{
  "ok": true,
  "status": "completed",
  "message": "Подписка активирована.",
  "cdk": "PLUSX-XXXXX-XXXXX-XXXXX",
  "expires_date": "2026-07-11T11:42:01Z",
  "success_message": "Спасибо за покупку!",
  "error": null,
  "created_at": 1781167306
}

Ответ — 200 OK (failed)

{
  "ok": true,
  "status": "failed",
  "message": "Не удалось активировать…",
  "cdk": "PLUSX-XXXXX-XXXXX-XXXXX",
  "expires_date": null,
  "success_message": null,
  "error": "RC HTTP 400 code 7102 …",
  "created_at": 1781167306
}

Значения status

статуссмысл
processingАктивация идёт — продолжайте опрашивать (каждые 2-3 сек).
completedГотово — подписка привязана. Ключ помечен использованным. Заполнены expires_date и опциональное success_message.
failedАктивация не удалась; причина в error. Ключ освобождён — клиент может перезапустить через POST {session} на /activate.

404 — неизвестный session (неверный токен или истёк после 15-мин TTL).

cURL

curl 'https://999cdk.store/api/v1/chatgpt/status?session=a1b2c3d4e5f6...'
POST /api/v1/claude/activate

Запускает асинхронную активацию Claude Pro. Возвращает session-токен для опроса статуса.

Активация Claude — асинхронная: этот вызов резервирует ключ и запускает выдачу, дальше опрашивайте /api/v1/claude/status пока не вернётся completed или failed. Обычно 1–2 минуты.

Тело запроса

полетипописание
cdk string Ключ Claude, например CLAUD-XXXXX-XXXXX-XXXXX. Регистр не важен.
org_id string Organization ID покупателя — UUID со страницы claude.ai → Settings → Account. К этой организации привяжется Claude Pro.
session string Опционально. Передайте существующий session-токен вместо cdk+org_id, чтобы продолжить или перезапустить активацию.

Запрос

POST /api/v1/claude/activate HTTP/1.1
Content-Type: application/json

{
  "cdk":    "CLAUD-XXXXX-XXXXX-XXXXX",
  "org_id": "c7dadb6d-47d1-4d31-956d-ed73b29b5051"
}

Ответ — 200 OK

{
  "ok": true,
  "status": "processing",
  "session": "a1b2c3d4e5f6a7b8c9d0...",
  "message": "Активация начата."
}

Сохраните session — по нему опрашивается статус и возобновляется активация. Страница статуса в вебе — это /claude/?session=<session>.

Коды ответа HTTP

кодсообщениесмысл
200processingКлюч зарезервирован, активация запущена. Опрашивайте статус.
200completedЭтот ключ уже был активирован ранее — вернётся та же session.
400разныеНет cdk/org_id, неверный формат ключа, некорректный Organization ID, либо ключ не для Claude.
403CDK is disabledКлюч отключён администратором.
404CDK not foundТакого Claude-ключа нет в базе.
409CDK is in useКлюч сейчас активируется другим запросом. Повторите чуть позже.
429too many requests…Rate-limit или авто-бан. Подождите и повторите.

cURL

curl -X POST https://999cdk.store/api/v1/claude/activate \
  -H 'Content-Type: application/json' \
  -d '{
        "cdk":    "CLAUD-XXXXX-XXXXX-XXXXX",
        "org_id": "c7dadb6d-47d1-4d31-956d-ed73b29b5051"
      }'
GET /api/v1/claude/status

Опрашивает статус активации Claude по session-токену.

Параметры запроса

полетипописание
session string Session-токен, который вернул /claude/activate.

Запрос

GET /api/v1/claude/status?session=a1b2c3d4e5f6... HTTP/1.1

Ответ — 200 OK

{
  "ok": true,
  "status": "processing",
  "message": "Активация выполняется…",
  "cdk": "CLAUD-XXXXX-XXXXX-XXXXX",
  "created_at": 1769841121
}

Значения status

статуссмысл
processingАктивация идёт — продолжайте опрашивать (например каждые 3–5 с).
completedГотово — Claude Pro привязан к организации покупателя. Ключ помечен использованным.
failedАктивация не удалась; ключ не был использован.

404 — неизвестный session (неверный токен или истёк).

POST /api/v1/claude/reactivate

Повторно привязывает уже купленную подписку к аккаунту Claude — для «зависшего» ключа, который показывает «использован», но Pro так и не появился.

Используйте, только если ключ уже used, но Claude Pro нет. Аккаунт должен быть на бесплатном плане. Мы повторно отправляем сохранённый чек Apple в claude.ai с sessionKey аккаунта. Синхронно — один вызов, без опроса статуса.

Тело запроса

полетипописание
cdk string Тот же ключ Claude, например CLAUD-XXXXX-XXXXX-XXXXX. Должен быть уже used.
session_key string Куки sessionKey аккаунта с claude.ai (DevTools → Application → Cookies → claude.ai → sessionKey). Начинается с sk-ant-sid.

Запрос

POST /api/v1/claude/reactivate HTTP/1.1
Content-Type: application/json

{
  "cdk":         "CLAUD-XXXXX-XXXXX-XXXXX",
  "session_key": "sk-ant-sid02-..."
}

Ответ — 200 OK

{
  "ok": true,
  "message": "Запрос принят. Если sessionKey от того же аккаунта (Organization ID)…"
}

ok:true возвращается сразу, как только ключ прошёл проверки (он used и не на кулдауне). Повтор для одного ключа — не чаще раза в 2 минуты.

Коды ответа HTTP

кодсообщениесмысл
200ok:trueПереотправка принята. Обновите Claude через 1–2 минуты.
400разныеНет cdk/session_key либо session_key неверного формата.
404CDK not foundТакого Claude-ключа нет в базе.
409непригоденКлюч ещё не used, либо по нему нет сохранённого чека.
429cooldownТот же ключ переотправляли менее 2 минут назад. Подождите и повторите.

cURL

curl -X POST https://999cdk.store/api/v1/claude/reactivate \
  -H 'Content-Type: application/json' \
  -d '{
        "cdk":         "CLAUD-XXXXX-XXXXX-XXXXX",
        "session_key": "sk-ant-sid02-..."
      }'
POST /api/v1/check

Read-only проверка одного ключа или ссылки активации. Возвращает good / used / invalid.

Тело запроса

codes — JSON-массив с одним элементом: либо голый код, либо полная ссылка активации ?cdk=….

POST /api/v1/check HTTP/1.1
Content-Type: application/json

{
  "codes": [ "PLUSX-XXXXX-XXXXX-XXXXX" ]
}

Ответ — 200 OK

{
  "ok": true,
  "results": [
    { "input":  "PLUSX-XXXXX-XXXXX-XXXXX",
      "code":   "PLUSX-XXXXX-XXXXX-XXXXX",
      "status": "good", "reason": null,
      "plan":   "plus",
      "email":  null, "used_at": null,
      "acc_id": null, "org_id": null }
  ]
}

Поля результата

полеописание
status good — существует, не использован. used — уже активирован. invalid — некорректный формат, не найден или отключён.
reason Только для invalid: bad_format, not_found или disabled. Иначе null.
email Для used-кодов, активированных полным токеном — email активировавшего, если был сохранён. Иначе null.
used_at Для used-кодов — время активации (YYYY-MM-DD HH:MM). Иначе null.
plan План этого ключа: plus, go или claude.
org_id Для used-кодов claude — Organization ID покупателя, к которому привязали Claude Pro. Иначе null.
acc_id Для used-кодов ChatGPT — UUID аккаунта, на который активировали, если выводится. Иначе null.

Пример — использованный Claude-код

Использованный claude-код возвращает org_id покупателя — удобно посмотреть, кому он активирован.

{
  "ok": true,
  "results": [
    { "input":  "CLAUD-XXXXX-XXXXX-XXXXX",
      "code":   "CLAUD-XXXXX-XXXXX-XXXXX",
      "status": "used", "reason": null,
      "plan":   "claude",
      "email":  null, "used_at": "2026-05-30 04:32",
      "acc_id": null,
      "org_id": "c7dadb6d-47d1-4d31-956d-ed73b29b5051" }
  ]
}