Updated October 2026: SCTE 35 is now split into ANSI/SCTE 35-1 and the new event-based SCTE 35-2 (May 2026); new sections on analog cue tones, SCTE-35 vs SCTE-104 vs SCTE 224, HLS Interstitials and how to decode a cue.

The short answer: SCTE-35 is the digital cue tone of streaming: a small binary message, defined by the Society of Cable Telecommunications Engineers, that sits inside a video stream and tells every downstream system that an ad break (or another program boundary) starts at an exact timestamp and lasts a set number of seconds. The encoder writes it, usually on request from playout automation over SCTE-104; the packager carries it into HLS and DASH manifests; the ad-insertion server reads it and stitches in the ad. The current text is ANSI/SCTE 35-1 2023r2, and SCTE 35-2 (2026) adds a simpler event-based form.

Why this matters

If you run, or are about to build, an ad-supported streaming service, SCTE-35 is the difference between an ad break that lands cleanly and one that does not happen at all. It is the signal that connects your content to your money: the server-side ad insertion you rely on cannot insert an ad until something in the stream tells it where the break is, how long it runs, and what kind of break it is. US connected-TV ad spend is projected at $29.3 billion in 2026, up 11%, inside a US digital video ad market above $80 billion (IAB, 2026 Digital Video Ad Spend & Strategy Report), and the live, linear, and FAST channels driving that growth are built on this one broadcast standard. This article is the builder's guide to the marker itself — what it is, where it is born, what it carries, and how it reaches the player — and the companion to the OTT monetization map, which shows where ad revenue sits among all the ways a platform earns.

The one job: how a stream says "an ad goes here"

Start with the problem SCTE-35 exists to solve. A streaming platform wants to replace or insert advertising at exact moments in a program — between innings, at a chapter break, returning from a national feed to a local one. But the video itself is just a sequence of pictures and sound; it carries no built-in notion of "this is where the commercial goes." Something has to mark the spot, precisely, in a way every downstream machine can read identically.

That marker is SCTE-35 — a signaling standard from the Society of Cable Telecommunications Engineers (SCTE), formally titled Digital Program Insertion Cueing Message, first published in 2001. The 2023r1 edition of 30 November 2023 was renumbered as ANSI/SCTE 35-1 2023r2, now titled Part 1: Legacy Splice-Based and Time-Based Signaling, and in May 2026 SCTE released a companion, SCTE 35-2 Event-Based Signaling (SCTE standards updates, 2026). Section and table numbers quoted in this article come from the 2023r1 text. A SCTE-35 message is a tiny data packet, interleaved with the audio and video, that announces an upcoming splice point: where it is on the timeline, whether the stream is leaving the program or returning to it, and — increasingly — what kind of boundary it is.

Here is the analogy to hold onto. A SCTE-35 cue is the chalk mark a film editor used to scratch onto a reel to say "cut here, drop the commercial in." The film does not know what a commercial is; the chalk mark does the telling, and any editor in any cutting room reads it the same way. SCTE-35 is that chalk mark, except it is a precise digital timestamp that machines — encoders, packagers, ad servers, and stitchers — read automatically and act on without a human in the room. Everything else in this article is detail about how the chalk mark is written, carried, and read.

One thing the cue does not do is contain the ad. SCTE-35 only marks the opportunity; the standard "defines an in-stream messaging mechanism to signal splicing and insertion opportunities" and deliberately says nothing about what gets inserted (ANSI/SCTE 35 2023r1, §1.2). Choosing and delivering the actual ad is a separate job, handled by the ad decision server and the stitcher we meet later.

A six-step chain read from the top down, with the standard that carries each handoff named beside the arrow. Automation and playout knows the schedule and calls the break, and issues a SCTE-104 request. The encoder writes the SCTE-35 cue into the stream, which travels on as a SCTE-35 message. The transport stream carries the cue on its own PID, listed in the PMT. The packager copies the cue into the manifests, where it becomes a cue in the playlist. The HLS and DASH manifests hold it as EXT-X-DATERANGE and an MPD EventStream, and a VAST call goes out. The ad server and stitcher pick the ad and rewrite the manifest. A closing line: one source stream, markers in the manifest, an ad on screen. Figure 1. The signaling chain. An automation system requests a cue over SCTE-104; the encoder writes a SCTE-35 message into the stream; the packager copies it into HLS and DASH manifests; the ad decision server and stitcher turn it into a real ad.

From analog cue tones to SCTE-35

SCTE-35 cue tones is the name engineers still use for SCTE-35 markers, because SCTE-35 replaced the analog cue tone. In analog cable, a network signalled a local ad break with an audible or sub-audible tone burst; the SCTE-35 standard itself defines a cue tone as "a signal that is usually either a sequence of DTMF tones or a contact closure" (ANSI/SCTE 35 2023r1, definitions). The headend's insertion gear heard the tone and rolled the local commercial. In digital TV the tone became a data message: the SCTE-35 cue, often called a "digital cue tone".

The heritage is still in the standard. SCTE-35 defines a DTMF_descriptor (descriptor tag 0x01) that carries the DTMF characters and a pre-roll value, so a receiver can regenerate the legacy tone sequence for older equipment downstream. When someone asks for an "SCTE trigger", they almost always mean the same thing in modern terms: a SCTE-35 cue in the stream, or the SCTE-104 request that tells the encoder to write one.

