Для AI-агентов: markdown этой страницы — /docs-content/cowork/relay-ticket.md индекс документации — /llms.txt
Билет для телефонного доступа
POST /v1/cowork/relay-ticket
Выдаёт десктопу Cowork/Code подписанный билет для подключения к ретранслятору — серверу, через который телефон получает доступ к десктопу. Платформа только подтверждает, кто подключается: трафик через неё не идёт, а десктоп не регистрируется как сервер.
Билет действует 5 минут и привязан к публичному ключу десктопа из тела запроса: с другим ключом ретранслятор его не примет. Держите билет в памяти и используйте его для переподключений, пока до expiresAt остаётся больше 60 секунд. Когда до expiresAt остаётся 60 секунд или меньше, при следующем подключении запросите новый билет.
Скоуп: vibe:cowork плюс класс ключа десктопа Cowork/Code. У владельца ключа должно быть активное место Cowork/Code.
Поля запроса (body)
| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
pubkey |
string | да | Публичный ключ Ed25519, которым десктоп представляется ретранслятору: ровно 32 байта в base64url без знаков = в конце — 43 символа |
Примеры
Эндпоинт принимает только ключ десктопа Cowork/Code, поэтому примеров два.
curl — ключ десктопа Cowork/Code
curl -X POST https://vibecode.bitrix24.tech/v1/cowork/relay-ticket \
-H "X-Api-Key: YOUR_COWORK_KEY" \
-H "Content-Type: application/json" \
-d '{"pubkey": "11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo"}'
JavaScript — ключ десктопа Cowork/Code
let cached = null
async function getRelayTicket(pubkey) {
// Переиспользуем билет, пока до истечения больше 60 секунд
if (cached && Date.parse(cached.expiresAt) - Date.now() > 60_000) {
return cached.ticket
}
const res = await fetch('https://vibecode.bitrix24.tech/v1/cowork/relay-ticket', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_COWORK_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({ pubkey }),
})
if (!res.ok) {
const { error } = await res.json()
throw new Error(`${res.status} ${error.code}`)
}
cached = await res.json() // { ticket, expiresAt } — без обёртки success/data
return cached.ticket
}
Поля ответа
| Поле | Тип | Описание |
|---|---|---|
ticket |
string | Токен JWS (JSON Web Signature) в компактной записи с подписью EdDSA. Передавайте его ретранслятору как есть |
expiresAt |
string | Момент истечения билета (ISO 8601), через 5 минут после выдачи |
Для справки: заголовок билета несёт alg: "EdDSA", typ: "JWT" и kid ключа подписи. В полезной нагрузке лежат typ: "cowork-relay-ticket", iss: "vibecode-platform", aud: "cowork-relay", sub и portal, cnf.jwk, в поле x которого лежит переданный pubkey, а также jti, iat и exp. Поля sub и portal — псевдонимы: ретранслятор различает по ним пользователей и аккаунты, но настоящих идентификаторов не узнаёт.
Пример ответа
Значение ticket сокращено:
{
"ticket": "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCIsImtpZCI6Ii4uLiJ9.eyJ0eXAiOiJjb3dvcmstcmVsYXktdGlja2V0Ii4uLn0.c2lnbmF0dXJl",
"expiresAt": "2026-09-22T12:05:00.000Z"
}
Пример ответа при ошибке
403 — ключ со скоупом vibe:cowork, но не от десктопа Cowork/Code:
{
"success": false,
"error": {
"code": "COWORK_DESKTOP_KEY_REQUIRED",
"message": "Only a Cowork/Code desktop key may request a relay ticket."
}
}
Ошибки
| HTTP | Код | Описание |
|---|---|---|
| 400 | INVALID_PUBKEY |
Поле pubkey не передано или не является 32-байтовым ключом в base64url без знаков = в конце |
| 400 | FST_ERR_CTP_EMPTY_JSON_BODY |
Передан заголовок Content-Type: application/json, а тело пустое |
| 400 | FST_ERR_CTP_INVALID_JSON_BODY |
Тело не разбирается как JSON |
| 401 | MISSING_API_KEY |
Не передан заголовок X-Api-Key |
| 401 | INVALID_API_KEY |
Ключ не опознан: такой строки на платформе нет |
| 401 | KEY_INACTIVE |
Ключ отозван — например, устройство отключили через DELETE /v1/cowork/key |
| 401 | KEY_EXPIRED |
Срок действия ключа истёк |
| 402 | ACCOUNT_FROZEN |
Счёт заморожен из-за отрицательного баланса. Этот вызов с баланса не оплачивается, поэтому отказ приходит, только пока на аккаунте действуют прежние правила заморозки. Новые правила закрывают лишь платные вызовы, платформа включает их постепенно |
| 403 | INSUFFICIENT_SCOPE |
У ключа нет скоупа vibe:cowork |
| 403 | COWORK_DESKTOP_KEY_REQUIRED |
Ключ не относится к классу десктопа Cowork/Code — такой отказ получает и ключ агентского места, и ключ стороннего агента |
| 403 | COWORK_SEAT_INACTIVE |
Место Cowork/Code есть, но его состояние не ACTIVE, а PAUSED, PARKED или CANCELLED |
| 403 | WRITE_BLOCKED_READONLY_KEY |
Ключ выпущен в режиме «только чтение» |
| 404 | COWORK_NOT_ACTIVATED |
У владельца ключа нет места Cowork/Code на этом аккаунте |
| 413 | PAYLOAD_TOO_LARGE |
Тело больше 4 КБ |
| 415 | FST_ERR_CTP_INVALID_MEDIA_TYPE |
Тело прислано с типом содержимого, который этот маршрут не разбирает. Отправляйте тело с заголовком Content-Type: application/json |
| 429 | RATE_LIMITED |
Превышен лимит запросов одного пользователя в аккаунте — несколько ключей одного пользователя делят общий лимит. Суммарный лимит платформы — 30 запросов в час. Действующее для вашего ключа значение приходит в заголовке x-ratelimit-limit — оно ниже суммарного, поскольку лимит делится между репликами |
| 503 | COWORK_FEATURE_DISABLED |
Cowork/Code отключён на уровне платформы |
| 503 | COWORK_RELAY_NOT_CONFIGURED |
Выдача билетов сейчас недоступна на этой платформе |
Полный список общих ошибок API — Ошибки.
Известные особенности
Успешный ответ (200) — это сам объект, без обёртки success. Ошибки приходят в конверте { success: false, error: { code, message } }. Определяйте успех по HTTP-статусу (res.ok).
Билет не сохраняется на платформе. Каждый вызов выдаёт новый билет, а прежние действуют до своего expiresAt. Отозвать выданный билет нельзя.
Эндпоинт сначала проверяет, доступна ли выдача билетов, и только потом — тело запроса. Пока выдача билетов недоступна, эндпоинт отвечает 503 COWORK_RELAY_NOT_CONFIGURED даже на запрос с неверным pubkey.
Как реагировать на отказы.
401— попросите пользователя войти заново.400,403 INSUFFICIENT_SCOPEи403 COWORK_DESKTOP_KEY_REQUIRED— повтор вернёт тот же отказ, исправьте запрос или ключ.404 COWORK_NOT_ACTIVATEDи403 COWORK_SEAT_INACTIVE— пользователю нужно активное место Cowork/Code.503— состояние платформы, а не проблема ключа: повторите позже.429— повторяйте с растущей паузой.