# Изменения API: 26 июня 2026

[← Журнал изменений](/docs/changelog) · [Июнь 2026](/docs/changelog/2026-06)

### FIX-0626-1: catalog-prices: системные поля priceScale, extraId, timestampX объявлены в схеме

**Было**

[GET /v1/catalog-prices](/docs/entities/catalog-prices/list) и [GET /v1/catalog-prices/:id](/docs/entities/catalog-prices/get) возвращали поля `priceScale`, `extraId` и `timestampX`, но они не были объявлены в схеме: проходили без нормализации (поле `timestampX` приходило в формате со смещением, например `2024-06-17T16:53:24+03:00`) и отсутствовали в ответе [GET /v1/catalog-prices/fields](/docs/entities/catalog-prices/fields).

**Стало**

Три поля объявлены как доступные только для чтения. Теперь они перечислены в [GET /v1/catalog-prices/fields](/docs/entities/catalog-prices/fields), а `timestampX` нормализуется в ISO 8601 UTC (`2024-06-17T13:53:24.000Z`) — единообразно с остальными полями типа datetime.

**Влияние на интеграторов**

Момент времени в `timestampX` не меняется — меняется только его строковое представление (UTC вместо локального смещения). Клиенты, разбирающие значение стандартным парсером дат, продолжают работать без изменений.

### FIX-0626-2: Скачивание исходников сервера и приложения: подписанный URL больше не отдаёт 403

**Было**

`GET /v1/infra/servers/:id/sources/:versionId/download` и `GET /v1/apps/:id/sources/:versionId/download` возвращали `200` с подписанным URL, но скачивание по этому URL падало с `403 AccessDenied`, если запрос шёл под личным ключом (`vibe_api_*`). Листинг версий при этом работал, и файл физически присутствовал в хранилище.

**Стало**

Подписанный URL теперь привязан к фактическому расположению объекта в хранилище, поэтому скачивание возвращает содержимое архива.

**Влияние на интеграторов**

Контракт эндпоинтов не меняется — это восстановление задокументированного поведения «`200` + рабочий подписанный URL». Никаких изменений на стороне клиента не требуется.

### NEW-0626-3: Обновление api-bearer токена и причина отказа Gateway

Новый эндпоинт [POST /v1/infra/servers/:id/access-tokens/:tokenId/refresh](/docs/infra/access-tokens/refresh) выпускает свежий JWT (до 10 минут) для уже существующего токена режима `api-bearer` — без создания новой записи, не расходуя лимит активных токенов и лимит выпусков в час. Долгоживущий клиент (CI, AI-агент) обновляет токен перед истечением `jwtExpiresAt` вместо повторного выпуска. Один отзыв гасит и исходный, и все обновлённые JWT одного токена.

Ответ `401 BH_LOGIN_REQUIRED`, который Gateway возвращает на субдомене приложения при отклонении заголовка `Authorization: Bearer`, теперь содержит поле `reason` с конкретной причиной: `expired`, `signature`, `subdomain`, `type`, `revoked`, `malformed` или `invalid`. Поле аддитивное — прежние клиенты его игнорируют.
