---
title: "Create or update template"
method: POST
path: "/templates/{code}"
tags: ["templates"]
---

# Create or update template

`POST /templates/{code}`

## Path parameters

- `code` string, required

## Request body

- DomainTemplate
  - `code` string — Code is the unique key chosen by the operator.
  - `description` string
  - `dvr` DomainStreamDVRConfig
    - `enabled` boolean
    - `max_size_gb` number — MaxSizeGB caps total disk usage. Oldest segments pruned when exceeded. 0 = no limit.
    - `profiles` string — Profiles selects which renditions the CMAF blob archive records: "" or "best" = the best rendition only (default); "all" = every rendition in the ABR ladder.
    - `retention_sec` integer — RetentionSec is the retention window in seconds. 0 = keep forever.
    - `segment_duration` integer — SegmentDuration overrides the global segment length in seconds. 0 = use default (4s).
    - `storage_path` string — StoragePath overrides the default DVR root directory for this stream. "" = use "./dvr/{streamCode}".
  - `inputs` DomainInput[] — Inputs are inherited by streams that leave Inputs empty. A template carrying a publish:// input is also the trigger that makes Prefixes matching produce a runtime stream — without an input source there is nothing for the runtime stream to subscribe to.
    - `headers` object — Headers are arbitrary HTTP headers sent with every request for HTTP/HLS inputs. Common uses: "Authorization": "Bearer <token>" "Authorization": "Basic <base64(user:pass)>" "X-Custom-Token": "secret"
    - `net` DomainInputNetConfig
      - `insecure_tls` boolean — InsecureTLS disables TLS certificate verification for HTTPS pulls (HLS playlist + segment GETs). Default false — leave secure-by-default for production. Use only when the source uses a self-signed, expired, or otherwise-invalid certificate that you trust at the network level (private VLAN, fixed IP allowlist).
      - `timeout_sec` integer — TimeoutSec is the per-protocol operation budget the reader applies when this input is opened. Semantics differ by protocol: - HLS: HTTP request timeout (entire round-trip incl. body) for the playlist GET. Segment GETs derive from this — typically 4× the playlist budget, floored at the segment default. - RTMP: TCP dial timeout (handshake budget). - RTSP: dial + initial read timeout (until first packet). - SRT: connection / handshake timeout. Zero uses the reader's per-protocol default (DefaultHLSPlaylistTimeoutSec for HLS; DefaultRTMPTimeoutSec / DefaultRTSPTimeoutSec for the rest).
    - `params` object — Params are extra URL query parameters merged into the source URL before connecting. Used for protocols that carry credentials or options in the query string (SRT ?passphrase=, S3 ?access_key= / ?secret_key=, etc.). "passphrase": "my-srt-passphrase" "access_key": "AKID..." (S3) "secret_key": "wJal..." (S3)
    - `pids` integer[] — Pids is an explicit allowlist of TS PIDs to keep — every other PID is dropped at ingest. Used when the source PSI is unreliable (legacy encoders with malformed PAT/PMT) or when the operator wants to cherry- pick a subset (e.g. drop a teletext PID, keep only one of N audio languages). The filter is purely PID-level: no PAT/PMT rewrite, no CRC recompute. Operators must include every PID needed for playback (typically PID 0 for PAT, the PMT PID, and the desired ES PIDs). Layers with Program when both are set: Program runs first (auto- detect ES PIDs + rewrite PAT to single-program), then Pids further restricts the output. Empty (default) disables the filter. Currently applies to UDP only — same rationale as Program.
    - `priority` integer — Priority determines failover order. Lower value = higher priority. The Stream Manager always prefers the lowest-priority alive input.
    - `program` integer — Program selects a single MPEG-TS program when the source is a multi-program transport stream (MPTS) — common in DVB headend feeds where one multicast carries many channels. When > 0, the ingest pipeline rewrites the PAT to advertise only the chosen program and drops PMT / ES packets belonging to other programs, producing a clean SPTS for downstream HLS / DASH / push consumers. Zero (default) disables filtering — the entire stream is forwarded unchanged. Currently applies to UDP only; HLS / SRT / File ingest are SPTS by convention so the filter is not wired for those (extend reader.go if a real MPTS file/SRT use case arises). Ignored for RTSP / RTMP, which are single-program by protocol design.
    - `url` string — URL is the source endpoint. See the package doc for supported formats.
  - `name` string — Name and Description are template-level metadata. Name surfaces in the API for human-readable lists; Description carries the rationale behind the template's settings. Streams inheriting this template keep their own Name / Description fields — the template metadata is for operator-facing tooling, not for downstream consumers.
  - `playback_policy` string — PlaybackPolicy is the media-auth Policy code inherited by streams referencing this template (see domain.Policy). Empty = no policy (inheriting streams stay public unless they set their own).
  - `prefixes` string[] — Prefixes is the list of URL-path prefixes that trigger auto-publish. When an encoder pushes to a path whose first segment(s) match any prefix here AND this template has at least one publish:// input, a runtime stream is created on the fly. Prefixes must not overlap any other template's prefix (validated at save time).
  - `protocols` DomainOutputProtocols
    - `dash` boolean — DASH enables MPEG-DASH packaging over HTTP. Required for Widevine/PlayReady DRM.
    - `hls` boolean — HLS enables Apple HTTP Live Streaming (m3u8 + segments over HTTP). Compatible with browsers, iOS, Android, Smart TVs.
    - `mpegts` boolean — MPEGTS exposes raw MPEG-TS over chunked HTTP at /<code>/mpegts — the lowest-latency relay path between Open-Streamer instances (and any HTTP client that can consume chunked TS, e.g. ffmpeg / VLC). Latency is bounded only by network RTT and one buffer-hub chunk (typically 50–200 ms vs 4–10 s for HLS / DASH). No goroutine is started per-stream; the endpoint subscribes to the playback buffer on demand. Disabling the flag turns the endpoint into a 404 for that stream so operators can opt out per-stream without changing the global router.
    - `rtmp` boolean — RTMP opens an RTMP publish endpoint for legacy players/CDNs.
    - `rtsp` boolean — RTSP opens an RTSP listener for pull clients (VLC, broadcast tools).
    - `srt` boolean — SRT opens an SRT listener port for contribution-quality pull.
  - `push` DomainPushDestination[] — Push is the list of external destinations the server actively pushes to.
    - `comment` string — Comment is a human-readable note for this destination.
    - `enabled` boolean — Enabled controls whether this destination is active.
    - `limit` integer — Limit is the maximum number of retry attempts. 0 = unlimited.
    - `retry_timeout_sec` integer — RetryTimeoutSec is the delay between retry attempts in seconds.
    - `status` 'idle' | 'connecting' | 'active' | 'retrying' | 'failed' | 'disabled'
    - `timeout_sec` integer — TimeoutSec is the connection/write timeout in seconds.
    - `url` string — URL is the destination ingest endpoint. Supported schemes: rtmp:// — plain TCP, default port 1935 (e.g. rtmp://rtmp.example.com/live2/{key}) rtmps:// — TLS-wrapped RTMP, default port 443 (e.g. rtmps://rtmps.example.com:443/rtmp/{key})
  - `stream_key` string — StreamKey is the shared push-authentication secret for streams that inherit this template. Empty means no secret is templated and each stream may set its own (or none).
  - `tags` string[] — Tags propagate to inheriting streams when the stream leaves Tags empty. Useful for grouping every stream that follows a common profile under one operational label.
  - `thumbnail` DomainThumbnailConfig
    - `enabled` boolean
    - `height` integer
    - `interval_sec` integer — IntervalSec generates one thumbnail every N seconds.
    - `output_dir` string — OutputDir is relative to the publisher HLS directory. E.g. "thumbnails" → written to {hls_dir}/{stream_code}/thumbnails/thumb.jpg
    - `quality` integer — Quality is the JPEG quality (1–31, lower = better). Default: 5.
    - `width` integer — Width and Height of the output thumbnail in pixels. 0 = match source resolution.
  - `transcoder` DomainTranscoderConfig
    - `audio` DomainAudioTranscodeConfig
      - `bitrate` integer — Bitrate is the audio bitrate in kbps.
      - `channels` integer — Channels: 1 = mono, 2 = stereo, 6 = 5.1.
      - `codec` 'aac' | 'mp2a' | 'mp3' | 'ac3' | 'eac3' | 'copy'
      - `copy` boolean — Copy copies origin audio without re-encoding.
      - `language` string — Language is ISO 639-1 code, e.g. "en", "vi".
      - `normalize` boolean — Normalize applies EBU R128 loudness normalization.
      - `sample_rate` integer — SampleRate is output sample rate in Hz.
      - `volume` string — Volume sets the output audio gain on the re-encode path (Copy=false; passthrough audio cannot be gained). The value is either a plain linear multiplier ("2", "0.5" → output = value × input) or a decibel string ("+9dB", "-6dB" → output level = input ± dB). Both reduce to one linear factor via ParseAudioVolume. Empty / "1" / "0dB" = unity (no change). Boosting can clip; samples are clamped to full scale.
    - `decoder` DomainDecoderConfig
      - `name` string — Name is the FFmpeg decoder name. "" = let FFmpeg choose automatically. Examples: "h264_cuvid", "h264_qsv".
    - `global` DomainTranscoderGlobalConfig
      - `deviceid` integer — DeviceID selects hardware device index.
      - `fps` integer — FPS sets output framerate. 0 = source/default.
      - `gop` integer — GOP sets keyframe interval in frames. 0 = encoder default.
      - `hw` 'none' | 'nvenc' | 'vaapi' | 'videotoolbox' | 'qsv'
    - `video` DomainVideoTranscodeConfig
      - `copy` boolean — Copy copies origin video without re-encoding.
      - `interlace` 'auto' | 'tff' | 'bff' | 'progressive'
      - `profiles` DomainVideoProfile[] — Profiles defines ABR renditions when re-encoding.
        - `bframes` integer — Bframes is the number of consecutive B-frames the encoder may emit. nil = encoder default; 0 = explicit none (low-latency live); 2-3 = typical VOD; NVENC HW B-ref pyramid is auto-enabled when >0.
        - `bitrate` integer — Bitrate is the target video bitrate in kbps. 0 = encoder auto.
        - `codec` 'h264' | 'h265' | 'av1' | 'mp2v' | 'copy'
        - `framerate` number — Framerate is the output frame rate (fps). 0 = match source.
        - `height` integer
        - `keyframe_interval` integer — KeyframeInterval is the GOP size in seconds. Must match or be a multiple of the HLS/DASH segment duration.
        - `level` string — Level controls the H.264/H.265 encoding level. Common: "3.1", "4.0", "4.1", "4.2", "5.0", "5.1"
        - `max_bitrate` integer — MaxBitrate caps the peak bitrate in kbps (CBR/VBR ceiling). 0 = no cap.
        - `preset` string — Preset controls the encoder speed/quality tradeoff. libx264: "ultrafast" | "superfast" | "veryfast" | "faster" | "fast" | "medium" | "slow" | "veryslow" NVENC: "p1" (fastest) .. "p7" (highest quality)
        - `profile` string — Profile controls the H.264/H.265 encoding profile. "baseline" | "main" | "high" (H.264); "main" | "main10" (H.265)
        - `refs` integer — Refs is the number of reference frames. nil = encoder default. Higher = better compression at cost of CPU/latency. NVENC has its own caps.
        - `resize_mode` 'pad' | 'crop' | 'stretch' | 'fit'
        - `sar` string — SAR is the output Sample Aspect Ratio, "N:M". "" = inherit from source. Use "1:1" for square pixels (web); "16:11", "59:54" etc. for anamorphic.
        - `width` integer — Width and Height define the output resolution. Set to 0 to keep the source dimensions (Width=0 & Height=0 = no scaling).
  - `watermark` DomainWatermarkConfig
    - `enabled` boolean
    - `filename` string — Filename references a WatermarkAsset by its on-disk name in the /watermarks library (eg. `vtv1_logo.png`). Required when Type == WatermarkTypeImage. The coordinator resolves this into ImagePath (private field) before passing the config to the transcoder.
    - `font_color` string — FontColor in FFmpeg color syntax. E.g. "white", "#FFFFFF", "white@0.8".
    - `font_file` string — FontFile is the path to a .ttf/.otf font file. "" = FFmpeg default font.
    - `font_size` integer — FontSize in pixels. Default: 24.
    - `offset_x` integer — OffsetX and OffsetY are pixel offsets from the chosen position edge. Ignored when Position == custom.
    - `offset_y` integer
    - `opacity` number — Opacity controls transparency: 0.0 = fully transparent, 1.0 = fully opaque.
    - `position` 'top_left' | 'top_right' | 'bottom_left' | 'bottom_right' | 'center' | 'custom' | 'bottom_right'
    - `resize` boolean — Resize, when true, makes the watermark render at a consistent on-screen ratio across every rendition in an ABR ladder. The largest profile renders the asset at its NATIVE pixel size (operators design at the top rendition); smaller profiles shrink the asset by the ratio of their width to the largest profile's width. Pixel-scale fields (FontSize for text, OffsetX/OffsetY for both) shrink with the same factor so corner padding and glyph height stay visually proportional. When false (default), the watermark uses native pixel dimensions and fixed offsets on every profile — appearing larger on lower-resolution renditions because they cover fewer pixels of frame.
    - `text` string — Text is the string to render. Supports strftime directives for live timestamps. E.g. "LIVE %{localtime:%H:%M:%S}"
    - `type` 'text' | 'image'
    - `x` string — X / Y are raw FFmpeg coordinate expressions used only when Position == custom. Empty string defaults to "0". The exact variables exposed depend on the filter: - drawtext (text watermark): w/h = frame size, tw/th = text size - overlay (image watermark): W/H = main video size, w/h = overlay size
    - `y` string

## Response `200`

OK

- object

## Other responses

- `201` — Created
- `400` — Bad Request
- `500` — Internal Server Error

---

[API](https://skmtc.net/datvietvac-techhub/apis/open-streamer-api.md) · [All operations](https://skmtc.net/datvietvac-techhub/apis/open-streamer-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/datvietvac-techhub/open-streamer-api/revisions/9f723293b698/schema)