Where the marker is born: SCTE-104 to SCTE-35

The cue does not appear by magic. In a live or linear channel it usually begins life one step upstream, in the automation system — the playout software that runs the channel and knows the schedule. When the schedule reaches an ad break, the automation system sends a request to the encoder asking it to mark a break. That request travels over a companion standard called SCTE-104, which is the messaging interface between an automation system and the compression/encoding equipment.

The division of labour is clean and worth remembering. SCTE-104 is the request — "insert a break here," issued by automation and timed against the broadcast clock (aligned to UTC time, vertical-interval timecode, or a hardware trigger). SCTE-35 is the fulfillment — the encoder receives the SCTE-104 request and writes a SCTE-35 message into the outgoing stream at the right instant, carrying everything a downstream system needs. One is the instruction handed to the encoder; the other is the durable mark the encoder leaves in the stream for everyone after it.

Not every cue starts as SCTE-104. A platform can insert SCTE-35 directly at the packaging stage for video-on-demand assets, or generate cues from an out-of-band schedule (more on that with SCTE 224 below). But the SCTE-104 → SCTE-35 handoff is the canonical live path, and knowing it explains why a missing or mistimed ad break is so often an upstream problem — a fault in the automation request or its timing, not in the player at all.

Anatomy of a SCTE-35 message

A SCTE-35 message is technically a small table called the splice_info_section. You will never write one by hand, but understanding its shape demystifies every ad-signaling problem you will ever debug. Think of it as an envelope with a few labelled fields and one main instruction inside.

The envelope opens with a fixed identifier, table_id, whose value is always 0xFC (ANSI/SCTE 35 2023r1, §9.6.1) — which is why engineers sometimes call SCTE-35 "the 0xFC table." Then come a handful of housekeeping fields: a protocol_version (currently always 0), a 33-bit pts_adjustment used to keep the cue's timing correct if the stream is re-timestamped along the way, and a 12-bit tier value used to route or filter cues. After the housekeeping sits the important part: a splice_command_type that names which instruction this message carries, followed by the command itself, then an optional list of descriptors that add richer meaning, and finally a CRC_32 checksum so a receiver can confirm the message arrived intact.

The standard defines six command types, but only a few matter in practice (ANSI/SCTE 35 2023r1, Table 7):

Hex Command Role today
0x00 splice_null A heartbeat / keep-alive; carries no splice.
0x04 splice_schedule Schedules future splices in advance; rarely used in streaming.
0x05 splice_insert The classic "cue out / cue in" ad-break command.
0x06 time_signal A timestamped point that gains meaning from its descriptors.
0x07 bandwidth_reservation Reserves bandwidth; used in some satellite paths.
0xFF private_command Vendor-defined, non-standard payloads.

Table 1. The SCTE-35 command types. In modern streaming you will almost always be working with splice_insert (0x05) and time_signal (0x06); the rest are legacy or niche.

The two that carry ad breaks — splice_insert and time_signal — deserve their own section, because the difference between them is the single most useful thing to understand about SCTE-35.

An envelope headed splice_info_section holding six fields stacked top to bottom: table_id, always 0xFC; pts_adjustment, 33 bits; tier, 12 bits; splice_command_type, which instruction; descriptor loop, optional; and CRC_32, the checksum. A brace on the right groups the first three as housekeeping fields. Two further call-outs name splice_command_type as the instruction, splice_insert or time_signal, and the descriptor loop as what kind of break, the segmentation_descriptor. A closing line: the command says when; the descriptors say what kind of break it is. Figure 2. Inside the envelope. A splice_info_section carries housekeeping fields, one splice command (splice_insert or time_signal), an optional loop of descriptors that label the break, and a CRC checksum.

The two commands that matter: splice_insert vs time_signal

The older, simpler command is splice_insert. It directly describes an ad break with its own fields. The key one is a single bit called out_of_network_indicator: when it is set to 1, the cue marks an out point — the moment to leave the program and go to an ad (the "cue-out"); when it is 0, the cue marks the in point — the moment to return to the program (the "cue-in") (ANSI/SCTE 35 2023r1, §9.7.3.1). A splice_insert can also carry a break_duration (how long the avail lasts) and a unique_program_id to tie a cue-out and its matching cue-in together. For a plain "leave for 90 seconds of ads, then come back," splice_insert says everything needed.

The newer, richer command is time_signal. On its own, a time_signal carries only a timestamp — a precise point on the timeline and nothing more. Its meaning comes entirely from the descriptors attached to it. The standard is explicit: when a time_signal is used to signal splice events, it "shall carry one or more segmentation descriptors" with the additional information about what to do (ANSI/SCTE 35 2023r1, §9.3). That sounds like a weakness but it is the opposite — it is what lets time_signal express things splice_insert cannot, like "this is the start of a provider placement opportunity for a specific program identified by this ID," or "this is a chapter boundary, not an ad."

