ryOS ryOS / Docs
GitHub Launch

API Reference

ryOS backend APIs use Node-style route handlers in api/, served by the standalone Bun API server.

Most actively refactored JSON routes use the shared apiHandler utility (api/_utils/api-handler.ts) for CORS, method checks, auth resolution, and consistent error handling. Some specialized routes (for example multipart upload handlers) still use explicit/manual handling.

API Request Flow

graph LR
    Client[Client App] --> Auth{Auth Check}
    Auth -->|Valid| Router[API Router]
    Auth -->|Invalid| Error[401 Error]
    Router --> API[Node.js Runtime]
    API --> Services[External Services]
    Services --> AI[AI Providers]
    Services --> DB[(Redis/KV)]
    Services --> Media[Media APIs]
    API --> Response[JSON Response]
    Response --> Client

Endpoint Documentation

Endpoint GroupDescription
Chat APIMain AI chat with streaming and tool calling
Song APIMusic library CRUD, lyrics, furigana, translations
Media APIText-to-speech, transcription, YouTube search
Auth APIUser registration, login, token management
Rooms APIChat room creation and management
Messages APISend and retrieve chat messages
Presence APIPresence tracking, user search, AI replies
AI Generation APIsApplet generation, IE time-travel, parse-title
Utility APIsLink preview, iframe check, share applet, stocks, sync, admin
KOReader Sync APIKOReader-compatible progress sync bridged to Books
Books OPDS CatalogPassword-authenticated EPUB catalog and downloads
API Design GuidePatterns and conventions for API development

Cross-Cutting Handler Pattern

  • apiHandler: shared wrapper for CORS preflight, origin checks, method allowlists, optional JSON parsing, unified logger wiring, and default JSON error handling.
  • request-auth: shared auth resolver for token endpoints, expecting:
    • Authorization: Bearer {token}
    • X-Username: {username}
  • Partial auth headers return 400.
  • Invalid token/username pairs return 401.
  • Optional-auth endpoints can be anonymous while still validating provided auth headers.

Infrastructure Adapters

  • Redis (api/_utils/redis.ts): Centralized Redis client factory supporting Upstash REST (REDIS_KV_REST_API_URL) and standard Redis (REDIS_URL) backends with a unified API.

Quick Reference

AI Endpoints

EndpointPurpose
/api/chatMain AI chat with tool calling
/api/ai/conversations/:channelSynced Chat and Assistant history
/api/ai/conversations/:channel/resetClear synced history and process memories
/api/ai/conversations/:channel/greetingServer-owned proactive greeting (chat channel)
/api/ai/attachments/:idPrivate synced chat images
/api/applet-aiApplet text + image generation
/api/stuff/remove-backgroundStuff cover background removal (transparent PNG)
/api/stuff/barcode-lookupBarcode product lookup
/api/stuff/product-lookupKeyword product lookup
/api/stuff/product-imageServer-side product cover fetch
/api/stuff/sharesRead, publish, or delete a shared shelf
/api/stuff/shares/:id/reserveReserve an item on a shared shelf
/api/stuff/shares/:id/bidPlace an offer on a shared-shelf item
/api/dictionaryDictionary lookup (q, lang of auto, en, zh, ja, or ko). Local WordNet, CC-CEDICT, JMdict, and kengdic return first
/api/dictionary/enrichSame lookup after Wiktionary examples are merged
/api/dictionary/aiPOST streamed AI notes (extras) or a no-results definition (fallback)
/api/fitness/exercisesPinned free-exercise-db list, or one exercise with instructions when id is set
/api/fitness/food-analyzePOST a meal photo or text for an editable calorie and macro estimate
/api/ie-generateTime-travel page generation
/api/parse-titleMusic metadata extraction
/api/ai/extract-memoriesDaily-note and long-term memory extraction
/api/ai/process-daily-notesBackground daily-note processing
/api/ai/cursor-run-statusCursor Cloud agent run polling
/api/ai/cursor-run-followupFollow-up prompt for an existing Cursor run

Media Endpoints

EndpointPurpose
/api/songs/Song library CRUD
/api/songs/[id]Individual song operations
/api/speechText-to-speech
/api/speech/permitsMint a Ryo-chat speech permit
/api/audio-transcribeSpeech-to-text
/api/youtube-searchYouTube music search
/api/apple-music-artworkApple Music artwork proxy

