Для AI-агентов: markdown этой страницы — /docs-content/infra/access-tokens/refresh.md индекс документации — /llms.txt
Обновить токен доступа
POST /v1/infra/servers/:id/access-tokens/:tokenId/refresh
Выпускает свежий JWT для уже существующего токена режима api-bearer — без создания новой записи. Долгоживущий клиент (CI, AI-агент) вызывает обновление перед истечением jwtExpiresAt вместо выпуска нового токена: обновление не расходует ни лимит активных токенов, ни лимит выпусков в час.
Тело запроса не требуется.
Параметры
| Параметр | В | Тип | Обяз. | Описание |
|---|---|---|---|---|
id |
path | string (UUID) | да | ID BLACKHOLE-сервера. Список: GET /v1/infra/servers |
tokenId |
path | string (UUID) | да | ID токена api-bearer — поле data.id из ответа на выпуск или элемент списка токенов |
Примеры
curl — личный ключ
curl -X POST "https://vibecode.bitrix24.tech/v1/infra/servers/SERVER_ID/access-tokens/TOKEN_ID/refresh" \
-H "X-Api-Key: YOUR_API_KEY"
curl — OAuth-приложение
curl -X POST "https://vibecode.bitrix24.tech/v1/infra/servers/SERVER_ID/access-tokens/TOKEN_ID/refresh" \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN"
JavaScript — личный ключ
const res = await fetch(
`https://vibecode.bitrix24.tech/v1/infra/servers/${serverId}/access-tokens/${tokenId}/refresh`,
{
method: 'POST',
headers: { 'X-Api-Key': 'YOUR_API_KEY' },
}
)
const { data } = await res.json()
console.log(data.token, data.jwtExpiresAt)
JavaScript — OAuth-приложение
const res = await fetch(
`https://vibecode.bitrix24.tech/v1/infra/servers/${serverId}/access-tokens/${tokenId}/refresh`,
{
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
},
}
)
const { data } = await res.json()
Поля ответа
| Поле | Тип | Описание |
|---|---|---|
success |
boolean | Всегда true при успехе |
data.id |
string | ID токена — тот же, что и при выпуске (новая запись не создаётся) |
data.mode |
string | "api-bearer" |
data.token |
string | Свежий JWT для заголовка Authorization: Bearer |
data.expiresAt |
string (ISO 8601) | Срок хранения записи токена — не меняется при обновлении |
data.jwtExpiresAt |
string (ISO 8601) | Реальный срок действия нового JWT. Ограничен 10 минутами (или expiresAt записи, если он ближе) |
data.subdomain |
string | Субдомен сервера |
data.appUrl |
string | Полный HTTPS-адрес приложения |
data.curlExample |
string | Готовый curl-пример с новым токеном |
data.note |
string | Пояснение о сроках действия и о повторном вызове |
Пример ответа
{
"success": true,
"data": {
"id": "9f1c4b7e-3d52-4a18-9c0e-7b2a1f6d84c3",
"mode": "api-bearer",
"token": "eyJhbGciOiJFUzI1NiJ9...",
"expiresAt": "2026-06-25T10:50:00.000Z",
"jwtExpiresAt": "2026-06-25T10:40:10.000Z",
"subdomain": "app-91306a4c",
"appUrl": "https://app-91306a4c.vibecode.bitrix24.tech",
"curlExample": "curl -H \"Authorization: Bearer eyJhbGciOiJFUzI1NiJ9...\" https://app-91306a4c.vibecode.bitrix24.tech/api/health",
"note": "Refreshed the Gateway session JWT for this api-bearer token (same token id, no new row). The JWT is valid for up to 10 minutes (or until the row's expiresAt, whichever is sooner). Call this endpoint again before jwtExpiresAt to keep a long-running client authenticated."
}
}
Пример ответа при ошибке
410 — срок хранения записи истёк:
{
"success": false,
"error": {
"code": "TOKEN_EXPIRED",
"message": "The long-lived token row has expired; mint a new token."
}
}
Ошибки
| HTTP | Код | Описание |
|---|---|---|
| 400 | WRONG_TOKEN_MODE |
Токен в режиме share-url. Обновление применимо только к api-bearer, ссылки share-url обновляются сами при переходе |
| 400 | SERVER_NO_SUBDOMAIN |
У сервера нет субдомена |
| 401 | MISSING_API_KEY |
Не передан заголовок X-Api-Key |
| 401 | INVALID_API_KEY |
Неверный или просроченный API-ключ |
| 403 | TOKEN_OWNER_MISMATCH |
Токен принадлежит другому ключу либо сервер больше не привязан к вашему ключу |
| 404 | NOT_FOUND |
Токен не найден на этом сервере |
| 404 | SERVER_NOT_FOUND |
Сервер не найден или удалён |
| 410 | ALREADY_REVOKED |
Токен отозван — выпустите новый |
| 410 | TOKEN_EXPIRED |
Срок хранения записи истёк — выпустите новый токен через POST /access-tokens |
| 503 | FEATURE_DISABLED |
Раздел токенов доступа выключен на платформе. Признак до вызова и запасной путь — Доступность |
Полный список общих ошибок API — Ошибки.
Диагностика отказа Gateway
Если запрос к приложению с заголовком Authorization: Bearer возвращает 401 с кодом BH_LOGIN_REQUIRED, тело ответа содержит поле reason с конкретной причиной отказа Gateway:
reason |
Что произошло | Что делать |
|---|---|---|
expired |
JWT просрочен (истёк 10-минутный срок) | Обновите токен этим эндпоинтом или выпустите новый |
signature |
Подпись не сошлась | Используйте токен, выпущенный для этого сервера, и не редактируйте его |
subdomain |
Токен привязан к другому субдомену | Обращайтесь к собственному субдомену app-* сервера |
revoked |
Токен отозван | Выпустите новый токен |
type |
Передан не api-bearer-токен |
Используйте токен режима api-bearer, а не сессию по куки |
malformed / invalid |
Строка не является корректным JWT | Проверьте целостность токена |
Известные особенности
- Один отзыв гасит все выданные JWT токена.
DELETEпо записи прекращает работу и исходного JWT, и всех выпущенных обновлением. - Ссылки
share-urlобновляются сами. При каждом переходе они проходят через/auth/bh-login, поэтому вызывать обновление для них не нужно. - Готовый цикл «использовал → при 401 обновил → повторил». Вместо слежения за таймером клиент реагирует на отказ:
async function callWithRefresh(serverId, tokenId, appUrl, jwt) {
let res = await fetch(`${appUrl}/api/health`, {
headers: { Authorization: `Bearer ${jwt}` },
})
if (res.status === 401) {
const r = await fetch(
`https://vibecode.bitrix24.tech/v1/infra/servers/${serverId}/access-tokens/${tokenId}/refresh`,
{ method: 'POST', headers: { 'X-Api-Key': 'YOUR_API_KEY' } },
)
const { data } = await r.json()
jwt = data.token // тот же tokenId, свежий JWT
res = await fetch(`${appUrl}/api/health`, {
headers: { Authorization: `Bearer ${jwt}` },
})
}
return res
}