Обзор платформы
Axisforge Events — это сервис потоковой доставки событий в реальном времени. Платформа связывает сервисы-производители (издатели) с приложениями-потребителями (подписчики) через стандартные защищённые соединения HTTPS:
- Издатели (Publishers) отправляют структурированные пакеты событий на входной шлюз через стандартные HTTPS-запросы методом
POST.
- Подписчики (Subscribers) получают поток событий в реальном времени, поддерживая открытое HTTPS-соединение методом
GET в режиме chunked streaming.
Публикация и подписка используют единый канонический путь /api/v1/sync/events и общий ключ аутентификации проекта.
Региональные базовые адреса (Base URLs)
Axisforge Events предоставляет две региональные точки подключения. Оба адреса имеют идентичные методы API, структуру путей и формат ключей авторизации:
| Регион |
Базовый URL |
Особенности маршрутизации |
| Европа (по умолчанию) |
https://api.axisforge.tech |
Прямое подключение к основному кластеру во Франкфурте. |
| СНГ (CIS) |
https://cis.axisforge.tech |
Доставка через регионального edge-партнёра для улучшения связности и стабилизации сетевых маршрутов. |
Вся обработка событий, дедупликация и постоянное хранение данных осуществляются в нашем дата-центре во Франкфурте. Для клиентов, расположенных в странах СНГ (включая Казахстан, Армению, Грузию и Узбекистан), региональный edge-партнёр ретранслирует HTTPS-трафик в сторону Франкфурта, предотвращая потери на нестабильных магистральных участках.
Авторизация
Ключ доступа передаётся в query-параметре URL t:
https://api.axisforge.tech/api/v1/sync/events?t=YOUR_API_KEY
API-ключ идентифицирует рабочее пространство и авторизует как отправку пакетов (POST), так и подписку на непрерывный поток (GET). Если параметр t опущен, шлюз возвращает ответ с кодом 401 Unauthorized.
Публикация событий (POST)
POST
/api/v1/sync/events?t=YOUR_API_KEY
Отправляет пакет событийных записей в конвейер доставки. После успешной валидации сервер подтверждает приём пустым ответом 200 OK и немедленно распределяет события подключённым подписчикам.
Заголовки запроса
Content-Type: application/json
Подписка на поток событий (GET)
GET
/api/v1/sync/events?t=YOUR_API_KEY
Открывает постоянное HTTPS-соединение для приёма событий в режиме chunked transfer streaming. Сервер непрерывно передаёт поступающие события рабочего пространства; каждый принимаемый фрагмент содержит одну или несколько записей.
Клиентские приложения обрабатывают поступающие фрагменты данных по мере их прибытия и фильтруют события по атрибуту channel. При сетевом разрыве соединение восстанавливается с применением стратегии экспоненциальной задержки.
Схема пакета JSON
Тело запроса на публикацию должно представлять собой валидный JSON-объект, содержащий имя канала, источник и массив объектов событий:
{
"channel": "telemetry-prod",
"source": "billing-service",
"events": [
{
"timestamp": "2026-10-04T12:00:00Z",
"level": "INFO",
"event_type": "invoice.generated",
"payload": {
"invoice_id": "inv_9042",
"customer_id": "cust_881",
"amount_eur": 420.00
}
},
{
"timestamp": "2026-10-04T12:00:01Z",
"level": "WARN",
"event_type": "gateway.latency_elevated",
"payload": {
"provider": "sepa_batch",
"duration_ms": 340
}
}
]
}
Лимиты и рекомендации
- Максимальный размер тела запроса: До 512 KiB на один POST-запрос (до 256 KiB на тарифе Developer). Запросы большего размера отклоняются на входном шлюзе.
- Рекомендуемый размер пакета: Рекомендуется группировать от 50 до 500 записей (ориентировочно 50–250 KiB) на одну отправку для оптимального баланса сетевой утилизации и времени доставки.
- Месячный объём стриминга: Рассчитывается как суммарный объём событий, принятых от издателей, плюс событий, доставленных активным подписчикам, в течение календарного месяца.
- Параллельные потоки: 1 активное подключение подписчика на тарифе Developer, 5 на тарифе Growth и неограниченное число выделенных соединений на тарифе Enterprise.
Коды ответов сервера
Шлюз возвращает стандартные HTTP-коды состояния:
200 OK — Успешное выполнение
Для POST-запросов: Пакет событий принят и отправлен в каналы доставки. Возвращается пустое тело ответа.
Для GET-запросов: Соединение установлено. Сервер непрерывно передаёт события в виде потока чанков.
401 Unauthorized — Отсутствует параметр токена
В запросе не указан обязательный параметр t:
{"error":"unauthorized","code":401,"message":"Authentication token required for event streaming"}
429 Too Many Requests — Превышена квота объёма стриминга
Рабочее пространство исчерпало месячную квоту событий. Ответ содержит заголовок Retry-After: 86400 с указанием времени до автоматического восстановления квоты:
{"error":"quota_exceeded","code":429,"message":"Monthly event synchronization quota exceeded. Bandwidth suspended."}
Политика повторных попыток (Retry Policy)
При кратковременных сетевых сбоях или получении ответа HTTP 429 клиентам рекомендуется использовать экспоненциальную задержку со случайным разбросом (jitter) перед повторным подключением или отправкой данных:
Wait_Time = Min(Max_Backoff, Initial_Backoff * 2^attempt) + Uniform_Random(0, Jitter_Span)
Примеры кода
Ниже приведены рабочие примеры реализации для издателей событий (POST) и подписчиков на поток (GET).
1. Публикация через cURL
curl -X POST "https://api.axisforge.tech/api/v1/sync/events?t=YOUR_API_KEY" \
-H "Content-Type: application/json" \
--data '{
"channel": "telemetry-prod",
"source": "cli-publisher",
"events": [
{
"timestamp": "2026-10-04T12:00:00Z",
"level": "INFO",
"event_type": "deploy.completed",
"payload": {"version": "v2.14.0", "duration_sec": 42}
}
]
}'
2. Python (Публикация и Подписка)
import requests
API_URL = "https://api.axisforge.tech/api/v1/sync/events"
API_KEY = "YOUR_API_KEY"
# Publisher Example (POST)
def publish_batch(channel, events):
payload = {
"channel": channel,
"source": "order-processor",
"events": events
}
response = requests.post(
API_URL,
params={"t": API_KEY},
json=payload,
timeout=10
)
if response.status_code == 200:
print("Events published successfully.")
elif response.status_code == 429:
retry_after = int(response.headers.get("Retry-After", 86400))
print(f"Monthly quota reached. Retry after {retry_after}s.")
else:
response.raise_for_status()
# Subscriber Example (GET Streaming)
def subscribe_stream(target_channel):
response = requests.get(
API_URL,
params={"t": API_KEY},
stream=True,
timeout=60
)
response.raise_for_status()
for chunk in response.iter_content(chunk_size=None):
if chunk:
# Each chunk contains one or more event records for your channels
handle_chunk(chunk, target_channel)
3. Node.js (Публикация и Подписка)
const API_URL = "https://api.axisforge.tech/api/v1/sync/events";
const API_KEY = "YOUR_API_KEY";
// Publisher Example (POST)
async function publishEvents(channel, events) {
const payload = {
channel: channel,
source: "node-service",
events: events
};
const res = await fetch(`${API_URL}?t=${API_KEY}`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload)
});
if (res.status === 200) {
console.log("Batch published successfully.");
} else if (res.status === 429) {
const retrySec = res.headers.get("Retry-After") || 86400;
console.warn(`Monthly quota reached. Retry after ${retrySec}s.`);
} else {
throw new Error(`Publish failed with HTTP ${res.status}`);
}
}
// Subscriber Example (GET Streaming)
async function subscribeStream(target_channel) {
const res = await fetch(`${API_URL}?t=${API_KEY}`, { method: "GET" });
if (!res.ok) {
throw new Error(`Subscription failed with HTTP ${res.status}`);
}
const reader = res.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { value, done } = await reader.read();
if (done) break;
// Each chunk contains one or more event records for your channels
handleChunk(decoder.decode(value, { stream: true }), target_channel);
}
}
Примечание о региональных адресах: Клиенты в регионе СНГ используют адрес https://cis.axisforge.tech с тем же путём запроса и API-ключом.
Примечание: Данная документация описывает спецификацию HTTPS API для Axisforge Events. В соответствии со стандартами безопасности публичные маркетинговые страницы сайта не отправляют и не собирают данные через данный эндпоинт.