Communication Endpoints

EndpointPurpose
/api/roomsRoom list + create
/api/rooms/[id]Room detail + delete
/api/rooms/[id]/joinJoin a room
/api/rooms/[id]/leaveLeave a room
/api/rooms/[id]/usersGet active users in room
/api/rooms/[id]/messagesList/send messages
/api/rooms/[id]/messages/[msgId]Delete message (admin)
/api/messages/bulkBulk message fetch
/api/presence/switchPresence switching
/api/presence/heartbeatGlobal online presence heartbeat
/api/rooms/[id]/typingBroadcast typing indicator
/api/usersUser search
/api/ai/ryo-replyAI reply in rooms
/api/listen/sessionsList/create listen-together sessions
/api/listen/sessions/[id]Get session state
/api/listen/sessions/[id]/joinJoin listen session
/api/listen/sessions/[id]/leaveLeave listen session
/api/listen/sessions/[id]/syncSync playback state (DJ only)
/api/listen/sessions/[id]/assign-djAssign the session DJ
/api/listen/sessions/[id]/transfer-hostTransfer session host
/api/listen/sessions/[id]/remote-commandSubmit remote playback command
/api/listen/sessions/[id]/reactionSend emoji reaction
/api/irc/serversList/create IRC server configs
/api/irc/servers/[id]DELETE — remove IRC server config (admin only)
/api/irc/servers/[id]/channelsBrowse IRC channels
/api/pusher/authAuthorize private/presence Pusher channels
/api/realtime/ticketMint local WebSocket realtime tickets
/api/telegram/link/createCreate Telegram account link
/api/telegram/link/statusCheck Telegram link status
/api/telegram/link/disconnectDisconnect Telegram account
/api/push/registerPOST { deviceToken, appVersion?, rooms? } — upsert the signed-in user's iOS APNs device (idempotent)
/api/push/unregisterPOST { deviceToken } — delete the device row and its watermarks

APNs pushes (api/_utils/push-relay.ts) fire when a room message is broadcast: private rooms notify the other members' devices; public/IRC rooms notify only devices that listed the room in rooms. Devices are dropped when their registering session signs out, on logout-all, and on account deletion. bun run push:test <token> [sandbox|prod] sends a test alert.

Push logs are prefixed [push] (device tokens shown as abcd…wxyz; no JWTs, keys, session tokens, or message text). Production logs one notifyRoomMessage done summary per message with outcome counts (sent, failed, dead, duplicate, sessionDead, ineligible, …) plus warnings for APNs failures, dead-token removal, and env changes. Set RYOS_DEBUG=1 (the shared API debug flag) to also log each skip reason, burst grouping, and every APNs attempt's env/status/reason.

The web client logs its half under the same [push] scope via createClientLogger (debug mode: dev builds or localStorage["ryos:debug"] = "1"): permission requests, shell configure/room-state sync, which display path a chat notification took (shell / browser / toast), and notification taps. The iOS shell logs ryOS: [push] … lines via NSLog (Console.app / Xcode): permission result, APNs token (redacted), api/push/register and AirBuild fallback status codes, local notifications, and tap → web delivery.

Utility Endpoints

EndpointPurpose
/api/link-previewURL metadata extraction
/api/iframe-checkEmbeddability checking
/api/share-appletApplet sharing
/api/stocksReal-time stock quotes
/api/currency-rateCurrency conversion rates
/api/mapkit-tokenMapKit JS token
/api/geoApproximate city for the request IP (Maps first-open camera)
/api/youbike/stationsTaiwan YouBike 2.0 station overlay (cached official open data)
/api/youbike/routeOn-road YouBike bike-leg geometry (cached public OSRM bike profile)
/api/musickit-tokenMusicKit JS token
/api/tv/create-channelAI-assisted TV channel creation
/api/opdsHTTP Basic-authenticated Books acquisition feed
/api/opds/books/:bookId.epubAuthenticated EPUB acquisition
/api/sync/auto-sync-preferenceRead/update the cross-device Auto Sync toggle
/api/sync/v2/opsApply batched journal ops
/api/sync/v2/changesRead journal ops after a cursor
/api/sync/v2/snapshotRead full key-value sync snapshot
/api/sync/v2/blobsPrepare/dedupe content-addressed blob uploads
/api/sync/v2/blob-uploadIssue and consume authenticated blob proxy uploads
/api/cron/sync-maintenanceGarbage-collect unreferenced sync blobs and heal user records
/api/analytics/eventsRecord lightweight client analytics events
/api/adminAdmin operations
/api/airdrop/heartbeatAirDrop presence heartbeat
/api/airdrop/discoverDiscover nearby AirDrop users
/api/airdrop/sendSend file via AirDrop
/api/airdrop/respondAccept/decline AirDrop transfer