The practical guidance the whole industry has converged on: splice_insert is legacy but still widely used for simple breaks; time_signal plus a segmentation descriptor is the modern default because it carries identity and intent, which targeted and audience-specific advertising depends on. A production platform reads both, because real upstream feeds send both.

Two panels of identical size side by side. The left panel, splice_insert, says the break is in its own fields and lists four of them: out_of_network_indicator, where 1 means leave the program and 0 means return; break_duration, how long the avail lasts; unique_program_id, which ties the cue-out to its cue-in; and avail_num / avails_expected, which slot in the break. The right panel, time_signal, says it carries only a timestamp plus descriptors: pts_time, a point on the 90 kHz clock, with an arrow down into a segmentation_descriptor block holding segmentation_type_id, UPID (Ad-ID, EIDR, URI) and restriction flags for web delivery and blackout. A closing line: splice_insert is self-contained; time_signal needs a descriptor for meaning. Figure 3. Two ways to mark a break. splice_insert describes the break in its own fields; time_signal carries only a timestamp and leans on a segmentation descriptor for identity and intent.

Segmentation descriptors: labelling what kind of break it is

A segmentation descriptor is the add-on that turns a bare timestamp into a meaningful event. It is the part of SCTE-35 that says what this boundary is, not just when. It carries three things worth knowing about.

