| `name` | String | required | Internal provider identifier referenced by `provider://<name>` URLs. Must be unique within the provider list. |
| `urls` | List | required | Ordered failover URL list for this provider. Tuliprox rotates through these URLs within a request when failover is triggered. |
| `provider_url_selection_policy` | Enum | `resume_last_working` | Controls how a new request chooses its starting URL. `resume_last_working` starts at the last successful URL. `restart_from_first` always begins again at `urls[0]` and only fails over within that request. |
| `dns` | Object | unset | Optional DNS/IP rotation settings for the provider. See the table below. |
| `refresh_secs` | Int | `300` | The interval in seconds the background task resolves the hostnames. (Minimum effective value is 10). |
| `prefer` | Enum | `system` | Which IP protocol to prefer during DNS resolution. Options: `system`, `ipv4`, `ipv6`. |
| `max_addrs` | Int | `None` | Hard limit on the number of resolved IPs to retain per host. |
| `schemes` | List | `[http, https]` | The HTTP schemes that IP connection rotation applies to. |
| `keep_vhost` | Bool | `false` | If `true`, the `Host` header retains the original `hostname[:port]`. If `false`, it uses `IP[:port]`. Essential for reverse proxies upstream! |
| `on_connect_error` | Enum | `try_next_ip` | Policy on TCP connection failure. Options: `try_next_ip` (cycles to the next resolved IP for the same host), `rotate_provider_url` (instantly fails over to the next URL in the `urls` list). |
### 1.1 DNS Resolved IP Persistence
Resolved IPs are persisted to `{storage_dir}/provider_dns_resolved.json` (not to `source.yml`).
This file is written atomically after each DNS refresh cycle and read at startup to seed DNS caches before the
background resolver
completes its first cycle.
On config hot-reloads, DNS caches are carried over from previous provider instances so that resolved IPs are available
| `url` | String | Yes | | The Provider URL. Tuliprox supports magic scheme prefixes: `http(s)://`, `file://`, `batch://`, and **`provider://my_failover_provider`** (for the Failover System above). |
| `username` / `password` | String | Often | | Mandatory if `type` = `xtream`. |
| `enabled` | Bool | No | `true` | If `false`, this input is completely ignored in all processing. |
| `cache_duration` | String | No | `0` | **Crucial:** Determines how often Tuliprox actually downloads the raw list from the provider. At `1d` (1 day), Tuliprox serves from its local `.db` for 24 hours, even if you trigger hourly updates. This heavily protects against provider bans! Supported units are `s`, `m`, `h`, and `d`. If `cache_duration` is set, the cached provider playlist stored on disk is reused for subsequent updates instead of downloading it again. |
| `persist` | String | No | | Optional path template (e.g., `./playlist_{}.m3u`) to permanently store the downloaded raw provider list locally on your disk. The `{}` in the filename is filled with the current timestamp. For `m3u` use a full filename. For `xtream` use a prefix like `./playlist_`. |
| `method` | Enum | No | `GET` | HTTP Request method for playlist downloads (`GET` or `POST`). |
| `exp_date` | Mixed | No | | Expiration date as `"YYYY-MM-DD HH:MM:SS"` or Unix timestamp. Used for status tracking and Panel API logic. |
| `headers` | Dict | No | | Custom HTTP headers for the download (e.g., `User-Agent: My-Player`). |
| `epg` | Object | No | | Allows mapping of external XMLTV files (see [below](#input-subsections-object-keys)). |
| `aliases` | List | No | | Connection pooling / Sub-accounts (see [below](#input-subsections-object-keys)). |
| `staged` | Object | No | | Hybrid architecture feature (see [below](#input-subsections-object-keys)). |
| `panel_api` | Object | No | | Automated reseller account generation (see [below](#input-subsections-object-keys)). |
#### Input URL Schemes (`inputs[].url`)
Tuliprox utilizes a flexible URI-based system to define where input data originates.
Depending on the prefix used, the engine switches between remote downloads, local file access, or internal failover
| **`http(s)://`** | Remote Server | Standard method for downloading playlists from provider endpoints. |
| **`file://`** | Local Storage | Reads a playlist directly from the host filesystem. Useful for manual backups or pre-processed files. |
| **`provider://`** | Failover System | Resolves the URL via internal `provider` definitions. **Pro-Tip:** Use this to implement automatic rotation or failover between multiple mirrors/gateways of the same provider. New requests honor `provider_url_selection_policy`, so they can either resume from the last healthy URL or always restart from the first URL. |
| **`batch://`** | CSV File | Dedicated scheme for bulk alias management. Points to a local `;` separated CSV file (e.g., `batch://./aliases.csv`). |
| `xtream_skip_live` / `vod` / `series` | Bool | `false` | Immediately ignores entire categories during the Xtream API download. Saves massive amounts of RAM and runtime if you only want Live-TV from a specific provider, for instance. |
| `xtream_live_stream_use_prefix` | Bool | `true` | Injects the `/live/` prefix into URLs. |
| `disable_hls_streaming` | Bool | `false` | Forces Tuliprox to play Live-TV as a raw MPEG-TS (`.ts`) stream, skipping HLS (`.m3u8`) reverse-proxy handling, and forcing direct TS endpoints. |
| `resolve_tmdb` | Bool | `false` | Enables TMDB queries for this specific input based on parsed titles to fill missing posters and release years. |
| `resolve_background` | Bool | `true` | Metadata scans run asynchronously in the background so the general playlist update (which blocks clients) finishes instantly. |
| `resolve_series` / `resolve_vod` | Bool | `false` | Fetches missing details like Plot or Cast via the Provider's API (`get_vod_info` / `get_series_info`). |
| `probe_series` / `probe_vod` | Bool | `false` | Allows explicit FFprobe analysis of movies or entire TV show seasons. |
| `probe_live` | Bool | `false` | Allows FFprobe to periodically tap into Live-TV streams in the background. |
| `probe_live_interval_hours` | Int | `120` | Interval after which a Live stream is re-analyzed (Important as backup streams often change resolutions). |
| `resolve_delay` / `probe_delay` | Int | `2` | **Ban Protection:** Hard wait time (in seconds) between API or Probe requests to the *same* provider! Prevents API spamming. |
| `resolve_filter` | String | - | Filter expression to selectively resolve only entries matching the condition. Uses the same Filter syntax. |
| `probe_filter` | String | - | Filter expression to selectively probe only entries matching the condition. Uses the same Filter syntax. |
| **`url`** | String | Yes | | The XMLTV endpoint. Use **`auto`** for Xtream inputs to automatically generate the native XMLTV URL using your credentials. Supports local paths and `http(s)` links. |
| **`priority`** | Int | No | `0` | Determines the lookup order. **Lower numbers have higher priority.** For example, `-2` is processed before `0`. Use negative numbers for primary sources. |
| **`logo_override`** | Bool | No | `false` | If set to `true`, channel logos from the provider are replaced by the icons found in the XMLTV file. |
#### Smart Match Parameters (`smart_match`)
The fuzzy matching logic attempts to "guess" the EPG ID by generating search keys based on the channel name.
| **`name`** | **Crucial:** The first alias is automatically renamed with the `name` from the input definition (e.g., `my_provider_1` gets `my_provider`). This is necessary for stable playlist UUID generation and consistent channel numbering across updates. |
| **`max_connections`** | Defines allowed concurrent streams. Default in CSV is **1**. |
| **`priority`** | Lower numbers = higher priority. `0` is higher than `1`. Negative numbers (e.g., `-1`) are allowed for top-tier priority. Items with the lowest values are processed first. |
| **`exp_date`** | Account expiration. Supports "YYYY-MM-DD HH:MM:SS" (e.g., `2028-11-30 12:00:00`) or Unix timestamps (seconds). Used for auto-cleanup or Panel API sync. |
| **`alias_pool`** | Object | | Controls the lifecycle of active aliases. |
| ↳ `size.min` | Mixed | `1` | Min accounts to keep. `number` or `auto`. If `auto`, it uses the count of enabled Tuliprox users (Active/Trial, not expired) mapped to this input's targets. |
| ↳ `size.max` | Mixed | `1` | Upper bound for aliases. If `auto`, checks are triggered upon user add/update. |
| ↳ `remove_expired` | Bool | `false` | If `true`, removes expired accounts from `source.yml` or batch CSVs during boot/update. (The root input is never removed). |
| `enabled` | Bool | No | `true` | If set to `false`, Tuliprox skips building this target during normal processing. This reduces CPU, disk, and upstream workload, but the target can still be selected explicitly via CLI target execution if matched by `-t`. |
| `name` | String | No | `default` | Logical target name. If not `default`, it must be unique. Unique names are important for selective execution (`-t <target_name>`) and for clearly separating output identities in Tuliprox's processing pipeline. |
| `processing_order` | Enum | No | `frm` | Defines execution order for **F**ilter, **R**ename, and **M**ap. This directly changes which intermediate state downstream steps operate on and can therefore materially alter the final playlist result. |
| `filter` | String | Yes | | Global filter DSL expression for the target. This determines which entries survive into the final target after the selected processing order has been applied. |
| `rename` | List | No | | Regex-based transformations applied to selected fields. This is commonly used to normalize channel/group labels before sorting, mapping, or export. |
| `mapping` | List | No | | References mapping IDs from `mapping.yml` for advanced transformation logic. This is where deep structural rewriting and metadata normalization can be applied. |
| `sort` | Object | No | | Defines ordering for groups and channels after transformations. This affects the final playlist structure seen by clients and can significantly improve navigation quality in IPTV players. |
| `options` | Object | No | | Target-level behavior switches such as logo suppression, duplicate removal, and shared live-stream handling. These options influence memory usage, playlist cleanliness, and reverse-proxy behavior. |
| `output` | List | Yes | | Mandatory list of output formats. A single target can generate multiple output representations (e.g., `xtream`, `m3u`, `strm`, `hdhomerun`) from the same transformed result set. |
| `favourites` | List | No | | Duplicates final transformed channels into dedicated favorite groups after processing is complete. This adds curated views without changing the original group structure. |
| `watch` | List | No | | Defines watched group patterns. If matching groups change during updates, Tuliprox emits Messaging events so operational changes become observable automatically. |
| `use_memory_cache` | Bool | No | `false` | If enabled, the final compiled playlist is cached in RAM. This reduces disk access and improves delivery speed, especially for M3U downloads, but increases memory consumption. |
---
### 3.2.1 `processing_order`
The processing order defines how Tuliprox applies:
* **F**ilter
* **R**ename
* **M**ap
Valid values are:
*`frm` (default)
*`fmr`
*`rfm`
*`rmf`
*`mfr`
*`mrf`
> **Note:** The selected processing order can change the final result significantly.
> For example, if renaming occurs before filtering, the filter must match the renamed state rather than the original
| `field` | Enum | Yes | | Field to transform, can be `group`, `title`, `name`, `caption` or `url`. This determines which part of the playlist entry Tuliprox rewrites before later stages such as sorting or final export. |
| `pattern` | String (Regex) | Yes | | Regular expression used to match the current value of the selected field. This enables structural normalization of inconsistent source naming schemes. |
| `new_name` | String | Yes | | Replacement string. It can reference regex capture groups via `$1`, `$2`, and so on. This allows Tuliprox to preserve selected original content while reformatting labels. |
#### Rename Example
Example:
```yaml
rename:
- field:group
pattern:'^DE(.*)'
new_name:'1. DE$1'
```
In above example, every group beginning with `DE` is renamed to start with `1.`, for example:
*`DE Sports` → `1. DE Sports`
*`DE Movies` → `1. DE Movies`
This can be useful for players that ignore provider order and perform their own alphabetical sorting.
> **Note:** The effective value that `rename` sees depends on `processing_order`.
> If mapping runs before renaming, your rename pattern must match the already mapped value rather than the original
> source value.
---
### 3.2.4 `mapping`
The `mapping` block references a list of mapping identifiers (IDs) defined in your [mapping files](./mapping-dsl.md) (
| `mapping` | List of Strings | No | | Ordered list of mapping IDs to apply. Each referenced mapping can perform deep transformations on the playlist structure, metadata, grouping, or labels, making this one of the most powerful target-level processing stages in Tuliprox. |
To define a new mapping IDs see details in chapter [Mapper DSL & Logic](./mapping-dsl.md).
---
### 3.2.5 `sort`
The `sort` block defines ordering rules for groups and channels.
| `match_as_ascii` | Bool | No | `false` | If enabled, Tuliprox normalizes accented characters during sorting comparisons. This improves deterministic ordering across multilingual playlists without modifying the original visible channel names. |
| `rules` | List | Yes | | Ordered list of sort rules. Each rule is evaluated against the playlist after transformation, and directly shapes the browsing order clients see in the final target. |
| `target` | Enum | Yes | | Defines whether the rule sorts `group` or `channel` entries. This changes whether Tuliprox reorders category containers or items within those categories. |
| `field` | String | Yes | | Sort field. For `channel`: `title`, `name`, `caption`, or `url`. For `group`: `group`. This determines which final-state value Tuliprox uses for ordering. |
| `filter` | String | Yes | | Filter expression defining which entries the rule applies to. This makes it possible to sort only selected subsets of the playlist instead of the entire target uniformly. |
| `order` | Enum | Yes | | `asc`, `desc`, or `none`. `none` preserves source order for matched entries and is useful when provider order should remain untouched. |
| `sequence` | List | No | | Ordered regex list used for index-based sorting. When present, Tuliprox prioritizes regex sequence position over `order`, enabling explicit semantic ordering such as quality tiers or curated group precedence. |
> **Note:** Sort rules must be written with the configured `processing_order` in mind,
> because sorting operates on the transformed state that exists at that point in the pipeline.
#### Sort Example
```yaml
sort:
match_as_ascii:false
rules:
- target:group
order:asc
filter:'Group ~ ".*"'
field:group
sequence:
- '^Freetv'
- '^Shopping'
- '^Entertainment'
- '^Sunrise'
- target:channel
order:asc
filter:'Group ~ ".*"'
field:title
sequence:
- '(?P<c1>.*?)\bUHD\b'
- '(?P<c1>.*?)\bFHD\b'
- '(?P<c1>.*?)\bHD\b'
- '(?P<c1>.*?)\bSD\b'
```
**Named Capture Groups** in `sequence`
To sort by specific parts of a value, use named capture groups such as:
| `ignore_logo` | Bool | No | `false` | Ignores `tvg-logo` and `tvg-logo-small` attributes. This reduces downstream device-side logo caching and can keep generated M3U playlists leaner for clients with limited storage or poor cache invalidation behavior. |
| `share_live_streams` | Bool | No | `false` | Allows Tuliprox to share live stream connections in reverse proxy mode. This can reduce upstream provider connection usage when multiple clients watch the same channel, but it increases memory usage per shared channel. |
| `remove_duplicates` | Bool | No | `false` | Attempts to remove duplicate entries by `url`. This improves playlist cleanliness and reduces confusing duplicates in the client-facing output. |
| `force_redirect` | Bool | No | `false` | Optional redirect-related behavior switch. This influences how Tuliprox serves final stream delivery where redirect-style output handling is required by the deployment model. |
> **⚠️ Warning:** When `share_live_streams` is enabled, each shared channel consumes at least **12 MB** of memory,
> regardless of the number of connected clients.
> If the reverse-proxy buffer size is increased above `1024`, memory usage increases accordingly.
> Example: with a buffer size of `2048`, each shared channel consumes at least **24 MB**.
---
### 3.2.7 Output Formats (`output`)
A target can be exported to multiple formats simultaneously. The target-level filter, rename, mapping, and sort
logic are applied first, and each output then formats the result differently.
> **Note:** Output-specific filters are applied **after all transformations have completed**.
> Therefore, any filter inside an individual output block must refer to the **final playlist state**.
| `type` | Enum | Yes | | Output format type. Supported values include `xtream`, `m3u`, `strm`, and `hdhomerun`. This determines how Tuliprox serializes and serves the final playlist to downstream consumers. |
| `filter` | String | No | | Optional output-level filter applied after all target transformations. This allows Tuliprox to derive specialized output subsets from the same target without duplicating upstream processing logic. |
**Specific Output Properties** are defined for each type:
| `type` | Enum | Yes | | Must be `xtream`. Generates an Xtream-compatible API output backed by Tuliprox's processed data model. |
| `skip_live_direct_source` | Bool | No | `true` | If `true`, Tuliprox ignores provider `direct_source` values for live content. This keeps playback under Tuliprox's delivery logic and avoids client behavior differences caused by bypass URLs. |
| `skip_video_direct_source` | Bool | No | `true` | If `true`, Tuliprox ignores provider `direct_source` values for movies/VOD. This improves consistency across clients that otherwise may bypass Tuliprox for video playback. |
| `skip_series_direct_source` | Bool | No | `true` | If `true`, Tuliprox ignores provider `direct_source` values for series entries. This ensures Tuliprox stays in control of series playback URL generation and proxy behavior. |
| `update_strategy` | Enum | No | `instant` | `instant` writes changes immediately, while `bundled` batches write operations. This directly trades off freshness versus disk I/O load during background metadata enrichment and output maintenance. |
| `trakt` | Object | No | | Trakt.tv integration block. Tuliprox can fetch Trakt lists, fuzzy-match them against playlist entries, and inject matched VOD or series entries into generated virtual categories. |
| `filter` | String | No | | Optional output-level filter for the Xtream export only. Useful when the same target should expose different subsets to different output formats. |
> **Note:** IPTV players vary in how they resolve streams: some use the direct-source attribute, while others
> reconstruct URLs
> from server metadata. To ensure Tuliprox maintains control over the stream routing (Proxy/Redirect),
> the Direct Source Handling (skip_*_direct_source) attributes default to true.
>
> **⚠️ Warning:** Setting `skip_*_direct_source` to `false` forces the player to use the provider's original
`direct-source` URL.
> This effectively **bypasses Tuliprox**, which will disable internal features like connection tracking,
> IP masking, and failover logic for those streams.
#### `trakt` Object in Xtream Output
Trakt.tv is an online platform for tracking, organizing, and discovering movies and TV shows.
Tuliprox can query Trakt lists and match playlist entries using Jaro-Winkler-style fuzzy matching.
Matching entries are then added to new virtual categories inside the Xtream output.
| `api.api_key` | String | Yes | | Trakt API key used for authenticated access. Without a valid key, Tuliprox cannot fetch remote list content. |
| `api.version` | String | No | `"2"` | API version header value. This ensures Tuliprox formats requests against the correct Trakt API version. |
| `api.url` | String | No | `https://api.trakt.tv` | Base API URL for Trakt requests. This defines the remote endpoint Tuliprox queries for list data. |
| `api.user_agent` | String | No | | Optional `User-Agent` used for Trakt API requests. This can help satisfy API gateway expectations or deployment-specific request policies. |
| `lists[].user` | String | Yes | | Trakt username owning the list. This identifies which account namespace Tuliprox fetches list data from. |
| `lists[].list_slug` | String | Yes | | Trakt list slug. Combined with `user`, this uniquely identifies the remote list to load. |
| `lists[].category_name` | String | Yes | | Name of the generated virtual category inside Tuliprox's Xtream output. This controls where matched entries appear to clients. |
| `lists[].content_type` | Enum | Yes | | `vod` or `series`. This determines which class of playlist entries Tuliprox will attempt to match and inject into the generated category. |
| `lists[].fuzzy_match_threshold` | Integer | No | | Fuzzy matching threshold for title matching. Higher values reduce false positives but may miss loosely matching items. |
| `type` | Enum | Yes | | Must be `m3u`. Generates a traditional playlist file suitable for IPTV players and related clients. |
| `filename` | String | No | | Optional custom output filename. This affects how Tuliprox writes or exposes the generated playlist artifact. |
| `include_type_in_url` | Bool | No | `false` | If enabled, Tuliprox adds the stream type (`live`, `movie`, `series`) into generated stream URLs. This can improve downstream routing clarity and compatibility with clients that distinguish path structure by media type. |
| `mask_redirect_url` | Bool | No | `false` | If enabled, Tuliprox uses URLs from `api-proxy.yml` for users operating in `redirect` proxy mode. This is important for multi-provider failover or cycling setups where exposing the provider URL directly would bypass Tuliprox's routing logic too early. |
| `filter` | String | No | | Optional M3U-only post-transformation filter. This allows M3U consumers to receive a narrower subset than other output formats derived from the same target. |
> **Note:** `mask_redirect_url` should be enabled if you use multiple providers and want Tuliprox to preserve
> redirect-mode
> routing and cycling behavior without exposing the direct upstream endpoint in the initial playlist URL.
| `type` | Enum | Yes | | Must be `strm`. Generates filesystem-based `.strm` references instead of a network playlist format. |
| `directory` | String | Yes | | Target directory where `.strm` files are written. This is the root Tuliprox manages for exported media stubs and must be chosen carefully to avoid overlap with real media directories. |
| `username` | String | No | | Optional username context used when generating stream references. This affects which user-specific URL or access context Tuliprox embeds into the exported `.strm` files. |
| `underscore_whitespace` | Bool | No | `false` | Replaces whitespace with `_` in paths and filenames. This improves compatibility with environments or scrapers that prefer filesystem-safe, normalized naming. |
| `cleanup` | Bool | No | `false` | If enabled, Tuliprox removes orphaned output files from the STRM directory. This keeps the export directory synchronized with the target, but can delete files if the directory points to an existing media folder. |
| `style` | Enum | Yes | | Naming convention for the output structure. Supported values: `kodi`, `plex`, `emby`, `jellyfin`. This affects scraper compatibility and how downstream media servers identify titles. |
| `flat` | Bool | No | `false` | If enabled, Tuliprox creates a flatter directory structure. This changes how categories and group information are represented on disk and can simplify some media-server imports. |
| `strm_props` | List | No | | Stream property lines inserted into `.strm` files, mainly for Kodi player behavior. This allows low-level playback hints to be embedded directly into generated files. |
| `add_quality_to_filename` | Bool | No | `false` | Appends detected media quality tags such as `[1080p 4K HEVC HDR]` to the filename. This improves visibility in library UIs but depends on prior probing/enrichment data being available. |
| `filter` | String | No | | Optional STRM-only output filter. Useful when only a subset of the target should be materialized as filesystem entries. |
| `type` | Enum | Yes | | Must be `hdhomerun`. Exposes the target through Tuliprox's HDHomeRun emulation layer for tuner-style discovery by clients such as Plex or Jellyfin. |
| `device` | String | Yes | | Must match a device name defined in `config.yml`. This links the playlist target to a specific emulated tuner endpoint. |
| `username` | String | Yes | | Must match a user from `api-proxy.yml`. This determines which account context, access restrictions, and connection limits apply when clients consume the lineup through the tuner interface. |
| `use_output` | Enum | No | | Selects whether the HDHomeRun stream URLs are based on `m3u` or `xtream` output behavior. This affects how playback URLs are generated and which delivery semantics back the tuner lineup. |
| `cluster` | String | No | | Optional logical cluster, for example `series`. This influences how Tuliprox groups the duplicated entries internally for output generation. |
| `group` | String | Yes | | Name of the favorite group created in the final playlist. This adds a curated access path without removing the original group membership. |
| `filter` | String | Yes | | Filter expression selecting which final entries should be duplicated into the favorites group. This operates on the transformed end state rather than the original raw input. |
| `match_as_ascii` | Bool | No | `false` | If enabled, Tuliprox normalizes accented characters during matching. This improves filter matching robustness across multilingual names while preserving the original visible title in output. |
---
### 3.2.9 Watch (`watch`)
For each target with a *unique name*, you can define watched groups.
It is a list of group patterns Tuliprox monitors for content changes during updates.
If matching groups gain or lose channels, Tuliprox emits a Messaging event such as:
| `group` | String (Regex) | Yes | | Regex pattern matched against final group names. This allows Tuliprox to detect meaningful content changes in selected areas of the playlist and notify operators automatically through the configured messaging backends. |