Integrate OmniView into your event app. Submit fan-filmed videos via the API and get a synchronized multi-camera viewer automatically.
API requests are authenticated using an API key tied to a specific event. Include the key in the X-API-Key header.
You receive your API key when you create an event via the API or in the dashboard.
curl -H "X-API-Key: your-api-key" \
https://holossystems.com/api/v1/events
Some read-only endpoints (manifest, video list, job status) do not require authentication.
The primary integration endpoint. Submit a video URL from your event app, optionally with GPS coordinates from the user's phone. The video is automatically synchronized against the reference.
| Parameter | Type | Description | |
|---|---|---|---|
| video_url | string | required | Full URL to the video (YouTube, TikTok, Instagram, SoundCloud) |
| platform | string | optional | youtube, tiktok, instagram, soundcloud. Default: youtube |
| latitude | float | optional | GPS latitude of the recording location (-90 to 90) |
| longitude | float | optional | GPS longitude of the recording location (-180 to 180) |
| title | string | optional | Display title for the video (max 300 chars) |
| user_label | string | optional | Location label from the user, e.g. "Front row left" (max 200 chars) |
curl -X POST https://holossystems.com/api/v1/intake \
-H "X-API-Key: 29c3d488-98fa-4ee9-a179-593754d7d0bf" \
-H "Content-Type: application/json" \
-d '{
"video_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"platform": "youtube",
"latitude": 52.3676,
"longitude": 4.9041,
"title": "Main stage opening",
"user_label": "Front row center"
}'
{
"job_id": "a1b2c3d4-...",
"status": "pending",
"video_id": "dQw4w9WgXcQ",
"message": "Video submitted for synchronization"
}
The first video submitted to an event automatically becomes the reference video. All subsequent videos are synchronized against it. Duplicate submissions return status: "duplicate" instead of an error.
Upload a video file directly instead of submitting a URL. GPS coordinates and compass heading are automatically extracted from the video metadata when available. Use multipart/form-data.
| Parameter | Type | Description | |
|---|---|---|---|
| file | file | required | Video file (mp4, mov, webm, avi, mkv, 3gp) |
| api_key | string | required | Event API key |
| title | string | optional | Display title |
| latitude | float | optional | GPS latitude (overrides video metadata) |
| longitude | float | optional | GPS longitude (overrides video metadata) |
| compass_heading | float | optional | Compass heading in degrees (0-360) |
| device_timestamp | string | optional | ISO 8601 timestamp from the recording device |
| location_name | string | optional | Location label, e.g. "Main Stage" |
curl -X POST https://holossystems.com/api/v1/events/{event_id}/upload \
-F "file=@concert.mov" \
-F "api_key=29c3d488-98fa-4ee9-a179-593754d7d0bf" \
-F "title=Main stage opening"
{
"status": "ok",
"video_id": "abc123",
"job_id": "def456",
"stage": "Main Stage",
"session_date": "2026-04-27"
}
{
"name": "Kingsday 2026",
"date": "2026-04-27",
"location": {
"name": "Museumplein",
"city": "Amsterdam",
"country": "NL",
"lat": 52.3580,
"lon": 4.8828
}
}
{
"id": "9a869d24-...",
"name": "Kingsday 2026",
"date": "2026-04-27",
"api_key": "29c3d488-...",
"status": "active",
"viewer_url": "/view/9a869d24-...",
"videos": []
}
The api_key is only returned on creation. Store it — you'll need it for all subsequent requests.
| Parameter | Type | Description | |
|---|---|---|---|
| source_url | string | required | Full URL to the video |
| platform | string | optional | youtube, tiktok, instagram, soundcloud |
| lat | float | optional | Latitude |
| lon | float | optional | Longitude |
| location_name | string | optional | Location label |
| title | string | optional | Display title |
When you submit a video, you get a job_id back. Poll this endpoint to check if synchronization is complete.
{
"id": "a1b2c3d4-...",
"status": "done",
"result": {
"offset_ms": -2340.5,
"confidence": 0.92,
"method": "audio_fingerprint"
}
}
| Status | Meaning | ||
|---|---|---|---|
| pending | Queued, waiting for processing | ||
| done | Successfully synchronized | ||
| failed | Sync failed — check result.error | ||
| Code | Meaning | ||
|---|---|---|---|
| 200 | Success | ||
| 201 | Created | ||
| 400 | Invalid request (bad URL, unsupported platform) | ||
| 401 | Missing or invalid API key | ||
| 403 | Event inactive or tier limit reached | ||
| 404 | Event or video not found | ||
| 409 | Duplicate video | ||
| 429 | Rate limit exceeded | ||
API intake requests are limited to 30 requests per minute per IP address. If you exceed this limit, you'll receive a 429 response. Wait and retry.
{
"detail": "Invalid API key"
}