First, a segmentation_type_id — a number that names the kind of boundary. This is where "an ad goes here" gets specific. The ad-relevant values are the ones a streaming team lives with; here are the ones that matter, with a column showing which command can carry each (the support matrix matches how production encoders such as Bitmovin's treat them):

Type ID Segmentation type Carried by splice_insert? Carried by time_signal?
0x10 / 0x11 Program Start / End Yes No
0x20 / 0x21 Chapter Start / End Yes No
0x22 / 0x23 Break Start / End Yes Yes
0x30 / 0x31 Provider Advertisement Start / End Yes Yes
0x32 / 0x33 Distributor Advertisement Start / End Yes Yes
0x34 / 0x35 Provider Placement Opportunity Start / End Yes Yes
0x36 / 0x37 Distributor Placement Opportunity Start / End Yes Yes
0x40 / 0x41 Unscheduled Event Start / End Yes No

Table 2. The ad-relevant segmentation type IDs (ANSI/SCTE 35 2023r1, Table 23). "Placement Opportunity" (0x34–0x37) is the type most ad decision systems treat as a replaceable ad avail; "Provider" vs "Distributor" says who owns the inventory. The right two columns show which command each type is conventionally carried by — the placement-opportunity and advertisement types travel happily on time_signal, which is why modern targeted advertising uses it.

The single most important distinction in that table is "placement opportunity" versus "advertisement." A placement opportunity (0x34–0x37) is a slot the platform is invited to fill with its own dynamically chosen ad — this is what dynamic ad insertion targets. A plain advertisement marker (0x30–0x33) describes an ad that is already in the feed. And "provider" versus "distributor" answers who owns that inventory: the content provider (the network) or the distributor (you, the platform carrying it).

Second, a segmentation descriptor carries a UPID — a unique program identifier — which says exactly which piece of content or which break this is. The UPID has a type, and the type tells a receiver how to read the bytes. Common UPID types include Ad-ID (0x03, the advertising industry's standard ad identifier), TMS/TID (0x08), EIDR (0x0A, a registry ID for movies and TV), a generic URI (0x0F), and a UUID (0x10). The UPID is how an ad decision server matches a break to a campaign, a blackout rule, or a reporting bucket.

Third, it carries restriction flags — most notably a web_delivery_allowed_flag and a no_regional_blackout_flag — that encode whether this content may be delivered to web/OTT audiences or must be blacked out in certain regions. These are how sports and syndicated rights restrictions ride along with the cue.

SCTE 35-2: event-based signaling (2026)

SCTE 35-2, released in May 2026, is the second part of the SCTE-35 family. It adds a streamlined EventDescriptor to time_signal that "takes the place of all other Signal and Descriptor combinations" and aligns transport-stream event carriage with the Event Appendix of SCTE 214-1, the DASH profile (SCTE 35-2 2026, scope). It covers frame-accurate and non-frame-accurate events in MPEG-2 transport streams, MPEG-DASH and HLS, and SCTE states it "is applicable as a replacement for all [SCTE 35-1] integrations."

What it means for a build today: Part 1 messages (splice_insert, and time_signal with segmentation descriptors) are what upstream feeds, encoders and ad-insertion services exchange now, so your parser must keep reading them. Treat 35-2 as the form to accept next: when you choose a packager or stitcher in 2026, ask whether its roadmap covers the 35-2 EventDescriptor, and keep your cue handling in one module so adding a second message form does not touch the rest of the pipeline.

The clock and the lead time: showing the math

Two numbers govern whether a break lands where it should, and both are worth working through out loud, because they explain a large share of real-world ad-timing bugs.

The first is the clock. SCTE-35 timestamps are expressed as a pts_time, a 33-bit value that counts ticks of a 90,000-ticks-per-second clock — the same 90 kHz presentation clock MPEG uses for video timing. To convert a wall-clock moment into a pts_time, multiply the seconds by 90,000:

splice point at 1 h 23 min 45.5 s into the stream
seconds      = (1 × 3600) + (23 × 60) + 45.5 = 5,025.5 s
pts_time     = 5,025.5 × 90,000 = 452,295,000 ticks

Because the field is 33 bits, the largest value it can hold is 2³³ − 1, so the clock wraps back to zero roughly every:

2^33 ÷ 90,000 ≈ 8,589,934,592 ÷ 90,000 ≈ 95,443 s ≈ 26.5 hours

That ~26.5-hour wrap is why a 24/7 channel cannot simply trust raw timestamps to keep climbing forever, and why the pts_adjustment field exists to correct timing when streams are re-stamped along the path. Units matter here: a timestamp off by 90,000 ticks is one full second of misalignment — an ad that starts a second into the host's next sentence.

The second number is lead time. A cue is useless if it arrives at the splicer too late to act on. The standard's pre-roll guidance is concrete: a cue "could be sent at 8, 5, 4 and 2 seconds prior to" the splice point, and warns that "any message received with less than 4 seconds of advance notice may not create the desired result" (ANSI/SCTE 35 2023r1, §9.1). The working rule that falls out of this: signal ad breaks at least 4 seconds ahead, and ideally repeat the cue several times during the run-up so a receiver that missed one copy still catches another. Most "the ad break didn't fire" incidents trace back to a cue that arrived inside that 4-second window.

A timeline running left to right toward the splice point. A caption says to send the cue at 8, 5, 4 and 2 seconds before the splice point, and four dots on the axis mark those moments, labelled in a staggered row above. The last four seconds of the axis, from the 4-second mark to the splice point, are drawn in orange. At the splice point a dashed line drops to a box marked ad avail and break_duration, with cue-out at its left edge and cue-in at its right. A legend explains the orange: under 4 seconds of notice, the cue may not fire, per SCTE-35 section 9.1. Figure 4. The pre-roll budget. The cue is sent several times before the splice point so a receiver that misses one copy still acts in time; cues arriving with under 4 seconds' notice may not fire.

From transport stream to manifest: SCTE-35 in HLS and DASH

So far the cue lives in an MPEG-2 transport stream — the broadcast-style container used for contribution and live feeds — where it rides on its own dedicated stream identified by a PID (a packet identifier) listed in the program's map table. But a viewer on a phone or smart TV is not watching a transport stream; they are watching segments named by an HLS or MPEG-DASH manifest, the small playlist that tells a player which chunks to download. So the cue has to be translated from the transport stream into the manifest. That translation is the packager's job, and it is where most streaming teams actually encounter SCTE-35.

In HLS (Apple's format, RFC 8216; its second edition, draft-pantos-hls-rfc8216bis-22 of May 2026, was in the RFC Editor queue as of October 2026), there are several ways the cue surfaces, from simplest to richest:

#EXTINF:4.0,
segment_18188.ts
#EXT-X-CUE-OUT:90.000        ← leave for a 90-second ad break (cue-out)
#EXTINF:4.0,
ad_segment_0001.ts
...
#EXT-X-CUE-IN                 ← return to the program (cue-in)
#EXTINF:4.0,
segment_18221.ts

The #EXT-X-CUE-OUT / #EXT-X-CUE-IN pair above is the simplest, duration-based form many ad-insertion services accept. For full fidelity, HLS uses the #EXT-X-DATERANGE tag, which can carry the original cue's raw bytes. RFC 8216 specifies that an out/in pair signalled by splice_insert "SHOULD be represented by one or more EXT-X-DATERANGE tags," with the out-point section placed in a SCTE35-OUT attribute and the in-point in SCTE35-IN (RFC 8216, §4.3.2.7.1):

#EXT-X-DATERANGE:ID="ad-break-42",START-DATE="2026-06-17T12:30:00Z",
  DURATION=90.000,SCTE35-OUT=0xFC30200000...

Some encoders also emit #EXT-OATCLS-SCTE35 or #EXT-X-SCTE35 tags carrying the base64- or hex-encoded raw SCTE-35 message, so a downstream system can re-parse the original cue exactly. Which tag you emit depends on what your ad-insertion service documents that it reads.

A newer HLS path changes what the player does with the cue. With HLS Interstitials (introduced by Apple in 2021), the server does not stitch the ad into the playlist; it adds an EXT-X-DATERANGE tag that tells the player to fetch and play the ad as a separate asset at that point. The industry calls this server-guided ad insertion (SGAI). AWS Elemental MediaTailor supports HLS Interstitials for live and VOD, schedules them from the SCTE markers in the origin manifest, and can pick SGAI or classic SSAI per session; AWS also warns that device support for interstitials "is not widespread" (AWS Media blog, updated March 2026). Either way the SCTE-35 cue is still the input: SGAI changes how the ad is delivered, not how the break is signalled. Our server-side ad insertion implementation guide compares SSAI, CSAI and SGAI for a launch.

In MPEG-DASH (ISO/IEC 23009-1, sixth edition 2026), the cue is expressed as an event inside the manifest (the MPD). SCTE 214 — the suite that profiles DASH for these services — defines two carriage paths: out-of-band events placed in the MPD as an EventStream, and in-band events carried in the segments as emsg boxes. The MPD form looks like this:

<Period start="PT32S" id="2">
  <EventStream schemeIdUri="urn:scte:scte35:2014:xml+bin" timescale="90000">
    <Event duration="8100000" id="42">
      <Signal xmlns="urn:scte:scte35:2013:xml">
        <Binary>/DAvAAAAAAAAAP/wBQb+AAAAAAAZAhdDVUVJ...==</Binary>
      </Signal>
    </Event>
  </EventStream>
</Period>

The Binary element holds the same SCTE-35 message, base64-encoded per RFC 4648 (ANSI/SCTE 35 2023r1, §7.4) — proof that HLS and DASH are two envelopes carrying the identical underlying cue. For the mechanics of the manifest formats themselves, see HLS vs DASH in the Video Streaming section; here we care only about how the cue travels inside them. The fact that one transport-stream cue maps cleanly into both manifests is what lets a single signaling pass serve every device — the same principle behind packaging CMAF, HLS, and DASH from one mezzanine.

One box at the top, SCTE-35 cue over splice_info_section, splits into two panels below. The left panel, HLS by RFC 8216 with EXT-X-DATERANGE, shows a playlist fragment: #EXT-X-CUE-OUT:90.000, then #EXT-X-DATERANGE:ID= Figure 5. One cue, two envelopes. The packager renders the same SCTE-35 message as HLS EXT-X-DATERANGE / CUE-OUT tags and as a DASH MPD EventStream, so every device sees the break.

The handshake: how a cue becomes a real ad

The cue is the start of the conversation, not the end of it. Once the marker reaches the ad-insertion layer, four steps turn it into an ad on screen.

The stitcher (in server-side insertion) or the player's ad component (in client-side insertion) detects the cue in the manifest and reads its type and duration. It then calls an ad decision server — the system that chooses which ad to show — using the advertising industry's request standard, VAST (Video Ad Serving Template, from the IAB Tech Lab), often orchestrated across a whole break by VMAP (which describes the full set of ad slots in a piece of content). The ad decision server returns the ad creative. Finally, for server-side insertion, the stitcher conditions that ad to match the content's quality ladder and rewrites the manifest so the ad plays as part of one continuous stream.

Two boundaries keep this article focused. The full VAST/VMAP request-and-response supply chain is its own subject, covered in ad serving, VAST/VMAP, and the ad stack; and the stitching architecture — why server-side insertion beats ad-blockers and keeps breaks smooth — is covered in SSAI vs CSAI. SCTE-35's job ends where those begin: it provides the where, how long, and what kind that the ad decision server needs to act. Without a correct cue, the most sophisticated ad stack in the world has nothing to fire on.

Out-of-band scheduling: SCTE 224 and ESNI

SCTE 224 is the out-of-band rulebook for linear channels: an API standard, current edition ANSI/SCTE 224 2021, that tells distributors which programs may air where, when blackouts and alternate content apply, and which audiences see what. Its full name is the Event Scheduling and Notification Interface (ESNI), and it carries that schedule and policy as structured data alongside the stream rather than inside it. Where SCTE-35 is the frame-accurate in-stream chalk mark, SCTE 224 is the rulebook delivered separately that tells systems how to interpret and apply those marks across regions and audiences.

The two are complementary, not competing. A live sports workflow commonly uses SCTE-104/35 for the precise in-stream timing of each break and SCTE 224 for the higher-level policy — this game is blacked out in these markets, this break is available for local sale in those. A platform that serves multiple territories or sells local inventory will eventually need both; a single-region AVOD catalog can often start with SCTE-35 alone.

The SCTE 224 data model is small. A Media object describes a channel or feed; its MediaPoint elements mark moments on that feed, either by clock time (matchTime) or by matching an in-stream signal (MatchSignal), which is how a SCTE 224 rule attaches to a SCTE-35 cue; each MediaPoint applies a Policy made of ViewingPolicy rules aimed at an Audience, such as a set of ZIP codes or device types. SCTE keeps building on the pair: SCTE 301, Next Generation Linear Channel Assembly (December 2025), extends SCTE 35, 224 and 250 into streaming channel assembly.

SCTE-35 vs SCTE-104 vs SCTE 224

The short version: SCTE-104 asks for a cue, SCTE-35 is the cue, SCTE 224 is the policy around it. All three are SCTE standards; the table shows where each one sits.

SCTE-104 SCTE-35 SCTE 224
What it is Automation-to-encoder API: the request "insert a break here" In-stream cue message: the mark itself Out-of-band schedule and policy interface (ESNI)
Where it travels Inside the facility, playout to encoder (often in SDI ancillary data or over IP) Inside the stream: MPEG-2 TS, then HLS tags and DASH events Beside the stream, as XML over a web API
Timing Timed to UTC, VITC or a hardware trigger Frame-accurate pts_time on a 90 kHz clock Schedule windows; can match an in-stream SCTE-35 signal
Typical job Playout automation tells the encoder about a break Ad insertion, chapter and program boundaries, blackout flags Regional blackouts, alternate content, audience rules
Current edition (Oct 2026) ANSI/SCTE 104 2023 ANSI/SCTE 35-1 2023r2 + SCTE 35-2 2026 ANSI/SCTE 224 2021

Table 3. The three SCTE standards around an ad break. Editions as listed in the SCTE standards catalog, checked October 2026.

A common mistake: trusting the marker without conditioning the stream

The recurring failure in ad signaling is treating the cue as the whole job. A team wires up SCTE-35 pass-through, sees the markers appear in the manifest, and assumes ads will land cleanly — then discovers breaks that start a beat late, ads that never fire, or breaks that cut a host off mid-word. The root cause is almost always one of three signaling-specific mistakes, none of which the ad stack can fix on its own.

The first is the splice point not landing on a segment boundary. A player can only switch streams at the edge of a segment, so if the cue's pts_time falls in the middle of a chunk, the splice rounds to the nearest boundary and drifts. The fix is to align encoding so a segment boundary (an IDR frame, the kind a player can cut to) sits exactly at the splice point — which is why encoders insert a keyframe at the cue. The second is the late cue: a marker delivered inside the 4-second pre-roll window the standard warns about, which a splicer may simply ignore. The third is dropping the descriptors: a pipeline that preserves a bare time_signal but strips its segmentation descriptor delivers a timestamp with no meaning, so the ad server cannot tell a placement opportunity from a chapter mark. Correct ad signaling is not "are the markers present" — it is "are they accurate, early enough, on a boundary, and complete." That is a quality-control discipline, not a checkbox.

How to decode and debug a SCTE-35 cue

To read a cue, take the raw message from wherever it surfaced (the SCTE35-OUT attribute in HLS, the Binary element in a DASH MPD, or the SCTE-35 PID in a transport stream) and run it through a decoder. A base64 cue starts with /D, usually /DA for short messages, because its first byte is always 0xFC (the table_id) and the next one is normally 0x30; if a string starts any other way, it is not a raw SCTE-35 section. Open-source decoders cover most teams: threefive for Python, Comcast's scte35-go and scte35-js, and TSDuck for whole transport streams. The decoded output shows the command, pts_time, duration, segmentation type and UPID, which is everything you need to check the four rules from the previous section.

On a FAST or live channel, debug a bad break in this order. First, compare the cue's pts_time with the segment boundaries in the manifest: a break that cuts off content usually means the splice point is not on an IDR frame at a segment edge, or the ads returned run longer than the signalled break, so the return to the program comes late. Second, check the lead time: the cue should reach the stitcher at least 4 seconds before the splice. Third, confirm the segmentation descriptor survived packaging. Only then look at the ad side: an avail that opens correctly but stays empty is an ad decision or VAST problem, not a signaling one. For FAST-specific setup, see our FAST channel development guide.

Frequently asked questions

What is SCTE-35?

SCTE-35 is the SCTE standard for in-stream cue messages that mark ad breaks and other program boundaries in a video stream. Ad-insertion systems read the cue to know where a break starts, how long it lasts and what kind of break it is.

What are SCTE-35 cue tones?

"Cue tones" is the older name for the same job: in analog cable, a DTMF tone sequence or contact closure triggered local ad insertion. SCTE-35 is the digital replacement, and the standard still carries a DTMF_descriptor so equipment can regenerate the old tones.

What is the difference between SCTE-35 and SCTE-104?

SCTE-104 is the request from playout automation to the encoder; SCTE-35 is the cue the encoder then writes into the stream. SCTE-104 stays inside the broadcast facility, while SCTE-35 travels with the video to packagers, stitchers and players.

What is SCTE 224?

SCTE 224, the Event Scheduling and Notification Interface (ESNI), is an out-of-band API that delivers schedules and viewing policy such as regional blackouts and alternate content. It complements SCTE-35: SCTE-35 marks the exact moment, SCTE 224 says what rules apply to it and for which audience.

What is a SCTE trigger?

A SCTE trigger is informal shorthand for the signal that starts a break: a SCTE-35 cue in the stream, or the SCTE-104 message that makes the encoder insert one.

Why do ad breaks cut off content on a FAST channel?

Usually because the splice point does not land on a segment boundary, the cue arrives with less than 4 seconds of notice, or the break duration does not match the ads returned. Align an IDR frame and segment edge with each cue, send cues early and repeat them, and make the stitcher fill or trim to the signalled duration.

How do I debug VAST errors on a FAST channel?

First decode the SCTE-35 cue to prove the avail opened at the right time with the right duration. If it did, the error sits in the ad request or response: read the VAST error code your player or stitcher logs and check the ad pod settings, both explained in our guide to ad serving, VAST/VMAP and ad pods.

↓ Free download: SCTE-35 Ad-Signaling Field & Marker ReferenceThe splice_info_section field by field, the command table (0x00 to 0xFF) and the segmentation type IDs (0x10 to 0x41) with their UPID types, the HLS and DASH carriage cheat sheet, and the pre-roll and QC checklist — one page you can keep open while you debug a break.

Where Fora Soft fits in

Ad signaling is where broadcast precision meets streaming scale, and the expensive failures are quiet: a break that fires a second late on every viewer, a blackout that leaks because a restriction flag was dropped, or a national feed whose local avails never open because the segmentation descriptor was stripped in packaging. Fora Soft has built video-streaming and OTT/Internet-TV platforms since 2005, across 250+ shipped projects, which means we have wired SCTE-104-to-SCTE-35 pipelines for live channels, conditioned encodes so splice points land on segment boundaries, carried cues faithfully into HLS and DASH manifests, and connected them to ad decision servers and server-side stitchers that hold up under live load. Our stance is scalability-first and vendor-neutral: we start from the scale and accuracy your channels demand — frame-accurate breaks across every device, correct blackouts across every territory — then build the signaling and ad-insertion path that your live, FAST, and AVOD streams actually require. That signaling work is part of our OTT, IPTV and Internet TV development, and for broadcast-grade channels on Wowza our Wowza streaming developers carry the cues through LL-HLS and CMAF packaging. For Mangomolo, an OTT platform that serves over 1 billion streams a month to 50+ publishers, we built a custom Wowza module that recognises SCTE-35 markers in live streams and inserts the right ads server-side in real time. If your channel needs the encoder, packager and stitcher side built from scratch, that is the core of our video streaming software development work.

Video Streaming: From ABR and CDNs to Players, WebRTC, DRM, and the Economics of Streaming - book coverVideo Streaming: From Network Protocols and Transport to Ingest, HLS, and MPEG-DASH - book coverVideo Encoding: A Complete Guide to Video Compression - book cover

The handbook

Fora Soft Video Engineering Handbook

We wrote a seven-volume handbook, 9,000+ pages, that takes the video stack from a single pixel to production — encoding, delivery, audio and AI — and someone who works through it can design and build a platform end to end. Volume 2 is the one to open next to this article: transport streams, ingest and the HLS and DASH packaging that decide whether your cue survives the trip into the manifest. Volume 3 picks up on the other side with players, DRM and the economics of ad-supported delivery, and volume 1 covers the encoding and IDR placement that make a splice point land on a segment boundary instead of drifting to the next one. Written by Nikolay Sapunov, CEO at Fora Soft.

Browse the handbook on Amazon →7 volumes · Kindle & paperback

Are your ad breaks landing where the cue says they should?

Tell us where your cues come from — a SCTE-104 automation feed, a VOD packaging pass, or an out-of-band SCTE 224 schedule — and what your segment duration and pre-roll look like, and we will say what it takes to get breaks that land on a boundary, cues that arrive more than 4 seconds ahead, and segmentation descriptors that survive packaging into HLS and DASH. 250+ video products shipped since 2005.

Book a 30-min call →WhatsApp →Email us →

See our case studies

References

  1. ANSI/SCTE 35-1 2023r2 — Digital Program Insertion Cueing Message Part 1: Legacy Splice-Based and Time-Based Signaling. SCTE. Tier 1. The current text of SCTE-35, renumbered from SCTE 35 and retitled to distinguish it from SCTE 35-2. https://account.scte.org/standards/library/catalog/scte-35-1-digital-program-insertion-cueing-message-part-1-legacy-splice-based-and-time-based-signaling/ — accessed 2026-10-26.
  2. SCTE 35-2 2026 — Digital Program Insertion Cueing Message Part 2: Event-Based Signaling. SCTE. Tier 1. Adds the EventDescriptor to time_signal, aligned with the SCTE 214-1 Event Appendix; "applicable as a replacement for all [SCTE 35-1] integrations." Released May 2026 (SCTE standards updates). https://account.scte.org/standards/library/catalog/scte-35-2-digital-program-insertion-cueing-message-part-2-event-based-signaling/ — accessed 2026-10-26.
  3. SCTE standards updates. SCTE. Tier 1. May 2026 release of SCTE 35-2; December 2025 release of SCTE 301 Next Generation Linear Channel Assembly. https://www.scte.org/standards/standards-updates/ — accessed 2026-10-26.
  4. ANSI/SCTE 35 2023r1 — Digital Program Insertion Cueing Message. Society of Cable Telecommunications Engineers (SCTE). Tier 1. The controlling standard for in-stream ad-break signaling; defines the splice_info_section (table_id 0xFC), the command types (splice_insert 0x05, time_signal 0x06), out_of_network_indicator semantics, segmentation descriptors and their type IDs (Table 23) and UPID types (Table 22), the pre-roll guidance (§9.1), and the base64/XML representation (§7.4). Published 2023-11-30. https://account.scte.org/standards/library/catalog/scte-35-digital-program-insertion-cueing-message/ — accessed 2026-06-17.
  5. ANSI/SCTE 104 2023 — Automation System to Compression System Communications API. SCTE. Tier 1. Defines the upstream interface an automation/playout system uses to request that the encoder insert SCTE-35 cues, timed to UTC, VITC, or a hardware trigger; SCTE-35 is the in-stream fulfillment of a SCTE-104 request. https://www.scte.org/standards/library/catalog/scte-104-automation-system-to-compression-system-communications-api/ — accessed 2026-06-17.
  6. ANSI/SCTE 224 2021 — Event Scheduling and Notification Interface (ESNI). SCTE. Tier 1. The out-of-band, API-based standard for scheduling and policy (blackouts, audience, alternate content) that complements in-stream SCTE-104/35 signaling. https://www.scte.org/standards/library/catalog/scte-224-event-scheduling-and-notification-interface/ — accessed 2026-06-17.
  7. ANSI/SCTE 214-1 / 214-3 — MPEG DASH for IP-Based Cable Services (MPD constraints; ISO BMFF / emsg carriage of SCTE-35). SCTE. Tier 1. Specifies how SCTE-35 events are carried in DASH as out-of-band MPD EventStream events (214-1, §6.7) and as in-band emsg events (214-3, §7.3). https://account.scte.org/standards/library/catalog/scte-214-1-mpeg-dash-for-ip-based-cable-services-part1-mpd-constraints-and-extensions/ — accessed 2026-06-17.
  8. HTTP Live Streaming — RFC 8216. IETF. Tier 1. §4.3.2.7.1 specifies how SCTE-35 cues map into HLS via the EXT-X-DATERANGE tag using SCTE35-OUT, SCTE35-IN, and SCTE35-CMD attributes; the second edition, draft-pantos-hls-rfc8216bis-22 (2026-05-01), was in the RFC Editor queue on 2026-10-26 (IETF datatracker). https://www.rfc-editor.org/rfc/rfc8216 — accessed 2026-06-17.
  9. Dynamic adaptive streaming over HTTP (DASH) — Part 1, ISO/IEC 23009-1. ISO/IEC. Tier 1. The DASH manifest standard whose EventStream / in-band event mechanism carries SCTE-35 cues into the MPD. Sixth edition, ISO/IEC 23009-1:2026. https://www.iso.org/standard/89027.html — accessed 2026-10-26.
  10. VAST and VMAP — Digital Video Ad Serving Template / Video Multiple Ad Playlist. IAB Tech Lab. Tier 1. The ad-request standards an ad decision server answers once a SCTE-35 cue opens an avail; VMAP describes the full set of ad slots in a piece of content. https://iabtechlab.com/standards/vast/ — accessed 2026-06-17.
  11. SCTE-35: The Essential Guide (2025 update). Bitmovin (Andy Francis). Tier 4 (first-party encoder vendor). Used to cross-check the HLS tag set (EXT-X-CUE-OUT/IN, EXT-OATCLS-SCTE35, EXT-X-DATERANGE), the DASH MPD EventStream example, and the segmentation-type-to-command support matrix; not used as the source for any normative spec claim. https://bitmovin.com/blog/scte-35-guide/ — accessed 2026-06-17.
  12. Comcast scte35-go / scte35-js — open-source SCTE-35 reference parsers. Comcast. Tier 4 (first-party implementation). Cross-checked the segmentation type-ID and UPID-type enumerations against a widely used implementation. https://github.com/Comcast/scte35-go — accessed 2026-06-17.
  13. SCTE-35 signal conditioning and EXT-X-DATERANGE ad markers. AWS Elemental (Live / MediaTailor documentation). Tier 3 (first-party vendor). Documents how a production encoder conditions SCTE-35 and how a packager/stitcher renders the cue into HLS markers. https://docs.aws.amazon.com/elemental-live/latest/ug/scte-35-ad-marker-ext-x-daterange.html — accessed 2026-06-17. Vendor docs — re-check.
  14. 2026 Digital Video Ad Spend & Strategy Report. IAB. Tier 3. US digital video ad spend above $80B in 2026 (+11%); CTV $29.3B (+11%). https://www.iab.com/news/u-s-digital-video-ad-spend-to-surpass-80b-in-2026/ — accessed 2026-10-26.
  15. Support for HLS Interstitials in AWS Elemental MediaTailor. AWS Media blog (updated 2026-03-28). Tier 3 (first-party vendor). SGAI via HLS Interstitials for live and VOD, scheduling from SCTE markers, PLAYER_SELECT mode, device-support caveat. https://aws.amazon.com/blogs/media/support-for-hls-interstitials-in-aws-elemental-mediatailor/ — accessed 2026-10-26.
  16. SCTE 224 ESNI API reference. broadpeak.io. Tier 4 (vendor implementation). Media, MediaPoint (matchTime, MatchSignal), Policy, ViewingPolicy and Audience objects. https://developers.broadpeak.io/docs/scte-224-esni-api — accessed 2026-10-26.
  17. Fora Soft — Video Streaming App Monetisation (overview blog). Fora Soft. Tier 7. Product-level companion on AVOD/FAST/SVOD/TVOD monetization; the commercial-intent counterpart this educational article links to. https://www.forasoft.com/blog/article/video-streaming-app-monetization-strategies — accessed 2026-06-17.

Where sources disagreed, the controlling standard was followed. The command types, table_id, out_of_network_indicator semantics, pre-roll guidance, and base64/XML representation are cited from ANSI/SCTE 35 2023r1 directly; the segmentation type-ID and UPID tables (Tables 23 and 22) are sourced to the spec and cross-checked against the Comcast reference implementation and Bitmovin's published matrix. HLS carriage is cited from RFC 8216 §4.3.2.7, DASH carriage from SCTE 214 and ISO/IEC 23009-1. The popular shorthand that "time_signal is just a newer splice_insert" was overridden in favour of the precise framing — time_signal carries only a timestamp and depends on segmentation descriptors for meaning (§9.3). CTV-spend figures are 2026 analyst estimates, cited as a forecast.