Consuming the public event API
Scope and authentication
Section titled “Scope and authentication”The documented Hack API currently exposes one read-only integration: GET /api/v1/public/event. It does not need a token or a cabinet session. User registration, teams, organizer/admin endpoints and internal feature flags are outside this public contract. There is no public developer-key, scope or webhook contract to implement against yet. Hack API is a closed-source product; public documentation grants no license to its source code.
Response semantics
Section titled “Response semantics”The response is {data: event} or {data: null}. The server selects the active event first; when none is active, it selects the nearest future event by start time. With neither candidate, data is null. Treat a null value as “no event to display”, not as an empty event or a transport error. Display event_name as text, not untrusted HTML.
Nullable dates, venue details and contact information must remain optional in your UI. Use each explicit registration flag as a boolean. The public flags describe registration availability; they are not an authorization grant or a substitute for server-side eligibility checks. An unknown field should not crash a client. The full field types and required list are in the OpenAPI contract and reference.
Minimal JavaScript client
Section titled “Minimal JavaScript client”Node.js 22+ or a modern browser with fetch/AbortSignal.timeout:
export async function getPublicEvent(baseUrl = 'https://api.hack-rnd.ru', signal = AbortSignal.timeout(5000)) { const response = await fetch(new URL('/api/v1/public/event', baseUrl), { headers: { Accept: 'application/json' }, signal, redirect: 'error', }); if (!response.ok) { const error = new Error(`Public event request failed: HTTP ${response.status}`); error.status = response.status; error.retryAfter = response.headers.get('retry-after'); throw error; } if (!response.headers.get('content-type')?.includes('application/json')) { throw new Error('Expected an application/json response'); } const payload = await response.json(); if (!payload || !Object.hasOwn(payload, 'data')) throw new Error('Missing public event data'); if (payload.data === null) return null; const event = payload.data; if (typeof event !== 'object' || Array.isArray(event) || typeof event.id !== 'string' || typeof event.event_name !== 'string' || typeof event.participant_registration_open !== 'boolean' || typeof event.volunteer_registration_open !== 'boolean') { throw new Error('Invalid public event fields'); } return event;}The small client checks only the fields it consumes; it is not a full schema validator. The hub’s separate live check validates the whole response against OpenAPI without saving event data. Import this module and call getPublicEvent(); render null and request failures as separate UI states. Browser use additionally depends on the API’s actual CORS policy. A successful server-side fetch does not prove every browser origin is allowed; use your own backend if your origin is not permitted, without forwarding private cabinet cookies.
Errors, limits and caching
Section titled “Errors, limits and caching”- Route limit:
throttle:120,1. Actual limiter keys and infrastructure restrictions are deployment dependent; do not assume an independent quota per application. - On 429, read
Retry-Afterwhen present and back off. Do not retry immediately in a loop. The example surfaces status/header without automatically retrying. - On network failure, timeout or 5xx, show a temporary failure or a cached last successful response with a visible stale state. Never silently change registration flags.
- Cache public responses for an application-appropriate TTL. Invalidate or refresh on a controlled schedule; do not fetch on every keystroke.
- Do not couple to a JSON error message shape: only the successful 200 payload is specified here.
data:nullis a valid successful state.
Verification boundary
Section titled “Verification boundary”2026-10-17: the live public endpoint returned a schema-valid response. Local tests cover null, valid flags, a malformed flag, missing data, 429 and 503. This does not test authenticated journeys, browser CORS, every infrastructure error or a live no-event state. The no-event case is covered with fixtures and source inspection.