Справочник API

Полный нормативный справочник по HTTP API Runnev. Базовый URL https://runnev.dev/v1. Каждый эндпоинт, его параметры, его ответы и рабочий пример.

Соглашения

  • Базовый URL. https://runnev.dev/v1. Поддерживаются HTTP/2 и HTTP/3; HTTP/1.1 тоже работает для потоковой передачи.
  • Content-type. Запросы и ответы — JSON (application/json), кроме потока подписки (text/event-stream) и сырой публикации/повтора (application/octet-stream).
  • Метки времени — RFC 3339 в UTC с точностью до миллисекунд, например 2026-08-04T11:02:13.418Z.
  • Идентификаторы — «голый» base62 (22 символа), например cBczepiZSW8GJaCae0xIj7. Без префиксов.
  • Номера — неотрицательные целые. Курсор потока — это номер его новейшего пакета, начинается с 0 на пустом потоке.
  • Кэширование. Каждый ответ /v1 отправляет cache-control: no-store.
  • Неизвестные параметры запроса игнорируются, а не отклоняются. См. Прямую совместимость.
  • Аутентификация. Authorization: Bearer <key> на каждом эндпоинте, кроме /v1/health, /v1/version и демо-потока. См. Аутентификацию.

Универсальные заголовки ответа

Каждый ответ /v1 несёт:

ЗаголовокПримерЗначение
x-request-idreq_0Kj2wq8ULn4mAe1sУникален на запрос; приводите его в поддержке.
x-ratelimit-limit1000Запросов, разрешённых в текущем окне.
x-ratelimit-remaining998Запросов осталось в окне.
x-ratelimit-reset1785931200Время Unix, когда окно сбрасывается.
cache-controlno-storeНикогда не кэшировать ответы API.
serverrunnevИдентификатор сервиса.

429 дополнительно отправляет retry-after в секундах. Ответы публикации добавляют x-runnev-cursor.

Пагинация

Эндпоинты списка принимают ?limit= (1–100, по умолчанию 20) и токен пагинации ?cursor=. Ответ включает has_more и, когда есть ещё, next_cursor для передачи обратно. Этот курсор пагинации — непрозрачный токен и не связан с курсором номеров потока.

Эндпоинты

GET/v1/healthliveness, без авторизации

Проверка живости. Без аутентификации.

curl https://runnev.dev/v1/health
200 OK
{"status":"ok","uptime_s":1843302}
GET/v1/versionинфо о сборке, без авторизации
200 OK
{"version":"1.6.2","commit":"9d3c1af","built":"2026-07-15T08:14:02Z"}
POST/v1/streamsсоздать поток

Создать поток. Требует авторизации.

Тело

ПолеТипПримечания
name обязательноstring1–128 символов. Уникальность не требуется.
retention_secondsinteger60–2592000. По умолчанию 86400.
max_bytesinteger1 МиБ – 4 ГиБ. По умолчанию 268435456.
modestringjson (по умолчанию) или raw.
idstringНеобязательный клиентский base62-id для идемпотентного создания.
curl https://runnev.dev/v1/streams \
  -H "Authorization: Bearer $RUNNEV_API_KEY" \
  -d '{"name":"orders-eu","retention_seconds":86400}'
201 Created
{
  "id": "cBczepiZSW8GJaCae0xIj7",
  "name": "orders-eu",
  "created_at": "2026-06-11T09:22:31Z",
  "retention_seconds": 86400,
  "max_bytes": 268435456,
  "cursor": 0,
  "bytes_stored": 0,
  "mode": "json"
}

Ошибки: 400 invalid_request_error (плохое тело), 409 stream_name_taken (переданный id уже существует), 422 retention_out_of_range, 403 stream_limit_reached.

GET/v1/streamsсписок потоков

Список потоков в проекте. Query: limit, cursor.

200 OK
{
  "data": [
    {"id":"cBczepiZSW8GJaCae0xIj7","name":"orders-eu","cursor":41823,"mode":"json","created_at":"2026-06-11T09:22:31Z","retention_seconds":86400,"max_bytes":268435456,"bytes_stored":118293011}
  ],
  "has_more": false,
  "next_cursor": null
}
GET/v1/streams/{id}метаданные или подписка

Двойной режим по заголовку Accept.

  • С Accept: text/event-stream → подписка (SSE). Query: cursor (head, 0 или целое). См. Подписку.
  • Иначе → вернуть объект метаданных потока (той же формы, что при создании).
подписка
curl -N "https://runnev.dev/v1/streams/cBczepiZSW8GJaCae0xIj7?cursor=head" \
  -H "Accept: text/event-stream" -H "Authorization: Bearer $RUNNEV_API_KEY"

Ошибки: 404 stream_not_found, 400 invalid_stream_id, 403 project_forbidden.

DELETE/v1/streams/{id}удалить поток

Удалить поток и все его пакеты. Открытые подписчики получают event: end. Возвращает 204 без тела.

curl -X DELETE https://runnev.dev/v1/streams/cBczepiZSW8GJaCae0xIj7 \
  -H "Authorization: Bearer $RUNNEV_API_KEY"   # 204
POST/v1/streams/{id}/{seq}публикация под номером

Основной путь записи. seq — неотрицательное целое, не более чем на 1024 впереди курсора. Идемпотентен по (id, seq). Принимает application/json ({"events":[...]}) или, для потоков raw, application/octet-stream. Макс. тело 8 МиБ.

curl https://runnev.dev/v1/streams/cBczepiZSW8GJaCae0xIj7/41823 \
  -H "Authorization: Bearer $RUNNEV_API_KEY" \
  -d '{"events":[{"type":"order.paid","id":"o_5521"}]}'
202 Accepted
{"stream_id":"cBczepiZSW8GJaCae0xIj7","seq":41823,"accepted":1,"cursor":41823,"duplicate":false}

Дополнительный заголовок ответа: x-runnev-cursor: 41823. Повтор сохранённого номера возвращает 200 с "duplicate": true.

Ошибки: 413 payload_too_large, 422 sequence_too_far_ahead, 409 invalid_sequence, 415 unsupported_media_type, 429 rate_limited.

POST/v1/streams/{id}/publishпубликация, серверный номер

Дописать под следующим номером, выбранным сервером. Не идемпотентен, если вы не отправите заголовок Idempotency-Key. Тело и лимиты те же, что выше.

202 Accepted
{"stream_id":"cBczepiZSW8GJaCae0xIj7","seq":41824,"accepted":1,"cursor":41824,"duplicate":false}
GET/v1/streams/{id}/cursorтекущий курсор
200 OK
{"cursor":41823,"updated_at":"2026-08-04T11:02:13.418Z"}
GET/v1/streams/{id}/batches/{seq}повтор одного пакета

Получить один пакет по номеру. Для потоков json ответ — объект пакета; для потоков raw — сохранённые байты с их исходным content-type.

200 OK
{"seq":41823,"ts":"2026-08-04T11:02:13.418Z","events":[{"type":"order.paid","id":"o_5521"}]}

Ошибки: 404 stream_not_found или 404, когда номер был вытеснен или никогда не существовал.

Прямая совместимость

Неизвестные параметры запроса игнорируются на каждом эндпоинте. Добавление, скажем, ?trace=abc&shard=3 к любому URL Runnev ничего не меняет в обработке запроса. Это постоянная гарантия, чтобы клиенты могли безопасно добавлять собственные параметры трассировки, шардирования или обхода кэша; новое поведение API всегда вводится через параметры, которые определяем мы, и никогда — превращением ранее игнорируемого параметра в ошибку.