Endpoint Categories Overview

graph TD
    API["/api/*"]
    API --> AI[AI Services]
    API --> Media[Media Services]
    API --> Comm[Communication]
    API --> Util[Utilities]
    
    AI --> chat["/chat"]
    AI --> applet["/applet-ai"]
    AI --> ie["/ie-generate"]
    AI --> parse["/parse-title"]
    
    Media --> song["/songs"]
    Media --> speech["/speech"]
    Media --> transcribe["/audio-transcribe"]
    Media --> yt["/youtube-search"]
    
    Comm --> rooms["/rooms"]
    Comm --> messages["/messages/bulk"]
    Comm --> presence["/presence/switch"]
    Comm --> users["/users"]
    Comm --> ryo["/ai/ryo-reply"]
    Comm --> listen["/listen/sessions"]
    Comm --> telegram["/telegram/link"]
    
    Util --> preview["/link-preview"]
    Util --> iframe["/iframe-check"]
    Util --> share["/share-applet"]
    Util --> stocks["/stocks"]
    Util --> sync["/sync/v2/*"]
    Util --> admin["/admin"]

Authentication

Browser sessions use an httpOnly ryos_auth cookie set by register, login, token/verify, token/refresh, and session. Programmatic clients may still use Bearer + X-Username headers:

Authorization: Bearer {token}
X-Username: {username}

Token-based sessions use a 1-year TTL, refreshed on each validated request. Auth-required endpoints use the shared request-auth validation boundary for consistent 400/401 semantics.

Standalone Bun Server Routes

When running via scripts/api-standalone-server.ts:

RoutePurpose
GET /healthProcess health + route count
GET /api/healthAPI health
GET /app-config.jsClient runtime config bootstrap (window.__RYOS_RUNTIME_CONFIG__)
WebSocket REALTIME_WS_PATHLocal realtime (ticket from /api/realtime/ticket)

Environment Variables

VariableEndpoints / purpose
REDIS_KV_REST_API_URL / REDIS_KV_REST_API_TOKENCore (Upstash REST)
REDIS_URLCore (standard Redis); required for multi-instance local realtime
PUSHER_APP_ID, PUSHER_KEY, PUSHER_SECRET, PUSHER_CLUSTERPusher realtime + /api/pusher/auth
REALTIME_PROVIDER, REALTIME_WS_PATHlocal → /api/realtime/ticket + WebSocket
MAPKIT_*/api/mapkit-token, Maps AI tools
MUSICKIT_* (or MAPKIT_* fallback)/api/musickit-token
TELEGRAM_BOT_TOKEN, TELEGRAM_WEBHOOK_SECRET, TELEGRAM_BOT_USERNAME/api/webhooks/telegram, /api/telegram/link/*
CRON_SECRET/api/cron/sync-maintenance, /api/cron/telegram-heartbeat
RYOS_APNS_TEAM_ID, RYOS_APNS_KEY_ID, RYOS_APNS_KEY_B64 (or RYOS_APNS_KEY_FILE)iOS APNs pushes for room messages (/api/push/*); unset → no pushes sent
CURSOR_API_KEY/api/ai/cursor-run-followup, admin Cursor actions
TRUSTED_PROXY_COUNT, AUTH_COOKIE_SECUREStandalone reverse-proxy hardening (see Self-hosting)

AI Providers

ProviderModels
OpenAIgpt-6 (gpt-6-astra), gpt-5.5, tts-1, whisper-1
Anthropicsonnet-4.6
Googlegemini-3-flash, gemini-3-flash-preview, gemini-3.1-pro-preview, gemini-3.1-flash-image-preview