You are viewing documentation for an outdated version of the specification.
OMSS v1.0 Specification
Open Media Streaming Specification Version: 1.0.0 Status: StableReleased: January 11, 2026
License: MIT
Table of Contents
- Introduction
- Core Principles
- API Conventions
- Endpoints
- Request Specifications
- Response Specifications
- Error Handling
- Caching and Performance
- Security Considerations
- Compliance Requirements
- Versioning and Compatibility
- Provider Data Handling
1. Introduction
1.1 Purpose
OMSS (Open Media Streaming Specification) defines a unified REST API standard for streaming media backends. It enables any frontend application to work seamlessly with any OMSS-compliant backend through standardized endpoints for retrieving streaming sources.1.2 Problem Statement
Modern streaming backends scrape data from various providers with inconsistent formats:- No standardized metadata: Files may be MP4, HLS, or DASH without clear type information.
- Missing quality information: Bitrate, resolution, and codec data are often unavailable.
- Language ambiguity: Audio/subtitle language tracks may be unlabeled.
- Ephemeral URLs: Signed URLs with expiration times require special handling.
- Cross-origin restrictions: Sources require proxy handling for CORS and access control.
1.3 Design Philosophy
- Source-focused: OMSS is about standardizing streaming sources, not media metadata.
- Pragmatic: Designed for backends that scrape third-party providers with incomplete data.
- Progressive disclosure: Required fields are minimal; optional fields provide enhanced functionality.
- HTTP-first: Uses HTTP status codes, headers, and semantics correctly.
- Proxy-enabled: All sources route through the OMSS proxy endpoint to handle provider restrictions.
1.4 Scope
In Scope:- REST API endpoint definitions for source retrieval.
- Standardized source/subtitle schemas.
- Proxy endpoint for source access.
- Error handling patterns.
- Caching strategies.
- Access control/authentication — implement that yourself. (you are no fun😔. Personal Note: I would not recommend hosting such a backend publicly anyway, since it brings risk and costs with it. For personal use you do not need these.)
- Media metadata (ratings, descriptions, posters, etc.) — use the TMDB API directly.
- Search functionality — use the TMDB API.
- Provider-specific scraping logic — implement that yourself.
- Video player implementation — whichever player you use.
1.5 TMDB Integration
OMSS uses TMDB (The Movie Database) as the primary identifier for all media content:- Frontend responsibility: Fetch media metadata (title, year, poster, description, ratings) from the TMDB API.
- OMSS responsibility: Provide streaming sources and subtitles for TMDB IDs.
- Clean separation: OMSS focuses exclusively on source standardization.
2. Core Principles
2.1 HTTP-First Design
- Primary signal: HTTP status codes indicate success or failure.
- Secondary signal: The response body provides details.
- Standard headers: Use
Cache-Control,ETag,Retry-After, etc.
2.2 Proxy-First Architecture
- All sources route through the proxy: Every
urlfield uses the OMSS proxy endpoint. - CORS handling: The proxy manages cross-origin requests.
2.3 Unknown Data Handling
Backends MUST handle incomplete provider data gracefully:- Missing metadata: Omit optional fields rather than returning null or empty values.
- Quality and language inference: Attempt to infer quality and language from filenames, manifests, resolution, or bitrate.
- Type detection: Analyze file extension, MIME type, or content headers.
2.4 Identifier Strategy
- Primary: TMDB (The Movie Database) IDs.
- Required: All media MUST have a TMDB ID.
2.5 Versioning
- URL-based:
/v1/,/v2/in the path. - Semantic versioning:
MAJOR.MINOR.PATCH. - Breaking changes: Require a new major version.
3. API Conventions
3.1 Base URL
3.2 Content Type
- Request:
application/json; charset=utf-8 - Response:
application/json; charset=utf-8
3.3 Character Encoding
UTF-8 MUST be used for all text data.3.4 Date/Time Format
ISO 8601 format MUST be used:3.5 Naming Conventions
- Fields: camelCase (e.g.,
expiresAt,mimeType). - Enums: lowercase (e.g.,
hls,mp4,vtt). - Error codes: SCREAMING_SNAKE_CASE (e.g.,
INVALID_ID,NOT_FOUND).
3.6 Content Negotiation
OMSS v1.0 supports only JSON responses. Supported:Accept: application/json→ 200 OK with JSONAccept: */*→ 200 OK with JSON (default)
Accept: application/xml→ Throws a 406 Not Acceptable error. See 7.3 Standard Error Codes
3.7 Preflight Requests
OMSS backends MUST handle OPTIONS requests for CORS preflight correctly. Example:4. Endpoints
4.1 Home
Purpose: General information about the backend.name(string): Implementation name.version(string): Semantic version of the OMSS implementation (e.g.,1.0.0).status(string): API status —operational,degraded, ordown(e.g. maintenance).endpoints(object): Functions mapped to paths.movie(string): Path to the movie endpoint. MUST contain the{id}placeholder where the frontend will insert the TMDB ID.tv(string): Path to the TV show endpoint. MUST contain the{id},{s}and{e}placeholders where the frontend will insert the TMDB ID, season and episode respectively.proxy(string): Path to the proxy endpoint. MUST contain the{encoded_data}placeholder where the frontend will insert the URI-encoded data object.
spec(string): When implementing OMSS, this MUST be"omss".
note(string): A custom message.
4.2 Movie Sources
Purpose: Retrieve movie streaming sources by TMDB ID.id(string, required): TMDB movie ID.
4.3 TV Episode Sources
Purpose: Retrieve TV episode streaming sources.id(string, required): TMDB series ID.s(integer, required): Season number (≥ 0).e(integer, required): Episode number (≥ 1).
4.4 Proxy Endpoint
Purpose: Unified proxy endpoint for streaming sources, subtitles, and manifests through the OMSS backend, since almost all providers have CORS or other restrictive security logic in place. This endpoint will make a request tourl with the provided headers and stream the response back to the client.
The Proxy also has to rewrite the manifest files (HLS/DASH) to ensure all sub-resources also go through the proxy.
Important Note: To send the data object to the backend you have to use encodeURIComponent() (not encodeURI()).
data(string, required): URL-encoded JSON proxy request object (useencodeURIComponent(), NOTencodeURI()).
4.5 Refresh Endpoint
Purpose: Unified endpoint to refresh a source by its unique ID.responseId(string, required): The unique ID of the source to refresh.
responseId is valid the response will always be 200 OK, since the backend should simply remove the cache entry and will try to fetch a new source the next time the frontend requests it. If it is invalid, see 7.3 Standard Error Codes.
5. Request Specifications
5.1 Headers
Required:Accept: application/json; charset=utf-8
5.2 Query Parameters
Validation Rules:- Query parameters are case-sensitive.
- Boolean parameters:
trueorfalse(lowercase).
5.3 Path Parameters
Validation Rules:id: String (numeric characters ONLY, treated as a string).s: Non-negative integer (0–99 typical range).e: Positive integer (≥ 1).
6. Response Specifications
6.1 Success Response
HTTP Status: 200 OKresponseId(string): Unique response identifier (e.g. UUID v4).sources(array): Array of Source objects (at least one required. if no source found, see 7.4.1).subtitles(array): Array of Subtitle objects (may be empty).diagnostics(array): Non-fatal warnings/errors about data quality/inference and provider issues (may be empty).expiresAt(string, optional): ISO 8601 timestamp when sources expire (for signed/temporary URLs).
6.2 Source Object
Purpose: Represents a streaming source with quality and technical metadata.6.2.1 Required Fields
-
url(string): Proxy endpoint URL for this source. Must contain the encoded data object.- MUST be in the format:
/v1/proxy/?data={encoded_data}. - Example:
/v1/proxy/?data=%7B%0D%0A%20%20%20%20%22url%22%3A%20%22https%3A%2F%2Fprovider%2Ecom%2Fstream%2Fabcd1234%2Emp4%22%2C%0D%0A%20%20%20%20%22headers%22%3A%20%7B%0D%0A%20%20%20%20%20%20%20%20%22Referer%22%3A%20%22https%3A%2F%2Fprovider%2Ecom%2Fwatch%2Fabcd1234%22%2C%0D%0A%20%20%20%20%20%20%20%20%22more%22%3A%20%22custom%20headers%20as%20needed%22%0D%0A%20%20%20%20%7D%0D%0A%7D
- MUST be in the format:
-
type(string): Source type, one of:hls— HTTP Live Streaming (M3U8).dash— MPEG-DASH (MPD).mp4— MP4 file.mkv— MKV file.webm— WebM file.embed— Embedded player (iframe). Note: This is not recommended for OMSS compliance, but can be used as a last resort. Avoid using embed and use direct streaming links instead. For frontend developers: Try to prevent users from using embedded players, since they usually have ads, trackers, and other unwanted content. Backend developers: Do your best to avoid using embed links. If you must return an embed link, go as far down the embed stack as possible to get the cleanest link.
-
quality(string): Video quality. There is no standardized list of qualities. -
audioTracks(array): Array of audio track objects. Default is English (en) if unknown.- Each audio track object contains:
language(string): Audio language (ISO 639-1 code).label(string): Human-readable language name.
- Each audio track object contains:
-
provider(object): Information about the upstream provider.id(string): Unique provider identifier.name(string): Human-readable provider name.
6.2.2 Handling Unknown Source Data
When scraping providers with incomplete metadata:Type Detection Order
-
File extension:
.m3u8→hls.mpd→dash.mp4→mp4.mkv→mkv.webm→webm
-
MIME type from the HTTP
Content-Typeheader. -
Content inspection (first few bytes):
#EXTM3U→hls<?xmlwithMPD→dash- Magic numbers for video containers.
-
Default: If unknown, use
embedas a fallback.
Quality Inference
-
Parse filename for quality indicators:
- Regex example:
/(\d{3,4}p|4K|8K|HD|SD|UHD)/i. - Examples:
movie_1080p.mp4,stream_4k.m3u8.
- Regex example:
-
Analyze resolution from manifest or stream metadata:
- HLS:
#EXT-X-STREAM-INF:RESOLUTION=1920x1080. - DASH:
<Representation width="1920" height="1080">.
- HLS:
-
If unknown:
qualityMUST be provided, so use"unknown".
Language Detection
-
Parse from filename:
- Patterns:
movie.en.mp4,stream_eng.m3u8,video-english.mp4.
- Patterns:
-
Extract from manifest metadata:
- HLS:
#EXT-X-MEDIA:LANGUAGE="en". - DASH:
<Representation lang="en">.
- HLS:
-
If unknown: Set the
languagefield toen(English) by default.
6.2.3 Multi-Audio Handling
For HLS/DASH with native multi-audio: The file returned by theurl field contains multiple audio tracks. The audioTracks array describes each track.
Seperate audio tracks are not supported in this version of the specification.Player Responsibility: Frontend players handle audio track switching using manifest metadata.
6.3 Subtitle Object
Purpose: Represents subtitle/caption tracks.6.3.1 Required Fields
-
url(string): Proxy endpoint path for this subtitle.- MUST be in the format:
/v1/proxy?data={encoded_data}. - Example:
/v1/proxy?data=%7B%0D%0A%20%20%20%20%22url%22%3A%20%22https%3A%2F%2Fprovider%2Ecom%2Fsub%2Fabc1234%2Evtt%22%2C%0D%0A%20%20%20%20%22headers%22%3A%20%7B%0D%0A%20%20%20%20%20%20%20%20%22Referer%22%3A%20%22https%3A%2F%2Fprovider%2Ecom%2Fdownload%2Fabcd1234%22%2C%0D%0A%20%20%20%20%20%20%20%20%22more%22%3A%20%22custom%20headers%20as%20needed%22%0D%0A%20%20%20%20%7D%0D%0A%7D
- MUST be in the format:
-
label(string): Human-readable language name.- Examples:
English,Spanish,Deutsch,日本語. - Should match the language code.
- Backends should attempt to infer this from filename or content, without adding extra metadata or ads.
- If unknown, use
"Unknown".
- Examples:
-
format(string): Subtitle format, one of:vtt— WebVTT (preferred for web; default).srt— SubRip.ass— Advanced SubStation Alpha.ssa— SubStation Alpha.ttml— Timed Text Markup Language.
6.3.3 Handling Unknown Subtitle Data
When scraping providers with incomplete subtitle metadata:Label Generation
-
Parse from filename:
- Patterns:
subs.en.vtt,subtitle_english.srt,movie.spa.vtt. - Common codes:
eng,en,spa,es, etc.
- Patterns:
-
If unknown: Use
"Unknown"as the label.
Format Detection
-
File extension:
.vtt→vtt..srt→srt..ass→ass..ssa→ssa.
-
If unknown: Use
vttas the default format.
6.4 Warning/Error Objects in Success Response
Purpose: Report non-response-fatal issues encountered during scraping. Iffield is an empty string, it means the warning applies to the entire response.
Description: A non-response-fatal warning/error is an issue encountered during scraping that does not prevent the backend from returning a successful response. These warnings/errors provide additional context about potential data quality issues or provider-specific scraping failures (for example: "Provider [name] failed to respond" would be a non-response-fatal error).
code(string): Machine-readable warning/error code.message(string): Human-readable description.field(string, optional): JSON path to the affected field.severity(string): One of:info— Informational notice.warning— Non-fatal issue.error— Fatal issue.
6.4.1 Standard Warning/Error Codes
7. Error Handling
7.1 Error Response Format
All non-2xx responses MUST include:error.code(string): Machine-readable error code.error.message(string): Human-readable error description.traceId(string): Unique identifier for error tracking/debugging.
error.details(object): Additional context about the error. Frontends should not display this.
7.3 Standard Error Codes
7.4 Edge Cases
7.4.1 Media Exists, No Sources
HTTP Status: 404 Not Found When the TMDB ID is valid but no streaming sources are available:7.4.2 Invalid TMDB ID
HTTP Status: 400 Bad Request7.4.3 TMDB ID Not Found
HTTP Status: 404 Not Found8. Caching and Performance
8.1 Caching Strategies
OMSS does not mandate specific caching strategies, but recommends best practices for both backends and clients to optimize performance. Backends should implement caching strategies to improve performance and reduce load on upstream providers, and also to help avoid IP bans. Recommended strategies include:- In-memory caching (e.g. Redis, Memcached).
- Cache sources and subtitles separately.
- Cache sources for around 2 hours (7,200 seconds) by default.
- Cache subtitles for longer durations (e.g. 24 hours).
- When the refresh endpoint is called, the cache for that specific source should be invalidated immediately.
- For large/public backends, consider caching with a CDN and browser caching headers.
- Do NOT cache proxy responses.
8.5 Performance Recommendations
For Backends:- Implement request coalescing for concurrent identical requests.
- Use connection pooling for upstream providers.
- Implement circuit breakers for failing providers.
- Pre-fetch sources for popular content.
- Respect cache headers and ETags.
- Implement exponential backoff for retries.
- Prefetch sources before playback.
- Monitor
expiresAtand refresh proactively. - Use conditional requests (
If-None-Match). - Implement client-side caching of source lists.
9. Security Considerations
9.1 HTTPS Requirement
- Production: All endpoints MUST use HTTPS.
- Development: HTTP is allowed for
localhostonly.
9.2 Input Validation
Backends MUST validate:-
Path parameters:
id: Alphanumeric, max 20 characters.s: Integer, 0–99.e: Integer, 1–9,999.responseId: Alphanumeric with hyphens/underscores, max 128 characters.
-
Query parameters:
- Reject SQL injection attempts.
-
Headers:
- Enforce size limits (to prevent header overflow attacks).
9.3 Proxy Security
It is recommended that you implement SSRF safeguards: validate that upstream URLs are not internal/private IPs.10. Compliance Requirements
10.1 Required for OMSS v1.0 Compliance
A backend MUST implement:-
Core endpoints:
GET /v1/movies/{tmdbId}GET /v1/tv/{tmdbId}/seasons/{s}/episodes/{e}GET /v1/proxy?data={encoded_data}GET /,/v1, or/v1/health
-
Source object with required fields:
url(as proxy path),type,quality,audioTracks,provider.
-
Subtitle object with required fields:
url(as proxy path),label,format.
-
Error responses for all non-2xx responses with:
error.code,error.message,traceId.
-
HTTP status codes:
- 200 for success.
- 400 for bad requests.
- 404 for not found.
- 500 for server errors.
-
Proxy routing: All
urlfields MUST use proxy paths. - HTTPS in production.
11. Versioning and Compatibility
11.1 Semantic Versioning
OMSS follows Semantic Versioning 2.0.0:- MAJOR: Breaking changes (incompatible API changes).
- MINOR: Backward-compatible new features.
- PATCH: Backward-compatible bug fixes/clarifications.
11.2 URL Versioning
Version is in the URL path:11.4 Deprecation Policy
- Announce at least 6 months before removal.
-
Headers: Deprecated endpoints return:
- Documentation: Migration guides are provided.
- Support: Deprecated features are supported for ≥ 1 major version.
- Removal: Only in a new major version.
11.5 Client Compatibility Expectations
Clients MUST:- Ignore unknown fields in responses.
- Use HTTP status codes as the primary signal.
- Handle new error codes gracefully.
- Support redirect responses (3xx).
- Version lock to a specific OMSS version (
/v1/). - Upgrade proactively when new versions are released.
- Monitor deprecation headers.
- Implement graceful degradation for missing required fields.
12. Provider Data Handling
12.1 Real-World Constraints
Backends scrape data from third-party providers with:- No standardization: Each provider has custom formats.
- Incomplete metadata: Missing quality, language and other information.
- Inconsistent naming: Files like
unknown.mp4,stream. - Dynamic URLs: Signed/expiring URLs requiring refresh.
- Unreliable availability: Sources disappear without notice.