API Reference

Complete reference for the Anilay Go backend REST API. All request and response bodies use JSON.

Authentication
Endpoints marked with Auth require the header: Authorization: Bearer <access_token>
Access tokens are JWT with a 15-minute lifetime. Refresh tokens last 30 days. When the access token expires, use POST /api/v1/auth/refresh to obtain a new pair.
317 endpoints

Service health and readiness probes.

Register, login, token management, and OAuth flows. Access tokens are JWT with a 15-minute lifetime. Refresh tokens last 30 days.

Public user profiles and search.

Browse, search, and get detailed anime information. All endpoints are public and responses are cached.

Manage personal anime watch lists. Track status, score, and episode progress.

User-curated lists of anime. Three-tier visibility: public (indexed on the browse page), unlisted (link-only), private (owner-only). Items store the Shikimori ID plus denormalised title/poster so adding an anime does not require it to exist in our local catalog. Phase 1 covers CRUD + items; groups, social (likes/favorites/views/forks), comments, cover upload, and challenge mode arrive in later phases.

User-facing R2 uploads (admin uploads use /admin/r2). These routes live on the Next.js side because the R2 SDK is JS-only; the Go API does not sign or handle R2 writes.

Path of Ascension: races (human, elf, vampire, ork), age accrual per watched episode, evolution, and racial passives. Accrual runs inside POST /anime-list/:anime_id/episode with a 15-minute anti-abuse cooldown. Streak resets after 6 hours of inactivity.

Threaded comments on anime pages with up/down voting. Muted users are blocked at /anime/:id/comments POST.

View and manage achievement unlock status.

Daily and weekly quests with rewards.

Virtual currency (coins), experience points (XP), leveling, and transactions.

Friend requests, management, and blocking.

Invite a friend into a watch-party from your solo watch page. The backend tracks "who is currently watching what" via heartbeat, joins that with the friends list to power the chat-sidebar "online + watching" pill, and on accept pre-creates a watch-party seeded with the sender's anime + timecode. Live delivery rides on the chat gateway (events WATCH_TOGETHER_REQUEST + WATCH_TOGETHER_RESOLVED). Invites expire after 60s; a background sweeper marks stale pending rows as expired and purges expired mutes.

In-app notification management.

Browse and purchase cosmetic items with coins.

User-to-user item trading marketplace.

Administrative endpoints. Requires authentication AND admin role.

Client-facing telemetry feeds powering the admin AI stats assistant. Heartbeats drive time-on-site; player events drive source-health rollups. Search + user-IP logs are written server-side from existing handlers/middleware and have no client endpoint.

Site-wide release notes powering the public /changelog page and the Instagram-stories "what's new" modal that pops once on a returning user's first load after a new entry. cover_url is the 9:16 portrait video the modal autoplays muted/looped; detail_banner_url is the dedicated 16:9 landscape banner shown on /changelog/:slug when a user hits "Подробнее". The public listing falls back to cropping cover_url into a 16:9 frame when detail_banner_url is empty.

User-facing catalog and inventory for frames, badges, themes, and custom avatars.

Synchronized watch-together rooms with realtime chat. The /ws endpoint upgrades to a WebSocket.

Analytics beacon, support forms, and public runtime settings used by the frontend.

Manage API keys for third-party integrations.

Expo Push token registration for the iOS/Android app. Tokens are fanned out to the Expo Push API on every in-app notification.

Direct messages (E2EE via Signal-style X3DH + ratcheted AEAD), group DMs, the global announcement channel, and the support queue. Hosted under chat.anilay.com (prod) / chat-staging.anilay.com (staging). WebSocket gateway at /api/v1/chat/ws delivers realtime MESSAGE_CREATE / REACTION / TYPING / READ_RECEIPT events; REST below is the authoritative source for state-changing operations.

Discord-style servers with roles, categories, channels, and per-channel permission overrides. Permission model: 64-bit bitflag (see frontend/src/lib/chat/perms.ts for the exhaustive list). Effective perms = @everyone role | user role perms → @everyone channel override → union of user-role channel overrides → user-specific channel override; ADMINISTRATOR and server ownership short-circuit to full. Cached in Redis per (user, channel) with a 60s TTL; every role / override change invalidates the relevant keys.

Staff-only endpoints behind RequireAdmin(). Hosted on chat.anilay.com / chat-staging.anilay.com alongside the user-facing chat routes.