From 3f397f5068a003eef92cc3eb6d01b9e8ab89624f Mon Sep 17 00:00:00 2001 From: Miguel Angel Simon Sierra Date: Mon, 13 Jul 2026 18:49:39 -0400 Subject: [PATCH] feat(cli): tag HeyGen API calls with X-HeyGen-Client-Source Send `X-HeyGen-Client-Source: hyperframes` from buildAuthHeaders on every HeyGen API call (both OAuth and API-key), so backend billing meta can isolate hyperframes CLI usage. The single buildAuthHeaders chokepoint covers the core CLI + cloud client. Mirrors the media-use tagging; the OAuth-only X-HeyGen-Source cli free-gate header is unchanged. --- packages/cli/src/auth/client.test.ts | 6 +++++- packages/cli/src/auth/client.ts | 12 ++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/packages/cli/src/auth/client.test.ts b/packages/cli/src/auth/client.test.ts index c30bb3f38a..844502d77e 100644 --- a/packages/cli/src/auth/client.test.ts +++ b/packages/cli/src/auth/client.test.ts @@ -3,6 +3,8 @@ import { AuthClient, HEYGEN_CLI_SOURCE, HEYGEN_CLI_SOURCE_HEADER, + HEYGEN_CLIENT_SOURCE, + HEYGEN_CLIENT_SOURCE_HEADER, apiBaseUrl, buildAuthHeaders, } from "./client.js"; @@ -81,12 +83,14 @@ describe("auth/client", () => { expect(buildAuthHeaders(cred)).toEqual({ authorization: "Bearer at_123", [HEYGEN_CLI_SOURCE_HEADER]: HEYGEN_CLI_SOURCE, + [HEYGEN_CLIENT_SOURCE_HEADER]: HEYGEN_CLIENT_SOURCE, }); }); - it("buildAuthHeaders uses x-api-key for api_key, without the cli-source header", () => { + it("buildAuthHeaders uses x-api-key for api_key, without the cli-source header but with the tool tag", () => { expect(buildAuthHeaders(apiKeyCred())).toEqual({ "x-api-key": "hg_x", + [HEYGEN_CLIENT_SOURCE_HEADER]: HEYGEN_CLIENT_SOURCE, }); }); diff --git a/packages/cli/src/auth/client.ts b/packages/cli/src/auth/client.ts index 10e858e4d1..0bb3f92bb4 100644 --- a/packages/cli/src/auth/client.ts +++ b/packages/cli/src/auth/client.ts @@ -23,6 +23,12 @@ import type { OAuthTokens } from "./store.js"; const DEFAULT_BASE_URL = "https://api.heygen.com"; export const HEYGEN_CLI_SOURCE_HEADER = "X-HeyGen-Source"; export const HEYGEN_CLI_SOURCE = "cli"; +// Tool-attribution header identifying this CLI as the request origin. Sent on +// every HeyGen call (both auth types) so the backend can isolate hyperframes CLI +// usage in billing meta. Distinct from HEYGEN_CLI_SOURCE_HEADER above, which is +// the OAuth-only cli-source header that gates the free allowance. +export const HEYGEN_CLIENT_SOURCE_HEADER = "X-HeyGen-Client-Source"; +export const HEYGEN_CLIENT_SOURCE = "hyperframes"; export function apiBaseUrl(): string { const override = process.env["HEYGEN_API_URL"]; @@ -182,12 +188,14 @@ export function buildAuthHeaders(credential: ResolvedCredential): Record {