OMG Radio API — Full Specification
Backend build guide for GenSpark · Modules A–I · β Version 1.0
Legal Foundation — Read Before Building
OMG Radio may ONLY train on: Ooki-owned audio masters, lyrics from registered Ooki songwriters, and catalog items explicitly whitelisted in the Training Dataset Manager. Training on any external copyrighted music, unlicensed audio, or third-party lyrics is strictly prohibited and constitutes a legal violation. Every trained model version must be logged in the AI Track Registry (Module G) with a training dataset hash for audit purposes.
OMG Radio may ONLY train on: Ooki-owned audio masters, lyrics from registered Ooki songwriters, and catalog items explicitly whitelisted in the Training Dataset Manager. Training on any external copyrighted music, unlicensed audio, or third-party lyrics is strictly prohibited and constitutes a legal violation. Every trained model version must be logged in the AI Track Registry (Module G) with a training dataset hash for audit purposes.
System Overview
OMG Radio is an AI-augmented radio station that plays real Ooki catalog tracks and AI-generated songs in a seamless flow. The AI learns exclusively from Ooki-owned content, generates original music in real-time, and transparently labels AI-generated tracks to listeners.
OMG Radio is an AI-augmented radio station that plays real Ooki catalog tracks and AI-generated songs in a seamless flow. The AI learns exclusively from Ooki-owned content, generates original music in real-time, and transparently labels AI-generated tracks to listeners.
9
Modules (A–I)
47
API Endpoints
8
Webhook Events
4
WebSocket Channels
β1.0
API Version
FLOW
Request → Generation → Playback Flow
How a single radio session generates and plays a track
1
Listener opens OMG Radio UI (Module H)
Frontend calls
GET /omg/v1/radio/stream-info to get current station context and now-playing card data2
Context Engine fires (Module D)
Radio Scheduler calls
GET /omg/v1/context/current — returns live genre, mood, lifestyle, tempo range for the session3
Scheduler decides: catalog track or AI generation?
Based on
catalog_ratio + ai_generation_ratio config from Module A (GET /omg/v1/admin/config)4a
[Catalog path] Pull real track from library
Calls
GET /omg/v1/scheduler/next-track?source=catalog — returns CDN stream URL for a real Ooki master4b
[AI path] Generate original track (Modules E + F)
Music Engine:
POST /omg/v1/generate/track · Lyrics Engine (if enabled): POST /omg/v1/generate/lyrics · Both receive the context payload5
Track registered in AI Registry (Module G)
POST /omg/v1/registry/tracks — logs metadata, training version, session ID, radio-only flag. Returns omg_track_id6
Frontend receives now-playing push (Module H + WebSocket)
WebSocket channel
ws://radio.ookimusic.com/omg/ws/now-playing broadcasts track card. If AI, Transparency Panel (Module I) data is includedBASE
Base URLs & Environments
Production
https://api.ookimusic.com/omg/v1/
Sandbox
https://sandbox.ookimusic.com/omg/v1/
WebSocket (Live Radio)
wss://radio.ookimusic.com/omg/ws/
AI Inference Service
https://ml.ookimusic.com/omg/v1/
Authentication & Authorization
JWT Bearer · Admin Staff JWT · API Key scopes
All OMG Radio endpoints require authentication. Public endpoints (station stream info, now-playing) accept a standard listener Bearer token. Admin endpoints additionally require the
omg:admin role embedded in the JWT. ML Inference endpoints require an internal service-to-service API key.AUTH
Authentication Endpoints
Use the main Ooki Auth API — OMG Radio shares the same auth layer
POST
/api/auth/admin/login
Staff login — returns JWT (15 min) + refresh token (7 days, HttpOnly cookie). Requires work email, password, and 6-digit 2FA TOTP. Rate limit: 5 req/15 min. Roles with OMG access:
omg:admin
super_admin, admin, developer
POST
/api/auth/refresh
Refresh expired access token using HttpOnly refresh cookie. Returns new JWT.
GET
/omg/v1/auth/validate
Validate token and return OMG-specific permission set (
can_train, can_generate, can_toggle_radio)
Required Headers
Authorization: Bearer <jwt_token> X-API-Key: ok_live_YOUR_KEY // for service-to-service calls X-CSRF-Token: <csrf_token> // required on all POST/PUT/PATCH/DELETE Content-Type: application/json
OMG Role Scopes
omg:admin
Full control: enable/disable radio, configure settings, manage training
omg:train
Trigger and monitor training pipeline; manage datasets
omg:generate
Invoke music and lyrics generation engines (service-to-service)
omg:read
Read-only: station status, now-playing, listener stats (all auth'd users)
Module A — Admin Panel / Station Control
Radio on/off · generation mode · content ratios · safety settings
A
Station Configuration Endpoints
All routes require
omg:admin JWT scope
GET
/omg/v1/admin/config
Fetch current station configuration object
omg:admin
PATCH
/omg/v1/admin/config
Update one or more config fields. Partial updates supported. Changes take effect on next scheduler cycle (~30s).
omg:admin
POST
/omg/v1/admin/radio/enable
Enable the OMG Radio station. Starts scheduler, context engine, and stream.
omg:admin
POST
/omg/v1/admin/radio/disable
Gracefully disable the station. Completes current track then stops. Body:
omg:admin
{"reason": "string"}
GET
/omg/v1/admin/status
Health check: radio enabled, training status, generation queue depth, listener count, uptime, last model version
omg:admin
POST
/omg/v1/admin/safety/test
Run safety filter pipeline on a test audio or lyrics payload. Returns content safety score and flagged categories.
omg:admin
Config Object Schema — PATCH /omg/v1/admin/config
{
"radio_enabled": true, // bool — master on/off switch
"generation_mode": "hybrid", // "catalog_only" | "ai_only" | "hybrid"
"catalog_ratio": 0.6, // 0.0–1.0, fraction of slots from catalog
"ai_generation_ratio": 0.4, // must sum to 1.0 with catalog_ratio
"lyrics_generation": true, // bool — enable Module F
"explicit_allowed": false, // bool — safety gate
"max_track_length_sec": 240, // int — AI gen max length in seconds
"generation_lead_time": 45, // int — seconds before playback to start gen
"fallback_mode": "catalog_only", // mode if ML service goes down
"stream_quality": "320kbps" // "128kbps" | "192kbps" | "320kbps"
}
Response — GET /omg/v1/admin/status
{
"radio_enabled": true,
"uptime_seconds": 86432,
"listener_count": 1247,
"current_track": {
"omg_track_id": "OMG-SESSION-001-001",
"track_origin": "ai_generated", // "catalog" | "ai_generated"
"title": "Ephemeral Drift",
"progress_pct": 42
},
"queue_depth": 3, // tracks buffered ahead
"training_status": "idle", // "idle"|"running"|"paused"|"failed"
"model_version": "omg-audio-v2.4",
"safety_status": "nominal",
"ml_service_health": "healthy"
}
Module B — Training Dataset Manager
Whitelist sources · include/exclude artists and eras · dataset snapshots
B
Dataset Management Endpoints
Define exactly which Ooki-owned content is eligible for AI training
GET
/omg/v1/dataset/config
Fetch current dataset configuration (whitelisted sources, artist filters, era filters)
omg:train
PATCH
/omg/v1/dataset/config
Update dataset configuration. Changes apply to next training run only — does not re-train automatically.
omg:train
GET
/omg/v1/dataset/stats
Dataset statistics: total masters eligible, total lyric files, total hours of audio, era breakdown
omg:train
GET
/omg/v1/dataset/artists
List artists in dataset —
omg:train
?status=included|excluded query param. Paginated.
PATCH
/omg/v1/dataset/artists/{artist_id}
Include or exclude a specific artist from training. Body:
omg:train
{"status": "included" | "excluded", "reason": "string"}
POST
/omg/v1/dataset/snapshot
Create a named snapshot of the current dataset config. Used for reproducible training runs. Body:
omg:train
{"name": "string", "description": "string"}
GET
/omg/v1/dataset/snapshots
List all dataset snapshots with hash, timestamp, and which training run used each
omg:train
POST
/omg/v1/dataset/validate
Run validation pass: checks all included masters exist in CDN, all lyrics have valid songwriter attribution, no third-party content detected. Returns validation report.
omg:train
Dataset Config Object Schema
{
"training_sources": {
"audio": "ooki_owned_only", // FIXED — do not change
"lyrics": "ooki_songwriters_only", // FIXED — do not change
"sonic_capsules": true // bool — include Sonic Capsule metadata
},
"artist_filter": {
"mode": "whitelist", // "whitelist" | "blacklist" | "all"
"artist_ids": ["art_001", "art_002"] // array of Ooki artist IDs
},
"era_filter": {
"include_years": [2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026]
},
"quality_gate": {
"min_audio_bitrate": 192, // kbps — minimum source quality
"require_isrc": true, // bool — only tracks with ISRC codes
"require_credits": true // bool — only tracks with songwriter credits
}
}
Module C — Multi-Modal Training Pipeline
Audio model · lyrics model · style embedding model · training jobs
C
Training Pipeline Endpoints
Orchestrate model training runs on Ooki-owned data
GET
/omg/v1/training/jobs
List training jobs —
omg:train
?model=audio|lyrics|style&status=running|completed|failed filters. Paginated.
GET
/omg/v1/training/jobs/{job_id}
Get full job details: progress, loss curve, current epoch, ETA, dataset snapshot used, GPU utilization
omg:train
POST
/omg/v1/training/jobs
Start a new training job. Body must specify model type, dataset snapshot ID, hyperparameters. Returns
omg:train
job_id immediately; training is async.
POST
/omg/v1/training/jobs/{job_id}/pause
Pause a running training job at the next checkpoint
omg:train
POST
/omg/v1/training/jobs/{job_id}/resume
Resume a paused training job from last checkpoint
omg:train
DELETE
/omg/v1/training/jobs/{job_id}
Cancel and delete a training job. Completed jobs cannot be deleted; use archive instead.
omg:admin
GET
/omg/v1/training/models
List all trained model versions with their deployment status and performance metrics
omg:train
POST
/omg/v1/training/models/{model_id}/deploy
Promote a trained model to production. Triggers a model swap on the ML inference service with zero downtime. Admin approval required.
omg:admin
POST /omg/v1/training/jobs — Request Body
{
"model_type": "audio", // "audio" | "lyrics" | "style_embedding"
"dataset_snapshot_id": "snap_20260425", // from Module B snapshot
"base_model_id": "omg-audio-v2.4", // fine-tune from existing; null = train from scratch
"hyperparams": {
"epochs": 50,
"learning_rate": 0.0001,
"batch_size": 32,
"warmup_steps": 500
},
"notify_webhook": "https://your.server/omg/training-done"
}
Job Status Response
{
"job_id": "job_abc123",
"model_type": "audio",
"status": "running", // "queued"|"running"|"paused"|"completed"|"failed"
"current_epoch": 24,
"total_epochs": 50,
"progress_pct": 48,
"current_loss": 0.0842,
"perplexity": 12.4, // lyrics model only
"eta_minutes": 94,
"gpu_utilization_pct":87,
"dataset_hash": "sha256:a3f8c...", // immutable audit fingerprint
"started_at": "2026-04-25T10:00:00Z",
"model_version_draft": "omg-audio-v2.5-draft"
}
Module D — Radio Context Engine
Live genre · mood · lifestyle · tempo — drives every generation request
D
Context Engine Endpoints
Live parameters that shape AI generation in real time
GET
/omg/v1/context/current
Get the active context object used for the current generation cycle. Refreshes every 30 minutes or on manual override.
omg:read
PATCH
/omg/v1/context/current
Override active context fields. Immediately affects next generation request. Admin only.
omg:admin
POST
/omg/v1/context/presets
Save a named context preset (e.g., "Late Night Vibes", "Morning Energy"). Body: full context object +
omg:admin
name field.
GET
/omg/v1/context/presets
List all saved context presets
omg:admin
POST
/omg/v1/context/presets/{preset_id}/activate
Activate a saved preset as the current context. Immediate effect.
omg:admin
GET
/omg/v1/context/history
Context change history — last 30 days. Shows what context was active during each generation session.
omg:admin
Context Object Schema
{
"context_id": "ctx_20260425_1400",
"genre": "Electronic",
"subgenre": "Ambient Techno",
"mood": ["dreamy", "uplifting", "introspective"],
"lifestyle": "focus", // "focus" | "party" | "chill" | "workout" | "sleep"
"tempo_range": [110, 124], // BPM min, max
"key_preference": "minor", // "major" | "minor" | "any"
"energy_level": 0.65, // 0.0–1.0
"time_of_day": "afternoon", // auto-set from server time, overridable
"active_since": "2026-04-25T14:00:00Z",
"auto_rotate": true, // bool — context auto-shifts every 30 min
"next_rotation": "2026-04-25T14:30:00Z"
}
Module E — Generative Music Engine
Generate original audio tracks using the trained OMG model + context
E
Music Generation Endpoints
Service-to-service: called by the Radio Scheduler, not directly by users
Generation is an async operation.
POST /generate/track returns a generation_id immediately. Poll GET /generate/track/{generation_id} or listen for the omg.track.generation_complete webhook event.
POST
/omg/v1/generate/track
Kick off AI track generation. Accepts a context object (or
omg:generate
context_id to pull from Module D). Returns generation_id instantly.
GET
/omg/v1/generate/track/{generation_id}
Poll generation status. When
omg:generate
status === "complete", response includes stream_url (temp CDN link, 24h TTL) and full track metadata.
POST
/omg/v1/generate/track/{generation_id}/regenerate
Re-generate with the same context but a different seed. Useful for admin quality checks.
omg:admin
GET
/omg/v1/generate/queue
View the generation queue: pending jobs, estimated wait times, GPU load. Admin view.
omg:admin
DELETE
/omg/v1/generate/track/{generation_id}
Cancel a pending generation job (cannot cancel in-progress generation)
omg:generate
POST /omg/v1/generate/track — Request Body
{
"context_id": "ctx_20260425_1400", // use existing context, OR provide inline:
"context_override": { // optional — merge over active context
"genre": "Electronic",
"mood": ["dreamy", "uplifting"],
"tempo_range": [110, 124]
},
"model_version": "omg-audio-v2.4", // null = use production model
"max_duration_sec": 210,
"seed": null, // null = random seed; set for reproducibility
"quality": "320kbps",
"include_lyrics": false, // if true, Module F is invoked automatically
"session_id": "OMG-SESSION-001" // radio session for attribution
}
Generation Complete Response
{
"generation_id": "gen_xyz789",
"status": "complete",
"duration_ms": 8200, // generation time in ms
"track_origin": "ai_generated",
"omg_track_id": "OMG-SESSION-001-042", // assigned by Module G
"title": "Ephemeral Drift", // AI-generated title
"genre": "Electronic",
"mood": ["dreamy", "uplifting"],
"bpm": 118,
"duration_sec": 203,
"model_version": "omg-audio-v2.4",
"stream_url": "https://cdn.ookimusic.com/omg/gen/gen_xyz789.mp3",
"stream_url_expires": "2026-04-26T14:00:00Z",
"waveform_url": "https://cdn.ookimusic.com/omg/wf/gen_xyz789.json"
}
Module F — Generative Lyrics Engine
AI-generated original lyrics trained exclusively on Ooki songwriter data
F
Lyrics Generation Endpoints
Only fires when
lyrics_generation: true in admin config
POST
/omg/v1/generate/lyrics
Generate original lyrics. Returns a
omg:generate
lyric_id and full lyrics structured by verse/chorus/bridge. Synchronous for short outputs (<60s).
GET
/omg/v1/generate/lyrics/{lyric_id}
Retrieve generated lyrics with full structured output and safety scores
omg:generate
POST
/omg/v1/generate/lyrics/{lyric_id}/safety-check
Run explicit content and copyright similarity check on generated lyrics. Required before playback if
omg:generate
explicit_allowed: false.
Request Body
{
"mood": ["longing", "hopeful"],
"theme": "late nights and new beginnings",
"language": "en", // ISO 639-1
"structure": "verse-chorus-verse-bridge-chorus",
"style_artist_ids": ["art_042"], // style INFLUENCE only — must be Ooki artists
"model_version": "omg-lyrics-v1.1",
"generation_id": "gen_xyz789" // link to corresponding audio generation
}
Response
{
"lyric_id": "lyr_abc456",
"theme": "late nights and new beginnings",
"language": "en",
"model_version": "omg-lyrics-v1.1",
"safety_score": 0.97, // 0.0–1.0; must be >= 0.80 for playback
"explicit_detected": false,
"structure": {
"verse_1": "Neon signs and empty streets...",
"chorus": "We're just starting now...",
"verse_2": "Heartbeats echo through the cold...",
"bridge": "And somewhere past the horizon line..."
}
}
Module G — AI Track Registry & Attribution
Immutable log of every AI-generated track — legal audit trail
G
Registry Endpoints
Every AI track MUST be registered before playback. Registry is append-only.
POST
/omg/v1/registry/tracks
Register a newly generated track. Called automatically by Module E on generation complete. Returns
omg:generate
omg_track_id.
GET
/omg/v1/registry/tracks
List all registered AI tracks. Filters:
omg:admin
?session_id=, ?date_from=, ?date_to=, ?model_version=, ?reuse_eligible=true
GET
/omg/v1/registry/tracks/{omg_track_id}
Full registry record for a single AI track including attribution, playback count, safety score, and model lineage
omg:admin
PATCH
/omg/v1/registry/tracks/{omg_track_id}
Update mutable fields only:
omg:admin
reuse_eligible, flag_for_review. All other fields are immutable after creation.
GET
/omg/v1/registry/sessions
List radio sessions with aggregate stats: tracks generated, tracks played, listener hours, generation success rate
omg:admin
POST
/omg/v1/registry/tracks/{omg_track_id}/playback
Increment playback counter. Called by the Radio Scheduler each time a track plays.
omg:generate
GET
/omg/v1/registry/audit-export
Export full audit log as CSV or JSON for legal review. Requires
omg:admin
omg:admin. Query params: ?format=csv|json&date_from=&date_to=
Registry Record Schema
{
"omg_track_id": "OMG-SESSION-001-042",
"generation_id": "gen_xyz789",
"track_type": "ai_generated", // always "ai_generated" in this registry
"session_id": "OMG-SESSION-001",
"radio_only": true, // cannot be sold/licensed
"model_version": "omg-audio-v2.4",
"lyrics_model_version":"omg-lyrics-v1.1", // null if no lyrics generated
"training_dataset_hash":"sha256:a3f8c9e...", // immutable audit fingerprint
"context_snapshot": { // frozen at generation time
"genre": "Electronic",
"mood": ["dreamy", "uplifting"],
"tempo_range": [110, 124]
},
"generated_at": "2026-04-25T14:22:10Z",
"first_played_at": "2026-04-25T14:24:00Z",
"playback_count": 1,
"reuse_eligible": false, // mutable — admin can toggle
"flag_for_review": false, // mutable — triggers safety review queue
"safety_score": 0.98
}
Module H — OMG Radio Station UI API
Public endpoints used by the frontend radio player — listener-facing
H
Public Radio Station Endpoints
Used by
app/omg-radio.html — requires listener Bearer token only
GET
/omg/v1/radio/stream-info
Get station info: stream URL, bitrate, current listener count, station status. Used on page load before WebSocket connects.
omg:read
GET
/omg/v1/radio/now-playing
Current now-playing card: title, artist, genre, duration, elapsed, is_ai_generated, album art URL. Polling fallback if WebSocket is unavailable.
omg:read
GET
/omg/v1/radio/queue
Upcoming track queue (next 5 tracks). Shows catalog vs AI indicator for each. Used to render the queue list in the UI.
omg:read
GET
/omg/v1/radio/history
Recently played tracks — last 20. Query param:
omg:read
?session_id= to filter by session.
POST
/omg/v1/radio/feedback
Submit listener feedback on a track:
omg:read
{"omg_track_id": "...", "rating": "thumbs_up"|"thumbs_down", "flag_inappropriate": false}
Now-Playing Response
{
"omg_track_id": "OMG-SESSION-001-042",
"title": "Ephemeral Drift",
"artist": "OMG Radio", // or real artist name if catalog
"is_ai_generated": true,
"track_origin": "ai_generated", // "catalog" | "ai_generated"
"genre": "Electronic",
"mood": ["dreamy", "uplifting"],
"duration_sec": 203,
"elapsed_sec": 87,
"cover_art_url": "https://cdn.ookimusic.com/omg/art/gen_xyz789.jpg",
"waveform_url": "https://cdn.ookimusic.com/omg/wf/gen_xyz789.json",
"transparency": { // Module I data — only for ai_generated
"model_version": "omg-audio-v2.4",
"influencing_genre":"Electronic",
"influencing_mood": ["dreamy", "uplifting"],
"lyrics_source": "omg_lyrics_engine" // or null if instrumental
}
}
Module I — Transparency Panel API
Expandable AI disclosure info — listeners can see what influenced the generation
I
Transparency Endpoints
Powers the "About this track" expandable panel in the listener UI
GET
/omg/v1/transparency/{omg_track_id}
Full transparency record for an AI-generated track: what model was used, what context influenced it, lyrics source, training dataset summary (without exposing raw data).
omg:read
GET
/omg/v1/transparency/station
Station-level transparency: general statement about the OMG Radio system, legal compliance summary, total AI tracks played, training data policy summary.
omg:read
Track Transparency Response
{
"omg_track_id": "OMG-SESSION-001-042",
"is_ai_generated": true,
"model_version": "omg-audio-v2.4",
"training_data_source": "Ooki-owned audio masters and registered songwriter lyrics only",
"influencing_genre": "Electronic",
"influencing_mood": ["dreamy", "uplifting"],
"influencing_lifestyle": "focus",
"lyrics_source": "omg_lyrics_engine",
"lyrics_model_version": "omg-lyrics-v1.1",
"no_third_party_content": true,
"generated_at": "2026-04-25T14:22:10Z",
"policy_url": "https://ookimusic.com/ai-policy"
}
WebSocket Channels
Real-time push — now playing, listener count, generation progress
WS
WebSocket Channels
Base:
wss://radio.ookimusic.com/omg/ws/ — authenticate via ?token=<jwt> query param
WS
wss://radio.ookimusic.com/omg/ws/now-playing
omg:read
Broadcasts a new
now_playing message every time a track changes. All connected clients receive simultaneously.// Incoming message shape
{
"event": "now_playing",
"data": { /* same as GET /radio/now-playing response */ },
"server_time_utc": "2026-04-25T14:24:00Z"
}
WS
wss://radio.ookimusic.com/omg/ws/listeners
omg:read
Broadcasts live listener count every 15 seconds.
{ "event": "listener_count", "count": 1247, "peak_today": 2384 }
WS
wss://radio.ookimusic.com/omg/ws/generation-progress
omg:admin
Admin-only. Real-time progress ticks for in-flight generation jobs. Powers the generation progress bars in the admin panel.
{
"event": "generation_progress",
"generation_id": "gen_xyz789",
"progress_pct": 73,
"eta_seconds": 12
}
WS
wss://radio.ookimusic.com/omg/ws/training-progress
omg:train
Real-time training epoch ticks. Powers the training progress charts in the admin panel (Module C).
{
"event": "training_epoch",
"job_id": "job_abc123",
"epoch": 24,
"loss": 0.0842,
"perplexity": 12.4
}
Frontend Connection Example
// Connect with auth token const ws = new WebSocket( `wss://radio.ookimusic.com/omg/ws/now-playing?token=${jwtToken}` ); ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.event === 'now_playing') { updateNowPlayingCard(msg.data); // update UI if (msg.data.is_ai_generated) { showTransparencyPanel(msg.data.transparency); } } }; // Reconnect on disconnect (exponential backoff) ws.onclose = () => setTimeout(connectRadioWS, backoffMs);
OMG Radio Webhook Events
Server-to-server push events — register via the Webhooks portal
HOOKS
Webhook Events Reference
All events include
event, timestamp, data, and signature (HMAC-SHA256) fields
omg.radio.enabled
Station was turned on by an admin
omg.radio.disabled
Station was gracefully shut down
omg.track.now_playing
A new track started playing (catalog or AI). Contains full now-playing card data.
omg.track.generation_complete
AI track generation finished. Data includes
generation_id, omg_track_id, stream_url.
omg.track.generation_failed
Generation job failed. Data includes
generation_id, error_code, message. Scheduler will fall back to catalog.
omg.training.job_completed
Training job finished. Data includes
job_id, model_version_draft, final loss/perplexity.
omg.training.job_failed
Training job failed. Data includes
job_id, error_stage, message.
omg.safety.flag_raised
Safety filter flagged a generated track or lyric. Data includes
omg_track_id, flag_type, safety_score. Track is automatically withheld from playback.
Webhook Payload Example
{
"event": "omg.track.generation_complete",
"timestamp": "2026-04-25T14:22:10Z",
"signature": "sha256=a1b2c3d4...", // HMAC-SHA256 of raw body + your webhook secret
"data": {
"generation_id": "gen_xyz789",
"omg_track_id": "OMG-SESSION-001-042",
"stream_url": "https://cdn.ookimusic.com/omg/gen/gen_xyz789.mp3",
"duration_sec": 203,
"model_version": "omg-audio-v2.4"
}
}
Database Schemas
Core tables the backend team needs to create
omg_config
Module A — Single row, always ID = 1
| Column | Type |
|---|---|
| id | int PK |
| radio_enabled | bool |
| generation_mode | enum |
| catalog_ratio | decimal |
| ai_generation_ratio | decimal |
| lyrics_generation | bool |
| explicit_allowed | bool |
| stream_quality | varchar |
| updated_at | timestamp |
| updated_by | uuid FK users |
omg_training_jobs
Module C — Training run records
| Column | Type |
|---|---|
| job_id | uuid PK |
| model_type | enum |
| status | enum |
| dataset_snapshot_id | uuid FK |
| base_model_id | varchar |
| hyperparams | jsonb |
| current_epoch | int |
| total_epochs | int |
| current_loss | decimal |
| dataset_hash | varchar(64) |
| model_version_draft | varchar |
| started_at | timestamp |
| completed_at | timestamp |
omg_generated_tracks
Module G — AI track registry (append-only)
| Column | Type |
|---|---|
| omg_track_id | varchar PK |
| generation_id | uuid |
| session_id | varchar |
| model_version | varchar |
| lyrics_model_version | varchar |
| training_dataset_hash | varchar(64) |
| context_snapshot | jsonb |
| safety_score | decimal |
| radio_only | bool |
| reuse_eligible | bool |
| flag_for_review | bool |
| playback_count | int |
| generated_at | timestamp |
omg_radio_context
Module D — Context history
| Column | Type |
|---|---|
| context_id | varchar PK |
| genre | varchar |
| subgenre | varchar |
| mood | text[] |
| lifestyle | varchar |
| tempo_min | int |
| tempo_max | int |
| energy_level | decimal |
| key_preference | varchar |
| active_since | timestamp |
| set_by | uuid FK users |
omg_dataset_snapshots
Module B — Dataset version control
| Column | Type |
|---|---|
| snapshot_id | uuid PK |
| name | varchar |
| description | text |
| config_json | jsonb |
| hash | varchar(64) |
| total_masters | int |
| total_lyric_files | int |
| total_audio_hours | decimal |
| created_at | timestamp |
| created_by | uuid FK users |
omg_listener_feedback
Module H — Listener ratings and flags
| Column | Type |
|---|---|
| id | uuid PK |
| omg_track_id | varchar FK |
| user_id | uuid FK users |
| rating | enum |
| flag_inappropriate | bool |
| created_at | timestamp |
Error Codes & Responses
Standard OMG Radio error format
ERR
Error Response Format
All OMG errors follow the same envelope
{
"error": {
"code": "OMG_GENERATION_FAILED",
"http_status":500,
"message": "Track generation timed out after 120s",
"detail": "GPU cluster at capacity — retry after 30s",
"retry_after":30, // seconds; null if no retry
"request_id": "req_1a2b3c4d"
}
}
| HTTP | Error Code | Meaning |
|---|---|---|
| 400 | OMG_INVALID_CONFIG | catalog_ratio + ai_generation_ratio ≠ 1.0, or invalid enum value |
| 401 | OMG_AUTH_REQUIRED | Missing or expired Bearer token |
| 403 | OMG_INSUFFICIENT_SCOPE | Token lacks required scope (e.g., omg:admin required) |
| 404 | OMG_TRACK_NOT_FOUND | omg_track_id does not exist in the registry |
| 409 | OMG_TRAINING_IN_PROGRESS | Cannot start a new training job while one is running for same model type |
| 409 | OMG_RADIO_ALREADY_ENABLED | POST /radio/enable called when radio is already on |
| 429 | OMG_RATE_LIMITED | Too many generation requests. Retry after value in response. |
| 500 | OMG_GENERATION_FAILED | AI generation service error. Scheduler falls back to catalog automatically. |
| 500 | OMG_SAFETY_BLOCK | Safety filter blocked the generated content. Track withheld, new generation triggered. |
| 400 | OMG_DATASET_VIOLATION | Attempted to include non-Ooki-owned content in training dataset |
Environments, Rate Limits & Checklist
Backend build requirements and environment config
ENV
Rate Limits
Public / Listener Endpoints
GET /radio/now-playing (polling)
1 req/sec per user
POST /radio/feedback
10 req/min per user
Admin / Generation Endpoints
POST /generate/track
4 concurrent max
POST /training/jobs
1 per model type
PATCH /admin/config
60 req/min
TODO
Backend Build Checklist for GenSpark
Everything that needs to be wired up before OMG Radio goes live
Infrastructure
Module A — Admin Control
Module B — Dataset Manager
Module C — Training Pipeline
Modules D · E · F
Modules G · H · I + Webhooks