Skip to content

feat(media-use): tag HeyGen API calls with X-HeyGen-Client-Source#2365

Merged
miguel-heygen merged 1 commit into
mainfrom
worktree-media-use-client-source
Jul 14, 2026
Merged

feat(media-use): tag HeyGen API calls with X-HeyGen-Client-Source#2365
miguel-heygen merged 1 commit into
mainfrom
worktree-media-use-client-source

Conversation

@miguel-heygen

Copy link
Copy Markdown
Collaborator

What

media-use now sends an X-HeyGen-Client-Source: media-use header on every HeyGen API request it makes (both OAuth and API-key auth), via heygenAuthHeaders() and the heygenJSON transport in the audio engine.

Why

media-use resolves voice / TTS / sound assets through the HeyGen API. Today those requests are indistinguishable from other first-party CLI traffic, so HeyGen API usage can't be attributed back to media-use. A stable, self-declared tool-attribution header lets the backend tag media-use usage as its own source. The header name already exists in the sound-search path (heygen-search.mjs); this extends it to the credit-consuming audio calls and makes it consistent across the engine.

How

  • New HEYGEN_CLIENT_SOURCE_HEADERS constant.
  • Merged unconditionally into heygenAuthHeaders() (covers the TTS request path) and into the heygenJSON transport's default headers (covers other REST calls).
  • Unconditional of auth type — a paying user's media-use call is still media-use — unlike the OAuth-only X-HeyGen-Source: cli header, which also gates the free allowance and is deliberately left untouched.

Test plan

  • heygen.test.mjs: both auth branches (api-key and OAuth) now assert X-HeyGen-Client-Source: media-use is present. node --test heygen.test.mjs → 5/5 pass.
  • oxlint + oxfmt clean on changed files.

Not covered

  • The header is consumed and persisted by a paired backend change; until that ships, the tag is sent but not yet recorded.
  • Non-HeyGen media providers and the hyperframes CLI's own calls are out of scope.

@somanshreddy somanshreddy left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed as the sender half of the X-HeyGen-Client-Source pair (EF #41968 is the receiver). LGTM — clean, and the wire seam lines up.

  • The value emitted here — X-HeyGen-Client-Source: media-use — is exactly what EF #41968's persist allowlist accepts (_KNOWN_CLIENT_SOURCES = {"media-use", "hyperframes"}), so the tag actually lands in billing meta rather than silently dropping. That cross-PR value match is the make-or-break check for this feature, and it holds.
  • Sent on both auth types. The comment correctly distinguishes this unconditional tool-attribution header from the OAuth-only X-HeyGen-Source: cli header that gates the free allowance — a paying (API-key) media-use call is still media-use, so tagging it too is right, and it matches the receiver reading client_source on both auth paths.
  • Tests updated for both branches (API-key + OAuth) asserting the tag is present. ✅
  • skills-manifest.json hash bump is the expected artifact of the skill-file change; CI (incl. manifest checks) is green.

Non-blocking nit: in heygenJSON, { ...HEYGEN_CLIENT_SOURCE_HEADERS, ...headers } lets a caller-supplied header override the tag. Harmless here (auth headers carry the same value, and an explicit override is a reasonable escape hatch) — just flagging that the precedence is intentional.

— Somu

@james-russo-rames-d-jusso james-russo-rames-d-jusso left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed as the client half of the X-HeyGen-Client-Source pair with EF#41968 open in the other tab. Layering on Somu's review (which nailed the wire-seam value-match + dual-auth coverage) — adding one call-site coverage check and cross-linking one downstream gotcha that lives on the EF side but is worth surfacing here for the Hex-slice goal.

Call-site coverage (comprehensive, not narrow — verified). Traced every credit-consuming HeyGen API call path in media-use and all of them go through a tagged transport at head cc1b7eb:

  • heygen-tts.mjs:69heygenAuthHeaders() → tagged at heygen.mjs:96-98 (both OAuth and API-key branches).
  • heygen-tts.mjs:76 (/voices?engine=starfish...) → heygenJSON(...) → tagged at heygen.mjs:111.
  • audio/scripts/lib/tts.mjs:306-309 synthesizeHeygenheygenJSON('/voices/speech', ...) with authHeaders() → double-tagged (auth-headers already carry the tag; heygenJSON merges its own default) — same value both places, safe.
  • scripts/lib/heygen-search.mjs:11 (pre-existing) already emits the same header/value via the heygen --headers flag; this PR is the missing-half extension to the audio engine (right pattern).

No un-tagged HeyGen API call path in media-use/ at HEAD. So the Hex-slice denominator ("all media-use HeyGen consumption") shouldn't have blind spots on the emit side.

One downstream drop worth checking with the receiver PR (EF#41968). MovioBill.meta picks up client_source fine via get_api_origin_meta_extras() — that's the direct write path this PR targets. But EF's filter_api_origin_meta() (used by heygen/jobs/video_repurpose/process_clip_activity.py and heygen/services/heygen_server/video_metadata_store.py to copy origin attribution onto derived resources) reads a fixed tuple API_ORIGIN_META_KEYS that does not include client_source at EF HEAD 58f8ee6. If the Hex-slice dashboard queries only the direct bill row, no issue. If it also expects the tool dimension to survive video_repurpose → clip meta or master_video_metadata propagation, client_source needs to land in that tuple too. Flagged on the EF PR — non-blocking here, cross-linked so the pair discussion sees it.

Small note, non-blocking. The header is user-declared and there is no server-side auth boundary tied to it (EF's _KNOWN_CLIENT_SOURCES allowlist gates persistence, and genesis-code-reviewer confirmed client_source feeds no OAuthBillingDecision / get_feature / quota routing). So spoofing risk is analytics-inflation only — worth carrying as a known property of the tag, not a fix here.

LGTM from my side — leaving as a comment; approval routes to Vai / OG on Miguel's stamp convention.

Review by Rames D Jusso

Send `X-HeyGen-Client-Source: media-use` on every media-use HeyGen API
request (both auth types, via heygenAuthHeaders + the heygenJSON transport),
so backend billing meta can isolate media-use consumption from other free
TTS and avatar-video usage. Unconditional of auth type — a paying user's
media-use call is still media-use — unlike the OAuth-only cli-source header
that gates the free allowance.
@miguel-heygen
miguel-heygen force-pushed the worktree-media-use-client-source branch from 3e1a56e to 344ed75 Compare July 13, 2026 23:03
@miguel-heygen
miguel-heygen merged commit dd938c7 into main Jul 14, 2026
40 checks passed
@miguel-heygen
miguel-heygen deleted the worktree-media-use-client-source branch July 14, 2026 00:03
miguel-heygen added a commit that referenced this pull request Jul 14, 2026
…Source (#2391)

The agent-driven video recipes (heygen video create) went out untagged, so
media-use avatar / image-to-video usage landed as generic cli traffic and
wasn't attributable to media-use. Add --headers "X-HeyGen-Client-Source:
media-use" to the generating recipes (persistent flag, allowlisted by the
CLI) so those videos carry client_source in master_video_table meta and show
up in the API dashboards alongside the TTS path (#2365) and CLI (#2368).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants