Skip to main content

OMSS v1.1 Specification

Open Media Streaming Specification Version: 1.1.0 Status: Final Released: June 15th, 2026 License: MIT

Table of Contents

  1. Introduction
  2. Core Principles
  3. API Conventions
  4. Endpoints
  5. Request Specifications
  6. Response Specifications
  7. Error Handling
  8. Caching and Performance
  9. Security Considerations
  10. Versioning and Compatibility
  11. Complete Examples
  12. License

1. Introduction

1.1 Purpose

OMSS (Open Media Streaming Specification) v1.1 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 MKV 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 might require proxy handling for CORS and access control.
OMSS standardizes streaming sources while acknowledging these real-world constraints.

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.

1.4 Scope

In Scope:
  • REST API endpoint definitions for source retrieval.
  • Standardized source/subtitle schemas.
  • Error handling patterns.
Out of Scope:
  • Access control/authentication — implement that yourself. (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.
That is because currently it seems that TMDB is the only decent API provider that is free, has a large database and a stable API. Supporting identifiers from multiple providers like anilist, trakt, or Sport Events etc. would add complexity and since these API’s aren’t really stable, also add a lot of maintenance work for backend developers, without really providing significant benefits to the end users.

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 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.3 Identifier Strategy

  • Primary: TMDB (The Movie Database) IDs.
  • Required: All media MUST have a TMDB ID.

2.4 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

All endpoints are relative to this base URL. From here on, all absolute paths are meant to be relative, starting from the web root. Clients should support non-root deployments, so the base URL can be configured as needed (e.g., https://api.example.com/omss/), but for simplicity, the specification assumes a root deployment.

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.1 supports only JSON responses. Supported:
  • Accept: application/json → 200 OK with JSON
  • Accept: */* → 200 OK with JSON (default)
Unsupported:

3.7 Preflight Requests

OMSS backends MUST handle OPTIONS requests for CORS preflight correctly. Example:
Response: 204 No Content

4. Endpoints

4.1 Home

Purpose: General information about the backend.
Response: 200 OK
Required Fields:
  • name (string): Implementation name.
  • version (string): Semantic version of the OMSS implementation (e.g., 1.1.0).
  • status (string): API status — operational, degraded, or down (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.
  • spec (string): When implementing OMSS, this MUST be "omss".
  • media (object): field for backends to provide a list of available media.
    • movies (array of integers OR string: ’_’ as const): List of TMDB movie IDs available in this backend or '_' if the backend supports all movies.
    • tv (array of objects or string: ’_’ as const): List of TMDB TV series IDs with available seasons and episodes, or '_'if the backend supports all TV series. You can use'\*' inside of the tv object to mark a specific series and/or season as available. Each object contains:
      • id (integer): TMDB series ID.
      • seasons (array of objects): List of seasons with available episodes. Each object contains:
        • season (integer): Season number.
        • episodes (array of integers): List of episode numbers available in this season.
  • providers (array of objects): List of providers this backend provides. Each object contains:
    • id (string): Unique provider identifier (MUST BE URL SAFE).
    • name (string): Human-readable provider name.
    • capabilities (array of strings): List of media types the provider supports any of movies, tv and/or subtitles.
Optional Fields:
  • note (string): A custom message by the backend.

4.2 Movie Sources

[!CAUTION] This endpoint is sunset as of OMSS v1.1 and will be removed in the next major version of the specification. Clients SHOULD migrate to the replacement endpoint defined by OMSS v2 once available. Backends implementing OMSS v1.x MUST continue to support this endpoint for the lifetime of the v1 specification.
Purpose: Retrieve movie streaming sources by TMDB ID.
Path Parameters:
  • id (string, required): TMDB movie ID.
Query Parameters:
  • platform (string, optional): Target platform for source optimization. One of web, native. Default is web. This will change the response structure!
  • provider (string, optional): Specific provider to fetch sources from. MUST be a valid provider ID. The result will stay the same, but the backend shall only return sources from the specified provider.
  • filter (string, optional): filter expression(s) to apply on the returned sources. The syntax and semantics of the filter expressions are defined at 5.4 Filter Expression Syntax. The filter parameter is only applicable to the sources array in the response, and does not affect the subtitles array.
Example Request:
Response: 200 OK (see 6.1 Success Response)

4.3 TV Episode Sources

[!CAUTION] This endpoint is sunset as of OMSS v1.1 and will be removed in the next major version of the specification. Clients SHOULD migrate to the replacement endpoint defined by OMSS v2 once available. Backends implementing OMSS v1.x MUST continue to support this endpoint for the lifetime of the v1 specification.
Purpose: Retrieve TV episode streaming sources.
Path Parameters:
  • id (string, required): TMDB series ID.
  • s (integer, required): Season number (≥ 0).
  • e (integer, required): Episode number (≥ 1).
Query Parameters:
  • platform (string, optional): Target platform for source optimization. One of web, native. Default is web. This will change the response structure!
  • provider (string, optional): Specific provider to fetch sources from. MUST be a valid provider ID. The result will stay the same, but the backend shall only return sources from the specified provider.
  • filter (string, optional): filter expression(s) to apply on the returned sources. The syntax and semantics of the filter expressions are defined at 5.4 Filter Expression Syntax. The filter parameter is only applicable to the sources array in the response, and does not affect the subtitles array.
Example Requests:
Response: 200 OK (see 6.1 Success Response)

4.4 Proxy Endpoint (sunset)

In previous versions of OMSS, the spec used to dictate the proxy behaviour. Starting v1.1, that isn’t the case anymore. It is up to the backend to decide how to/if it wants to implement the proxy.

4.5 Refresh Endpoint

[!CAUTION] This endpoint is sunset as of OMSS v1.1 and will be removed in the next major version of the specification. Clients SHOULD migrate to the replacement endpoint defined by OMSS v2 once available. Backends implementing OMSS v1.x MUST continue to support this endpoint for the lifetime of the v1 specification.
Purpose: Unified endpoint to refresh a response by its id.
Path Parameters:
  • id (string, required): The ID of the response to refresh.
Response Object Schema:
Example Request:
Response: 200 OK If the id is valid the response will always be 200 OK, since the backend should simply remove the cache entry and immediatley invalidate the id 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 lowercase.
  • Boolean parameters: true or false (lowercase).

5.3 Path Parameters

Validation Rules:
  • id: String (numeric characters ONLY, treated as a string).
  • s: Non-negative integer (0–∞ range).
  • e: Positive integer (≥ 1).

5.4 Filter Expression Syntax

The optional filter query parameter allows clients to filter the returned sources (not subtitles) based on their properties. Filtering is applied by the backend after source retrieval and before the response is returned to the client.

5.4.1 Syntax

A filter expression consists of one or more conditions.
The semicolon (;) acts as a logical AND operator. All conditions MUST evaluate to true for an item to be included in the response. Examples:

5.4.2 Operators

The following operators are supported: The wildcard * MAY be used with any operator and/or search string to match any value. When used with ==, it matches any non-empty value. When used with !=, it matches no values. When used with =in= or =out=, it behaves as if all possible values were included in the set. Examples:

5.4.3 Supported Fields

Backends MUST support filtering on the following fields: Backends MAY support additional fields. Clients MUST support the required fields (see above) and should ignore unsupported fields without throwing an error.

5.4.4 Array Matching

For array fields such as audioTracks, a condition matches if at least one element in the array satisfies the condition. Examples:
The following source:
matches both expressions above.

5.4.5 Examples

Return only 4K sources:
Return only streamable HLS sources:
Return only sources from a specific provider:
Return sources with English or German audio:

5.4.6 Invalid Filter Expressions

If the filter expression contains invalid syntax, unsupported operators, malformed values, or unknown fields, the backend MUST return:
with HTTP status 400 Bad Request, before any other processing of the request is done.

6. Response Specifications

6.1 Success Response

Both the movie and TV episode endpoints share this response structure, which includes arrays of Source and Subtitle objects, as well as any diagnostics about data quality or scraping issues. The response structure will stay the same regardless of the provider query parameter, as it only returns sources from the specified provider. If the provider parameter is not specified, sources from all providers will be returned. If the specified provider does not return any sources, the response shall throw a NO_SOURCES_AVAILABLE error (see 7.4.1 Media Exists, No Sources). If the provider parameter is specified but does not match any known provider, the response shall throw a PROVIDER_NOT_FOUND error (see 7.3 Standard Error Codes). However, the platform query parameter will change the structure of the 6.2 Source Objects and 6.3 Subtitle Objects in the response, as described in their respective sections. HTTP Status: 200 OK
Required Top-Level Fields:
  • id (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. Usage: If the source object is found in the sources array, it means that the source is streamable and can be used directly in video players. If it is found in the downloads array, it means that the source is NOT streamable and should be treated as a direct download link. Clients should not attempt to use download links as streaming sources, as they may quite literally break your backend, because your backend might try to download the whole file into it’s memory before sending it to the client, which can cause out-of-memory errors and crashes. Platform: The structure of the Source Object can differ based on the platform query parameter in the request. For web, the url must be a playable streaming link (e.g., HLS, MP4) that can be used directly in HTML5 video players (i.e. without CORS or any other restrictions). For native, the url has to be the upstream URL and a new headers (object) field will be added. This allows native player implementations that can handle CORS and custom headers to access the original streaming URL from the provider, while web clients will receive a proxied/optimized URL that is accessible without additional headers or CORS restrictions in browsers. Default: web. ?platform=web Example
?platform=native&provider=provider_123 Example
?platform=native

6.2.1 Required Fields

  • id (string): Unique source identifier (e.g. UUID v4).
  • url (string): For web: A string representing the URL to the streaming source that can be used directly in HTML5 video players without CORS issues. For native: A string representing the original URL to the streaming source from the provider, which may require CORS handling or custom headers (provided in the headers field).
  • headers (object, only for native platform): Key-value pairs of HTTP (and non-standard HTTP) headers that should be included when accessing the url for native player implementations that can handle CORS and custom headers. For web platform, this field is not included, and the provided url must be accessible without additional headers or CORS restrictions without additional headers.
  • streamable (boolean): Indicates if the source is streamable (true) or a direct download link (false). If false, clients must treat the URL as a download link rather than a streaming source. Download links CANNOT be used as streaming sources. (see Range Header)
  • type (string): Source type, one of:
    • hls — HTTP Live Streaming (M3U8).
    • mp4 — MP4 file.
    • mkv — MKV file.
    • dash — MPEG-DASH (.mpd files).
  • quality (string): Video quality. One of 8K, 4K, QHD, FHD, HD, SD, or Auto: Quality should be inferred from the best available metadata, prioritizing resolution, then bitrate, filename, or manifest information. If the quality cannot be determined, use Auto. Suggested resolution mapping:
    • 4320p+ → 8K
    • 2160p–4319p → 4K
    • 1440p–2159p → QHD
    • 1080p–1439p → FHD
    • 720p–1079p → HD
    • Below 720p → SD
    • Unknown → Auto
  • audioTracks (array of strings): Human-readable language name. default/unknown —> Original
  • 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

Backends must handle missing or incomplete provider data to the best of their ability, while ensuring that the response remains valid and usable for clients.

6.2.3 Multi-Audio Handling

It is the client’s responsibility to handle multiple audio tracks. The backend should provide an audioTracks array with human-readable language names. For backends: If the language cannot be determined, use "Original".

6.3 Subtitle Object

Purpose: Represents subtitle/caption tracks. Platform: The structure of the Subtitle Object can differ based on the platform query parameter in the request. For web, the url must be a direct link to a subtitle file (e.g., VTT, SRT) that can be used directly in HTML5 track elements without CORS issues. For native, the url has to be the upstream URL and a new headers (object) field will be added. This allows native player implementations that can handle CORS and custom headers to access the original subtitle URL from the provider, while web clients will receive a proxied/optimized URL that is accessible without additional headers or CORS restrictions in browsers. Default: web. ?platform=web Example
?platform=native&provider=provider_123 Example

6.3.1 Required Fields

  • id (string): Unique subtitle identifier (e.g. UUID v4).
  • url (string): For web: A string representing the URL to the subtitle file that can be used directly in HTML5 track elements without CORS issues. For native: A string representing the original URL to the subtitle file from the provider, which may require CORS handling or custom headers (provided in the headers field).
  • headers (object, only for native platform): Key-value pairs of HTTP (and non-standard HTTP) headers that should be included when accessing the url for native player implementations that can handle CORS and custom headers. For web platform, this field is not included, and the provided url must be accessible without additional headers or CORS restrictions without additional headers.
  • label (string): Human-readable language name for the subtitle track. default/unknown —> Unknown
  • format (string): Subtitle format, one of:
    • vtt — WebVTT (preferred for web; default).
    • srt — SubRip.
  • provider (object): Information about the upstream provider.
    • id (string): Unique provider identifier.
    • name (string): Human-readable provider name.

6.3.3 Handling Unknown Subtitle Data

Backends must handle missing or incomplete subtitle data to the best of their ability, while ensuring that the response remains valid and usable for clients.

6.4 Warning/Error Objects in Success Response

Purpose: Report non-response-fatal issues encountered during scraping. If source 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).
[!NOTE] If the provider parameter is specified in the request, but the backend fails to fetch sources from that specific provider, the response will not include a warning/error object in the diagnostics array, but will instead return a NO_SOURCES_AVAILABLE error response (see 7.4.1 Media Exists, No Sources).
Fields:
  • code (string): Machine-readable warning/error code.
  • message (string): Human-readable description.
  • source (string): Identifier of the source of the issue (e.g., provider ID). If empty, applies to the whole response.
  • severity (string): One of:
    • 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:
Required Fields:
  • error.code (string): Machine-readable error code.
  • error.message (string): Human-readable error description.
  • traceId (string): Unique identifier for error tracking/debugging.
Optional Fields:
  • error.details (any): Additional context about the error. Frontends should not display this.

7.3 Standard Error Codes

[!NOTE] INVALID_TMDB_ID should be used, when the TMDB ID is valid in format but does not correspond to any media (e.g., 99999999). For IDs that are not even valid in format (e.g., abc123), INVALID_PARAMETER should be used instead.

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 for that media, the backend MUST return a 404 Not Found status with a NO_SOURCES_AVAILABLE error code. This indicates that while the media exists, the backend was unable to find any streamable sources for it (applies to a failure when fetching sources from a specific provider).

7.4.2 Invalid TMDB ID

HTTP Status: 400 Bad Request

7.4.3 TMDB ID Not Found

HTTP Status: 404 Not Found

8. 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, aswell as the id, for that specific source should be invalidated immediately.
  • For large/public backends, consider caching with a CDN and browser caching headers.

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.
For Clients:
  • Respect cache headers and ETags.
  • Prefetch sources before playback (for example at the end of a episode).
  • Use conditional requests (If-None-Match).

9. Security Considerations

9.1 HTTPS Requirement

  • Production: All endpoints MUST use HTTPS.
  • Development: HTTP is allowed for localhost only.

9.2 Input Validation

Backends MUST validate:
  1. Path parameters:
    • id: Alphanumeric, max 20 characters.
    • s: Integer, 0–99.
    • e: Integer, 1–9,999.
    • responseId: Alphanumeric with hyphens/underscores, max 128 characters.
  2. Query parameters:
    • Reject injection attempts.
  3. Headers:
    • Enforce size limits (to prevent header overflow attacks).

10. Versioning and Compatibility

10.1 Semantic Versioning

OMSS follows Semantic Versioning 1.0.0:
  • MAJOR: Breaking changes (incompatible API changes).
  • MINOR: Backward-compatible new features.
  • PATCH: Backward-compatible bug fixes/clarifications.

10.2 URL Versioning

Version is in the URL path:

10.4 Deprecation Policy

This is best effort, but especially in the beginning, this might not be followed strictly, since the spec is still evolving and breaking changes are expected. However, once the spec stabilizes, the following deprecation policy should be followed:
  1. Announce at least 6 months before removal.
  2. Headers: Deprecated endpoints return:
  3. Documentation: Migration guides are provided.
  4. Support: Deprecated features are supported for ≥ 1 major version.
  5. Removal: Only in a new major version.

10.5 Client Compatibility Expectations

Clients MUST:
  1. Ignore unknown fields in responses.
  2. Use HTTP status codes as the primary signal.
  3. Handle new error codes gracefully.
  4. Support redirect responses (3xx).
Clients SHOULD:
  1. Version lock to a specific OMSS version (/v1/).
  2. Upgrade proactively when new versions are released.
  3. Monitor deprecation headers.
  4. Implement graceful degradation for missing required fields.

11. Complete Examples

11.1 Movie Request — Web Platform (Default)

Request
Since the platform query parameter is omitted, the response uses the default web structure. All url fields are accessible without additional headers or CORS restrictions directly in browsers without requiring custom headers or proxy handling by the client. For examples when requesting a specific provider, see above in the 4.2 Movie Sources section. Response: 200 OK

11.2 TV Episode Request — Native Platform

Request
For the native platform, the backend returns upstream URLs directly and includes the required request headers for native player implementations. Response: 200 OK

11.3 Media Exists but No Sources Available

Request
The TMDB ID is valid, but the backend could not find any playable or downloadable sources. Response: 404 Not Found

11.4 Invalid TMDB ID Format

Request
TMDB IDs must contain numeric characters only. Response: 400 Bad Request

11.5 Unsupported Accept Header

Request
OMSS v1.1 supports JSON responses only. Response: 406 Not Acceptable

11.6 Refresh Endpoint — Success

Request
The backend invalidates the cached source immediately. The next request for this media will trigger a fresh scrape. Response: 200 OK

11.7 Refresh Endpoint — Unknown ID

Request
The provided response ID does not exist or has already expired. Response: 404 Not Found

11.8 Root Endpoint

Request
The root endpoint provides general information about the OMSS backend implementation and available endpoints. Response: 200 OK

11.9 Versioned Root Endpoint with Limited Media Availability

Request
This example shows a backend that exposes only a limited set of available movies and TV episodes. Response: 200 OK

12. License

This specification is licensed under the MIT License.
Last modified on July 24, 2026