@contenthero/sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,116 @@
1
+ # @contenthero/sdk
2
+
3
+ Official SDK for the [ContentHero](https://contenthero.ai) Studio API. Generate images, video, and audio programmatically. This is the shared kernel the ContentHero MCP and CLI sit on.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @contenthero/sdk
9
+ ```
10
+
11
+ Requires Node 20+ (uses the global `fetch`).
12
+
13
+ ## Quick start
14
+
15
+ ```ts
16
+ import { ContentHero } from '@contenthero/sdk'
17
+
18
+ const client = new ContentHero({ apiKey: process.env.CONTENTHERO_API_KEY })
19
+
20
+ // Submit and poll to completion.
21
+ const image = await client.generateAndWait({
22
+ modelId: 'nano-banana-2',
23
+ prompt: 'a golden retriever astronaut on the moon, cinematic',
24
+ aspectRatio: '16:9',
25
+ })
26
+
27
+ console.log(image.outputUrls)
28
+ ```
29
+
30
+ The API key (`ch_live_...`) is read from `CONTENTHERO_API_KEY` when not passed explicitly. Identity is resolved from the key server-side, so you never send a user id.
31
+
32
+ ## Generation is async
33
+
34
+ On the wire, generation is always asynchronous: a submit returns immediately and you poll for the result. The SDK gives you both shapes.
35
+
36
+ ```ts
37
+ // Fire-and-forget: returns as soon as the job is accepted.
38
+ const { outputId } = await client.generate({
39
+ modelId: 'veo-3',
40
+ prompt: 'a timelapse of a city at dusk',
41
+ duration: 8,
42
+ audioEnabled: true,
43
+ })
44
+
45
+ // Poll yourself, later.
46
+ const generation = await client.getGeneration(outputId)
47
+ if (generation.status === 'completed') {
48
+ console.log(generation.outputUrls)
49
+ }
50
+ ```
51
+
52
+ `generateAndWait` does the polling for you and resolves with the finished `Generation` (or throws `GenerationFailedError` / `GenerationTimeoutError`). Tune it with `{ pollIntervalMs, timeoutMs, signal }`.
53
+
54
+ Audio (ElevenLabs) is synchronous server-side, so `generate` returns `status: 'completed'` with `outputUrls` already populated.
55
+
56
+ ## The request envelope
57
+
58
+ `modelId` is always required. Beyond that, a typed core of universal fields covers most needs, `references` carries image/video/frame inputs, and `parameters` is a passthrough for anything model-specific. Per-model capabilities are validated server-side, so an unsupported field for a given model comes back as a `ValidationError`.
59
+
60
+ ```ts
61
+ // Image-to-image with a reference.
62
+ await client.generate({
63
+ modelId: 'nano-banana-2',
64
+ prompt: 'turn this into a watercolor',
65
+ references: { images: ['https://...'] },
66
+ })
67
+
68
+ // Text-to-speech.
69
+ await client.generate({
70
+ modelId: 'elevenlabs-tts',
71
+ text: 'Welcome to ContentHero.',
72
+ voiceId: 'your-voice-id',
73
+ })
74
+ ```
75
+
76
+ ## Balance
77
+
78
+ ```ts
79
+ const { balance, tier, autoTopupEnabled } = await client.getBalance()
80
+ ```
81
+
82
+ ## Errors
83
+
84
+ Every non-2xx response maps to a typed error; all extend `ContentHeroError`.
85
+
86
+ | Class | Status | Meaning |
87
+ | --- | --- | --- |
88
+ | `ValidationError` | 400 | Malformed or model-unsupported request |
89
+ | `AuthenticationError` | 401 | Missing, revoked, or expired key |
90
+ | `InsufficientCreditsError` | 402 | Not enough credits (carries `balance`, `required`) |
91
+ | `PermissionError` | 403 | Key lacks the required scope |
92
+ | `NotFoundError` | 404 | Unknown generation id |
93
+ | `GenerationFailedError` | n/a | `generateAndWait` saw a terminal failure |
94
+ | `GenerationTimeoutError` | n/a | `generateAndWait` exceeded `timeoutMs` |
95
+
96
+ ```ts
97
+ import { InsufficientCreditsError } from '@contenthero/sdk'
98
+
99
+ try {
100
+ await client.generateAndWait({ modelId: 'veo-3', prompt: '...' })
101
+ } catch (err) {
102
+ if (err instanceof InsufficientCreditsError) {
103
+ console.error(`Need ${err.required}, have ${err.balance}`)
104
+ }
105
+ }
106
+ ```
107
+
108
+ ## Configuration
109
+
110
+ ```ts
111
+ new ContentHero({
112
+ apiKey: '...', // or CONTENTHERO_API_KEY
113
+ baseUrl: 'https://app.contenthero.ai', // or CONTENTHERO_BASE_URL
114
+ fetch: customFetch, // optional, defaults to global fetch
115
+ })
116
+ ```
@@ -0,0 +1,84 @@
1
+ /**
2
+ * The ContentHero client: a thin, typed wrapper over the /api/v1 surface.
3
+ *
4
+ * Identity is the API key. The key resolves the owning account server-side, so
5
+ * the SDK never sends a user id. Generation is always-async on the wire; the
6
+ * SDK offers both a fire-and-forget `generate` and a `generateAndWait` that
7
+ * polls to a terminal state for you.
8
+ */
9
+ import type { Avatar, AvatarSummary, Balance, BrandKit, BrandKitSummary, GenerateRequest, GenerateResult, Generation, ListMediaOptions, MediaItem, MediaSummary, ModelInfo, TranscribeRequest, Transcription, Voice, VoiceSummary, WaitOptions } from './types.js';
10
+ /** Minimal fetch signature, so a custom implementation can be injected. */
11
+ export type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;
12
+ export interface ContentHeroOptions {
13
+ /**
14
+ * API key (`ch_live_...`). Falls back to the `CONTENTHERO_API_KEY`
15
+ * environment variable when omitted.
16
+ */
17
+ apiKey?: string;
18
+ /**
19
+ * API base URL. Falls back to `CONTENTHERO_BASE_URL`, then the production
20
+ * host. Override for self-hosted or preview environments.
21
+ */
22
+ baseUrl?: string;
23
+ /** Custom fetch implementation. Defaults to the global `fetch`. */
24
+ fetch?: FetchLike;
25
+ }
26
+ export declare class ContentHero {
27
+ private readonly apiKey;
28
+ private readonly baseUrl;
29
+ private readonly fetchImpl;
30
+ constructor(options?: ContentHeroOptions);
31
+ /**
32
+ * Submit a generation. Returns immediately. For image/video the result is
33
+ * `status: 'processing'` (poll with `getGeneration` or use `generateAndWait`);
34
+ * audio returns `status: 'completed'` with `outputUrls` populated.
35
+ */
36
+ generate(request: GenerateRequest): Promise<GenerateResult>;
37
+ /** Fetch the current state of a generation by its id. */
38
+ getGeneration(outputId: string): Promise<Generation>;
39
+ /**
40
+ * Submit a generation and poll until it reaches a terminal state. Resolves
41
+ * with the completed `Generation`, throws `GenerationFailedError` if it fails,
42
+ * or `GenerationTimeoutError` if it does not finish within `timeoutMs` (the
43
+ * server-side job may still complete; re-poll with `getGeneration`).
44
+ */
45
+ generateAndWait(request: GenerateRequest, options?: WaitOptions): Promise<Generation>;
46
+ /** Fetch the authenticated account's credit balance, tier, and auto-top-up state. */
47
+ getBalance(): Promise<Balance>;
48
+ /**
49
+ * Transcribe an audio URL to text (ElevenLabs Scribe). Synchronous: the
50
+ * transcript comes back inline. Free (no credit charge).
51
+ */
52
+ transcribe(request: TranscribeRequest): Promise<Transcription>;
53
+ /** List the account's avatars (the list half of the list+get pair). */
54
+ listAvatars(): Promise<AvatarSummary[]>;
55
+ /** Get one avatar with its looks (the get half). Throws NotFoundError if absent. */
56
+ getAvatar(avatarId: string): Promise<Avatar>;
57
+ /** List the account's saved voices (the list half of the list+get pair). */
58
+ listVoices(): Promise<VoiceSummary[]>;
59
+ /** Get one voice's detail (the get half). Throws NotFoundError if absent. */
60
+ getVoice(voiceId: string): Promise<Voice>;
61
+ /** List the account's brand kits (the list half of the list+get pair). */
62
+ listBrandKits(): Promise<BrandKitSummary[]>;
63
+ /** Get one brand kit, fully assembled (the get half). Throws NotFoundError if absent. */
64
+ getBrandKit(brandKitId: string): Promise<BrandKit>;
65
+ /** List the account's recent studio outputs (the list half of the list+get pair). */
66
+ listMedia(options?: ListMediaOptions): Promise<MediaSummary[]>;
67
+ /**
68
+ * Get one studio output by id token (the get half). The token may be the full
69
+ * output id, its first 8 characters, or either with a `-N` variation suffix
70
+ * (1-based). Throws NotFoundError if absent.
71
+ */
72
+ getMedia(idToken: string): Promise<MediaItem>;
73
+ /**
74
+ * List the models available to this key (the discovery catalog): which models
75
+ * exist, their content type and operation kind, and their capability surface.
76
+ * The source of truth for building model selections instead of hardcoding ids.
77
+ */
78
+ listModels(options?: {
79
+ contentType?: 'image' | 'video' | 'audio';
80
+ }): Promise<ModelInfo[]>;
81
+ /** Issue an authenticated request and map non-2xx responses to typed errors. */
82
+ private request;
83
+ }
84
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EACV,MAAM,EACN,aAAa,EACb,OAAO,EACP,QAAQ,EACR,eAAe,EACf,eAAe,EACf,cAAc,EACd,UAAU,EACV,gBAAgB,EAChB,SAAS,EACT,YAAY,EACZ,SAAS,EACT,iBAAiB,EACjB,aAAa,EACb,KAAK,EACL,YAAY,EACZ,WAAW,EACZ,MAAM,YAAY,CAAA;AAEnB,2EAA2E;AAC3E,MAAM,MAAM,SAAS,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AAEhF,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,mEAAmE;IACnE,KAAK,CAAC,EAAE,SAAS,CAAA;CAClB;AAKD,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAQ;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAW;gBAEzB,OAAO,GAAE,kBAAuB;IAqB5C;;;;OAIG;IACG,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IAIjE,yDAAyD;IACnD,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAO1D;;;;;OAKG;IACG,eAAe,CAAC,OAAO,EAAE,eAAe,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,UAAU,CAAC;IAqB/F,qFAAqF;IAC/E,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAIpC;;;OAGG;IACG,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,aAAa,CAAC;IAIpE,uEAAuE;IACjE,WAAW,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;IAK7C,oFAAoF;IAC9E,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIlD,4EAA4E;IACtE,UAAU,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IAK3C,6EAA6E;IACvE,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IAI/C,0EAA0E;IACpE,aAAa,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAKjD,yFAAyF;IACnF,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAIxD,qFAAqF;IAC/E,SAAS,CAAC,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAiBxE;;;;OAIG;IACG,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAInD;;;;OAIG;IACG,UAAU,CAAC,OAAO,GAAE;QAAE,WAAW,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,CAAA;KAAO,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAMnG,gFAAgF;YAClE,OAAO;CA4BtB"}
package/dist/client.js ADDED
@@ -0,0 +1,190 @@
1
+ /**
2
+ * The ContentHero client: a thin, typed wrapper over the /api/v1 surface.
3
+ *
4
+ * Identity is the API key. The key resolves the owning account server-side, so
5
+ * the SDK never sends a user id. Generation is always-async on the wire; the
6
+ * SDK offers both a fire-and-forget `generate` and a `generateAndWait` that
7
+ * polls to a terminal state for you.
8
+ */
9
+ import { errorFromResponse, GenerationFailedError, GenerationTimeoutError } from './errors.js';
10
+ const DEFAULT_BASE_URL = 'https://app.contenthero.ai';
11
+ const TERMINAL = new Set(['completed', 'failed']);
12
+ export class ContentHero {
13
+ apiKey;
14
+ baseUrl;
15
+ fetchImpl;
16
+ constructor(options = {}) {
17
+ const apiKey = options.apiKey ?? readEnv('CONTENTHERO_API_KEY');
18
+ if (!apiKey) {
19
+ throw new Error('A ContentHero API key is required. Pass { apiKey } or set CONTENTHERO_API_KEY.');
20
+ }
21
+ const fetchImpl = options.fetch ?? globalThis.fetch;
22
+ if (!fetchImpl) {
23
+ throw new Error('No fetch implementation found. Use Node 20+ or pass a custom fetch via { fetch }.');
24
+ }
25
+ this.apiKey = apiKey;
26
+ this.baseUrl = (options.baseUrl ?? readEnv('CONTENTHERO_BASE_URL') ?? DEFAULT_BASE_URL).replace(/\/+$/, '');
27
+ this.fetchImpl = fetchImpl;
28
+ }
29
+ /**
30
+ * Submit a generation. Returns immediately. For image/video the result is
31
+ * `status: 'processing'` (poll with `getGeneration` or use `generateAndWait`);
32
+ * audio returns `status: 'completed'` with `outputUrls` populated.
33
+ */
34
+ async generate(request) {
35
+ return this.request('POST', '/api/v1/studio/generate', request);
36
+ }
37
+ /** Fetch the current state of a generation by its id. */
38
+ async getGeneration(outputId) {
39
+ return this.request('GET', `/api/v1/studio/generate/${encodeURIComponent(outputId)}`);
40
+ }
41
+ /**
42
+ * Submit a generation and poll until it reaches a terminal state. Resolves
43
+ * with the completed `Generation`, throws `GenerationFailedError` if it fails,
44
+ * or `GenerationTimeoutError` if it does not finish within `timeoutMs` (the
45
+ * server-side job may still complete; re-poll with `getGeneration`).
46
+ */
47
+ async generateAndWait(request, options = {}) {
48
+ const { pollIntervalMs = 3000, timeoutMs = 600_000, signal } = options;
49
+ const submitted = await this.generate(request);
50
+ const deadline = Date.now() + timeoutMs;
51
+ while (true) {
52
+ const generation = await this.getGeneration(submitted.outputId);
53
+ if (generation.status === 'completed')
54
+ return generation;
55
+ if (generation.status === 'failed') {
56
+ throw new GenerationFailedError(generation.outputId, generation.error ?? 'Generation failed');
57
+ }
58
+ if (Date.now() >= deadline) {
59
+ throw new GenerationTimeoutError(submitted.outputId);
60
+ }
61
+ await sleep(pollIntervalMs, signal);
62
+ }
63
+ }
64
+ /** Fetch the authenticated account's credit balance, tier, and auto-top-up state. */
65
+ async getBalance() {
66
+ return this.request('GET', '/api/v1/account/balance');
67
+ }
68
+ /**
69
+ * Transcribe an audio URL to text (ElevenLabs Scribe). Synchronous: the
70
+ * transcript comes back inline. Free (no credit charge).
71
+ */
72
+ async transcribe(request) {
73
+ return this.request('POST', '/api/v1/studio/transcribe', request);
74
+ }
75
+ /** List the account's avatars (the list half of the list+get pair). */
76
+ async listAvatars() {
77
+ const data = await this.request('GET', '/api/v1/avatars');
78
+ return data.avatars;
79
+ }
80
+ /** Get one avatar with its looks (the get half). Throws NotFoundError if absent. */
81
+ async getAvatar(avatarId) {
82
+ return this.request('GET', `/api/v1/avatars/${encodeURIComponent(avatarId)}`);
83
+ }
84
+ /** List the account's saved voices (the list half of the list+get pair). */
85
+ async listVoices() {
86
+ const data = await this.request('GET', '/api/v1/voices');
87
+ return data.voices;
88
+ }
89
+ /** Get one voice's detail (the get half). Throws NotFoundError if absent. */
90
+ async getVoice(voiceId) {
91
+ return this.request('GET', `/api/v1/voices/${encodeURIComponent(voiceId)}`);
92
+ }
93
+ /** List the account's brand kits (the list half of the list+get pair). */
94
+ async listBrandKits() {
95
+ const data = await this.request('GET', '/api/v1/brand-kits');
96
+ return data.brandKits;
97
+ }
98
+ /** Get one brand kit, fully assembled (the get half). Throws NotFoundError if absent. */
99
+ async getBrandKit(brandKitId) {
100
+ return this.request('GET', `/api/v1/brand-kits/${encodeURIComponent(brandKitId)}`);
101
+ }
102
+ /** List the account's recent studio outputs (the list half of the list+get pair). */
103
+ async listMedia(options = {}) {
104
+ const q = new URLSearchParams();
105
+ if (options.contentType) {
106
+ const types = Array.isArray(options.contentType) ? options.contentType : [options.contentType];
107
+ q.set('contentType', types.join(','));
108
+ }
109
+ if (options.status)
110
+ q.set('status', options.status);
111
+ if (options.limit != null)
112
+ q.set('limit', String(options.limit));
113
+ if (options.offset != null)
114
+ q.set('offset', String(options.offset));
115
+ const qs = q.toString();
116
+ const data = await this.request('GET', `/api/v1/media${qs ? `?${qs}` : ''}`);
117
+ return data.media;
118
+ }
119
+ /**
120
+ * Get one studio output by id token (the get half). The token may be the full
121
+ * output id, its first 8 characters, or either with a `-N` variation suffix
122
+ * (1-based). Throws NotFoundError if absent.
123
+ */
124
+ async getMedia(idToken) {
125
+ return this.request('GET', `/api/v1/media/${encodeURIComponent(idToken)}`);
126
+ }
127
+ /**
128
+ * List the models available to this key (the discovery catalog): which models
129
+ * exist, their content type and operation kind, and their capability surface.
130
+ * The source of truth for building model selections instead of hardcoding ids.
131
+ */
132
+ async listModels(options = {}) {
133
+ const query = options.contentType ? `?contentType=${options.contentType}` : '';
134
+ const data = await this.request('GET', `/api/v1/models${query}`);
135
+ return data.models;
136
+ }
137
+ /** Issue an authenticated request and map non-2xx responses to typed errors. */
138
+ async request(method, path, body) {
139
+ const headers = {
140
+ Authorization: `Bearer ${this.apiKey}`,
141
+ Accept: 'application/json',
142
+ };
143
+ if (body !== undefined)
144
+ headers['Content-Type'] = 'application/json';
145
+ const response = await this.fetchImpl(`${this.baseUrl}${path}`, {
146
+ method,
147
+ headers,
148
+ body: body !== undefined ? JSON.stringify(body) : undefined,
149
+ });
150
+ const text = await response.text();
151
+ let data = undefined;
152
+ if (text) {
153
+ try {
154
+ data = JSON.parse(text);
155
+ }
156
+ catch {
157
+ data = text;
158
+ }
159
+ }
160
+ if (!response.ok) {
161
+ throw errorFromResponse(response.status, data);
162
+ }
163
+ return data;
164
+ }
165
+ }
166
+ /** Read an env var without assuming `process` exists (keeps non-Node bundles happy). */
167
+ function readEnv(name) {
168
+ const env = globalThis.process
169
+ ?.env;
170
+ return env?.[name];
171
+ }
172
+ /** Promise-based delay that rejects if the provided signal aborts. */
173
+ function sleep(ms, signal) {
174
+ return new Promise((resolve, reject) => {
175
+ if (signal?.aborted) {
176
+ reject(new Error('Aborted'));
177
+ return;
178
+ }
179
+ const timer = setTimeout(() => {
180
+ signal?.removeEventListener('abort', onAbort);
181
+ resolve();
182
+ }, ms);
183
+ const onAbort = () => {
184
+ clearTimeout(timer);
185
+ reject(new Error('Aborted'));
186
+ };
187
+ signal?.addEventListener('abort', onAbort, { once: true });
188
+ });
189
+ }
190
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Typed error hierarchy for the ContentHero SDK.
3
+ *
4
+ * Every non-2xx response from the API is mapped to one of these so callers can
5
+ * branch on `instanceof` rather than poking at status codes. `ContentHeroError`
6
+ * is the base; catch it to handle anything the SDK throws from a request.
7
+ */
8
+ export interface ContentHeroErrorOptions {
9
+ status?: number;
10
+ /** The parsed response body (object or string), when there was one. */
11
+ body?: unknown;
12
+ }
13
+ /** Base class for every error thrown by the SDK. */
14
+ export declare class ContentHeroError extends Error {
15
+ /** HTTP status code, when the error came from an API response. */
16
+ readonly status?: number;
17
+ /** The parsed response body, when available. */
18
+ readonly body?: unknown;
19
+ constructor(message: string, options?: ContentHeroErrorOptions);
20
+ }
21
+ /** 401: the API key is missing, malformed, revoked, or expired. */
22
+ export declare class AuthenticationError extends ContentHeroError {
23
+ constructor(message?: string, options?: ContentHeroErrorOptions);
24
+ }
25
+ /** 403: the key is valid but lacks the scope required for this operation. */
26
+ export declare class PermissionError extends ContentHeroError {
27
+ constructor(message?: string, options?: ContentHeroErrorOptions);
28
+ }
29
+ /** 400: the request was rejected as malformed or unsupported by the model. */
30
+ export declare class ValidationError extends ContentHeroError {
31
+ constructor(message?: string, options?: ContentHeroErrorOptions);
32
+ }
33
+ /** 404: the referenced generation does not exist (or is not owned by this key). */
34
+ export declare class NotFoundError extends ContentHeroError {
35
+ constructor(message?: string, options?: ContentHeroErrorOptions);
36
+ }
37
+ /**
38
+ * 402: the account does not have enough credits for the requested generation.
39
+ * Carries the current `balance` and the `required` amount when the API reports
40
+ * them, so callers can surface a precise top-up prompt.
41
+ */
42
+ export declare class InsufficientCreditsError extends ContentHeroError {
43
+ readonly balance?: number;
44
+ readonly required?: number;
45
+ constructor(message?: string, options?: ContentHeroErrorOptions & {
46
+ balance?: number;
47
+ required?: number;
48
+ });
49
+ }
50
+ /**
51
+ * 429: the API key exceeded its per-minute request limit. `retryAfter` is the
52
+ * suggested wait in seconds when the API reports it, so callers can back off
53
+ * before retrying.
54
+ */
55
+ export declare class RateLimitError extends ContentHeroError {
56
+ readonly retryAfter?: number;
57
+ constructor(message?: string, options?: ContentHeroErrorOptions & {
58
+ retryAfter?: number;
59
+ });
60
+ }
61
+ /**
62
+ * Thrown by `generateAndWait` when the generation reaches a terminal `failed`
63
+ * state. `outputId` lets the caller re-fetch the record for the error detail.
64
+ */
65
+ export declare class GenerationFailedError extends ContentHeroError {
66
+ readonly outputId: string;
67
+ constructor(outputId: string, message?: string, options?: ContentHeroErrorOptions);
68
+ }
69
+ /**
70
+ * Thrown by `generateAndWait` when the generation does not reach a terminal
71
+ * state before the configured timeout. The job may still complete server-side;
72
+ * `outputId` lets the caller keep polling with `getGeneration`.
73
+ */
74
+ export declare class GenerationTimeoutError extends ContentHeroError {
75
+ readonly outputId: string;
76
+ constructor(outputId: string, message?: string);
77
+ }
78
+ /** Map an HTTP status + parsed body onto the right typed error. */
79
+ export declare function errorFromResponse(status: number, body: unknown): ContentHeroError;
80
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,uBAAuB;IACtC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,uEAAuE;IACvE,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAED,oDAAoD;AACpD,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,kEAAkE;IAClE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,gDAAgD;IAChD,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAA;gBAEX,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,uBAAuB;CAQ/D;AAED,mEAAmE;AACnE,qBAAa,mBAAoB,SAAQ,gBAAgB;gBAC3C,OAAO,SAA0B,EAAE,OAAO,CAAC,EAAE,uBAAuB;CAIjF;AAED,6EAA6E;AAC7E,qBAAa,eAAgB,SAAQ,gBAAgB;gBACvC,OAAO,SAAsB,EAAE,OAAO,CAAC,EAAE,uBAAuB;CAI7E;AAED,8EAA8E;AAC9E,qBAAa,eAAgB,SAAQ,gBAAgB;gBACvC,OAAO,SAAoB,EAAE,OAAO,CAAC,EAAE,uBAAuB;CAI3E;AAED,mFAAmF;AACnF,qBAAa,aAAc,SAAQ,gBAAgB;gBACrC,OAAO,SAAc,EAAE,OAAO,CAAC,EAAE,uBAAuB;CAIrE;AAED;;;;GAIG;AACH,qBAAa,wBAAyB,SAAQ,gBAAgB;IAC5D,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;gBAGxB,OAAO,SAAyB,EAChC,OAAO,CAAC,EAAE,uBAAuB,GAAG;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE;CAO9E;AAED;;;;GAIG;AACH,qBAAa,cAAe,SAAQ,gBAAgB;IAClD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;gBAG1B,OAAO,SAAwB,EAC/B,OAAO,CAAC,EAAE,uBAAuB,GAAG;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE;CAM9D;AAED;;;GAGG;AACH,qBAAa,qBAAsB,SAAQ,gBAAgB;IACzD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;gBAEb,QAAQ,EAAE,MAAM,EAAE,OAAO,SAAsB,EAAE,OAAO,CAAC,EAAE,uBAAuB;CAK/F;AAED;;;;GAIG;AACH,qBAAa,sBAAuB,SAAQ,gBAAgB;IAC1D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;gBAEb,QAAQ,EAAE,MAAM,EAAE,OAAO,SAA+C;CAKrF;AAED,mEAAmE;AACnE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,gBAAgB,CA+BjF"}
package/dist/errors.js ADDED
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Typed error hierarchy for the ContentHero SDK.
3
+ *
4
+ * Every non-2xx response from the API is mapped to one of these so callers can
5
+ * branch on `instanceof` rather than poking at status codes. `ContentHeroError`
6
+ * is the base; catch it to handle anything the SDK throws from a request.
7
+ */
8
+ /** Base class for every error thrown by the SDK. */
9
+ export class ContentHeroError extends Error {
10
+ /** HTTP status code, when the error came from an API response. */
11
+ status;
12
+ /** The parsed response body, when available. */
13
+ body;
14
+ constructor(message, options) {
15
+ super(message);
16
+ this.name = 'ContentHeroError';
17
+ this.status = options?.status;
18
+ this.body = options?.body;
19
+ // Preserve the prototype chain when compiled down to ES targets.
20
+ Object.setPrototypeOf(this, new.target.prototype);
21
+ }
22
+ }
23
+ /** 401: the API key is missing, malformed, revoked, or expired. */
24
+ export class AuthenticationError extends ContentHeroError {
25
+ constructor(message = 'Authentication failed', options) {
26
+ super(message, options);
27
+ this.name = 'AuthenticationError';
28
+ }
29
+ }
30
+ /** 403: the key is valid but lacks the scope required for this operation. */
31
+ export class PermissionError extends ContentHeroError {
32
+ constructor(message = 'Permission denied', options) {
33
+ super(message, options);
34
+ this.name = 'PermissionError';
35
+ }
36
+ }
37
+ /** 400: the request was rejected as malformed or unsupported by the model. */
38
+ export class ValidationError extends ContentHeroError {
39
+ constructor(message = 'Invalid request', options) {
40
+ super(message, options);
41
+ this.name = 'ValidationError';
42
+ }
43
+ }
44
+ /** 404: the referenced generation does not exist (or is not owned by this key). */
45
+ export class NotFoundError extends ContentHeroError {
46
+ constructor(message = 'Not found', options) {
47
+ super(message, options);
48
+ this.name = 'NotFoundError';
49
+ }
50
+ }
51
+ /**
52
+ * 402: the account does not have enough credits for the requested generation.
53
+ * Carries the current `balance` and the `required` amount when the API reports
54
+ * them, so callers can surface a precise top-up prompt.
55
+ */
56
+ export class InsufficientCreditsError extends ContentHeroError {
57
+ balance;
58
+ required;
59
+ constructor(message = 'Insufficient credits', options) {
60
+ super(message, options);
61
+ this.name = 'InsufficientCreditsError';
62
+ this.balance = options?.balance;
63
+ this.required = options?.required;
64
+ }
65
+ }
66
+ /**
67
+ * 429: the API key exceeded its per-minute request limit. `retryAfter` is the
68
+ * suggested wait in seconds when the API reports it, so callers can back off
69
+ * before retrying.
70
+ */
71
+ export class RateLimitError extends ContentHeroError {
72
+ retryAfter;
73
+ constructor(message = 'Rate limit exceeded', options) {
74
+ super(message, options);
75
+ this.name = 'RateLimitError';
76
+ this.retryAfter = options?.retryAfter;
77
+ }
78
+ }
79
+ /**
80
+ * Thrown by `generateAndWait` when the generation reaches a terminal `failed`
81
+ * state. `outputId` lets the caller re-fetch the record for the error detail.
82
+ */
83
+ export class GenerationFailedError extends ContentHeroError {
84
+ outputId;
85
+ constructor(outputId, message = 'Generation failed', options) {
86
+ super(message, options);
87
+ this.name = 'GenerationFailedError';
88
+ this.outputId = outputId;
89
+ }
90
+ }
91
+ /**
92
+ * Thrown by `generateAndWait` when the generation does not reach a terminal
93
+ * state before the configured timeout. The job may still complete server-side;
94
+ * `outputId` lets the caller keep polling with `getGeneration`.
95
+ */
96
+ export class GenerationTimeoutError extends ContentHeroError {
97
+ outputId;
98
+ constructor(outputId, message = 'Timed out waiting for generation to finish') {
99
+ super(message);
100
+ this.name = 'GenerationTimeoutError';
101
+ this.outputId = outputId;
102
+ }
103
+ }
104
+ /** Map an HTTP status + parsed body onto the right typed error. */
105
+ export function errorFromResponse(status, body) {
106
+ const record = (body && typeof body === 'object' ? body : undefined);
107
+ const message = (record && typeof record.error === 'string' && record.error) ||
108
+ (typeof body === 'string' && body) ||
109
+ `Request failed with status ${status}`;
110
+ const options = { status, body };
111
+ switch (status) {
112
+ case 400:
113
+ return new ValidationError(message, options);
114
+ case 401:
115
+ return new AuthenticationError(message, options);
116
+ case 402:
117
+ return new InsufficientCreditsError(message, {
118
+ ...options,
119
+ balance: typeof record?.balance === 'number' ? record.balance : undefined,
120
+ required: typeof record?.required === 'number' ? record.required : undefined,
121
+ });
122
+ case 403:
123
+ return new PermissionError(message, options);
124
+ case 404:
125
+ return new NotFoundError(message, options);
126
+ case 429:
127
+ return new RateLimitError(message, {
128
+ ...options,
129
+ retryAfter: typeof record?.retryAfter === 'number' ? record.retryAfter : undefined,
130
+ });
131
+ default:
132
+ return new ContentHeroError(message, options);
133
+ }
134
+ }
135
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @contenthero/sdk
3
+ *
4
+ * Official SDK for the ContentHero Studio API: programmatic image, video, and
5
+ * audio generation. The shared kernel the ContentHero MCP and CLI sit on.
6
+ */
7
+ export { ContentHero } from './client.js';
8
+ export type { ContentHeroOptions, FetchLike } from './client.js';
9
+ export type { References, GenerateRequest, GenerateResult, Generation, GenerationStatus, Balance, SubscriptionTier, WaitOptions, ModelKind, ModelCapabilities, ModelInfo, TranscribeRequest, Transcription, AvatarSummary, AvatarLook, Avatar, VoiceSummary, Voice, BrandKitSummary, BrandKitAccount, BrandKitSection, BrandKitKnowledge, BrandKit, MediaType, MediaVariation, MediaSummary, MediaItem, ListMediaOptions, } from './types.js';
10
+ export { ContentHeroError, AuthenticationError, PermissionError, ValidationError, NotFoundError, InsufficientCreditsError, RateLimitError, GenerationFailedError, GenerationTimeoutError, } from './errors.js';
11
+ export type { ContentHeroErrorOptions } from './errors.js';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,YAAY,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAChE,YAAY,EACV,UAAU,EACV,eAAe,EACf,cAAc,EACd,UAAU,EACV,gBAAgB,EAChB,OAAO,EACP,gBAAgB,EAChB,WAAW,EACX,SAAS,EACT,iBAAiB,EACjB,SAAS,EACT,iBAAiB,EACjB,aAAa,EACb,aAAa,EACb,UAAU,EACV,MAAM,EACN,YAAY,EACZ,KAAK,EACL,eAAe,EACf,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,QAAQ,EACR,SAAS,EACT,cAAc,EACd,YAAY,EACZ,SAAS,EACT,gBAAgB,GACjB,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,aAAa,EACb,wBAAwB,EACxB,cAAc,EACd,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,aAAa,CAAA;AACpB,YAAY,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @contenthero/sdk
3
+ *
4
+ * Official SDK for the ContentHero Studio API: programmatic image, video, and
5
+ * audio generation. The shared kernel the ContentHero MCP and CLI sit on.
6
+ */
7
+ export { ContentHero } from './client.js';
8
+ export { ContentHeroError, AuthenticationError, PermissionError, ValidationError, NotFoundError, InsufficientCreditsError, RateLimitError, GenerationFailedError, GenerationTimeoutError, } from './errors.js';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAgCzC,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,aAAa,EACb,wBAAwB,EACxB,cAAc,EACd,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,aAAa,CAAA"}
@@ -0,0 +1,314 @@
1
+ /**
2
+ * Public request/response types for the ContentHero SDK.
3
+ *
4
+ * These mirror the server contract in the ContentHero app
5
+ * (lib/studio/v1-request.ts and the /api/v1 route responses). The request is a
6
+ * thin envelope: a typed core of universal fields, a `references` object, and a
7
+ * model-specific `parameters` passthrough for the long tail. Per-model
8
+ * capabilities (which models accept which fields) are validated server-side
9
+ * against the same registry that drives the Studio UI.
10
+ */
11
+ /**
12
+ * Reference inputs (image-to-image, video-to-video, frame conditioning).
13
+ *
14
+ * Every value may be either a media URL OR one of your own output ids, so you
15
+ * can chain generations: pass a previous generation's id and the server
16
+ * substitutes that output's URL (ownership-checked). The id may be the full
17
+ * output id, its first 8 characters, or either with a `-N` variation suffix
18
+ * (1-based), e.g. `"a1b2c3d4-2"`. Without a suffix the first variation is used.
19
+ */
20
+ export interface References {
21
+ /** Image references / image-to-image inputs (URL or output id). */
22
+ images?: string[];
23
+ /** Video references, e.g. video-to-video models (URL or output id). */
24
+ videos?: string[];
25
+ /** Audio references, e.g. lip-sync custom audio input (URL or output id). */
26
+ audio?: string[];
27
+ /** First frame for video models that accept one (URL or output id). */
28
+ startFrame?: string;
29
+ /** Last frame for video models that accept one (URL or output id). */
30
+ endFrame?: string;
31
+ }
32
+ /**
33
+ * A generation request. `modelId` is always required. For image/video the
34
+ * `prompt` and typed-core fields apply; for audio (ElevenLabs) the audio fields
35
+ * apply. Anything a specific model supports beyond the typed core can be passed
36
+ * through `parameters`.
37
+ */
38
+ export interface GenerateRequest {
39
+ /** Media kind. Optional: inferred from the model when omitted. */
40
+ contentType?: 'image' | 'video' | 'audio';
41
+ /** Model identifier, e.g. 'nano-banana-2'. Required. */
42
+ modelId: string;
43
+ /** Text prompt. Required for image/video and for music/sfx audio. */
44
+ prompt?: string;
45
+ aspectRatio?: string;
46
+ resolution?: string;
47
+ /** Quality mode for models that expose it separately (e.g. GPT Image). */
48
+ quality?: string;
49
+ /** Number of images to produce (image models). */
50
+ numImages?: number;
51
+ /** Number of variations to produce (video models). */
52
+ numGenerations?: number;
53
+ /** Clip duration in seconds (video models). */
54
+ duration?: number;
55
+ /** Enable generated audio on video models that support it. */
56
+ audioEnabled?: boolean;
57
+ negativePrompt?: string;
58
+ seed?: number;
59
+ /** Upscale factor for upscale models, e.g. "2x", "4x" (validated per model). */
60
+ upscaleFactor?: string;
61
+ references?: References;
62
+ /** Model-specific parameters passed through to the provider (long tail). */
63
+ parameters?: Record<string, unknown>;
64
+ /** Text to speak (text-to-speech). */
65
+ text?: string;
66
+ /** ElevenLabs voice id (text-to-speech). */
67
+ voiceId?: string;
68
+ /** Human-readable voice name, stored for display (text-to-speech). */
69
+ voiceName?: string;
70
+ /** Duration in seconds (music / sound effects). */
71
+ durationSeconds?: number;
72
+ /** How literally to follow the prompt, 0.0 to 1.0 (sound effects). */
73
+ promptInfluence?: number;
74
+ /**
75
+ * Optional client-chosen id for idempotency. Must be a UUID; it becomes the
76
+ * generation's id. Re-submitting with the same id returns the existing job
77
+ * instead of starting (and charging for) another, so retries are safe. You
78
+ * also know the id up front and can poll `getGeneration` immediately.
79
+ */
80
+ outputId?: string;
81
+ }
82
+ /** Lifecycle state of a generation. */
83
+ export type GenerationStatus = 'pending' | 'processing' | 'completed' | 'failed';
84
+ /**
85
+ * Result of submitting a generation. Image/video return `status: 'processing'`
86
+ * (poll with `getGeneration`, or use `generateAndWait`). Audio is synchronous
87
+ * and returns `status: 'completed'` with `outputUrls` already populated.
88
+ */
89
+ export interface GenerateResult {
90
+ outputId: string;
91
+ status: 'processing' | 'completed';
92
+ /** Estimated credit cost computed server-side. */
93
+ creditsEstimate?: number;
94
+ /** Present when the result is already complete (audio). */
95
+ outputUrls?: string[];
96
+ /** True when a client-supplied `outputId` matched an existing job (no new work was started). */
97
+ idempotentReplay?: boolean;
98
+ }
99
+ /** A generation record as returned by `getGeneration` and `generateAndWait`. */
100
+ export interface Generation {
101
+ outputId: string;
102
+ status: GenerationStatus;
103
+ contentType: 'image' | 'video' | 'audio';
104
+ modelId: string;
105
+ /** Output asset URLs. Empty until the generation completes. */
106
+ outputUrls: string[];
107
+ /** Error detail when `status` is 'failed', otherwise null. */
108
+ error: string | null;
109
+ createdAt: string;
110
+ completedAt: string | null;
111
+ }
112
+ /** Subscription tiers the API normalizes balances against. */
113
+ export type SubscriptionTier = 'mortal' | 'hero' | 'champion' | 'legend';
114
+ /** Account credit standing as returned by `getBalance`. */
115
+ export interface Balance {
116
+ balance: number;
117
+ tier: SubscriptionTier;
118
+ autoTopupEnabled: boolean;
119
+ }
120
+ /** Options for `generateAndWait`'s polling behavior. */
121
+ export interface WaitOptions {
122
+ /** Milliseconds between status polls. Default 3000. */
123
+ pollIntervalMs?: number;
124
+ /** Give up after this many milliseconds. Default 600000 (10 minutes). */
125
+ timeoutMs?: number;
126
+ /** Abort the wait (does not cancel the server-side job). */
127
+ signal?: AbortSignal;
128
+ }
129
+ /** Request to transcribe an audio URL to text. */
130
+ export interface TranscribeRequest {
131
+ /** Public URL of the audio to transcribe. */
132
+ audioUrl: string;
133
+ /** Optional ISO language hint (e.g. "en"); auto-detected when omitted. */
134
+ languageCode?: string;
135
+ /** Label each speaker (diarization). */
136
+ diarize?: boolean;
137
+ }
138
+ /** Result of transcribing audio. Synchronous (no polling). */
139
+ export interface Transcription {
140
+ outputId: string;
141
+ transcript: string;
142
+ language: string;
143
+ wordCount: number;
144
+ /** Source audio length in seconds, when known. */
145
+ durationSeconds: number | null;
146
+ }
147
+ /** An avatar as returned by `listAvatars` (the list projection). */
148
+ export interface AvatarSummary {
149
+ id: string;
150
+ name: string;
151
+ /** The avatar's base image (profile photo); the default look for lip-sync. */
152
+ imageUrl: string | null;
153
+ defaultVoiceId: string | null;
154
+ isDefault: boolean;
155
+ status: string;
156
+ }
157
+ /** An outfit/look variation of an avatar. */
158
+ export interface AvatarLook {
159
+ id: string;
160
+ name: string | null;
161
+ imageUrl: string | null;
162
+ lookType: string | null;
163
+ isDefault: boolean;
164
+ }
165
+ /** Full avatar detail as returned by `getAvatar`. */
166
+ export interface Avatar extends AvatarSummary {
167
+ description: string | null;
168
+ age: string | null;
169
+ gender: string | null;
170
+ ethnicity: string | null;
171
+ niche: string[];
172
+ createdAt: string | null;
173
+ looks: AvatarLook[];
174
+ }
175
+ /** A voice as returned by `listVoices` (the list projection). */
176
+ export interface VoiceSummary {
177
+ voiceId: string;
178
+ name: string | null;
179
+ provider: string | null;
180
+ isFavorited: boolean;
181
+ previewUrl: string | null;
182
+ lastUsedAt: string | null;
183
+ }
184
+ /** Full voice detail as returned by `getVoice`. */
185
+ export interface Voice extends VoiceSummary {
186
+ accent: string | null;
187
+ language: string | null;
188
+ gender: string | null;
189
+ age: string | null;
190
+ description: string | null;
191
+ useCase: string | null;
192
+ }
193
+ /** A brand kit as returned by `listBrandKits` (the list projection). */
194
+ export interface BrandKitSummary {
195
+ id: string;
196
+ name: string;
197
+ businessName: string | null;
198
+ nicheDefinition: string | null;
199
+ isDefault: boolean;
200
+ isActive: boolean;
201
+ isFavorited: boolean;
202
+ isArchived: boolean;
203
+ createdAt: string | null;
204
+ }
205
+ /** A brand/inspiration account linked to a brand kit. */
206
+ export interface BrandKitAccount {
207
+ platform: string | null;
208
+ name: string | null;
209
+ handle: string | null;
210
+ avatarUrl: string | null;
211
+ followerCount: number | null;
212
+ }
213
+ /** A curated section of a brand kit (overview / voice tabs). */
214
+ export interface BrandKitSection {
215
+ tab: string;
216
+ sectionName: string;
217
+ sortOrder: number;
218
+ /** Field objects: { key, label, type, value }. */
219
+ fields: unknown[];
220
+ }
221
+ /** A knowledge-base item (body truncated to a preview). */
222
+ export interface BrandKitKnowledge {
223
+ id: string;
224
+ title: string | null;
225
+ sourceType: string | null;
226
+ sourceUrl: string | null;
227
+ contentPreview: string | null;
228
+ }
229
+ /** Full brand kit as returned by `getBrandKit` (the whole document). */
230
+ export interface BrandKit extends BrandKitSummary {
231
+ websiteUrl: string | null;
232
+ sourceType: string | null;
233
+ primaryOffer: string | null;
234
+ positioning: Record<string, unknown> | null;
235
+ audience: Record<string, unknown> | null;
236
+ voiceProfile: Record<string, unknown> | null;
237
+ logos: unknown[];
238
+ brandColors: unknown[];
239
+ typography: Record<string, unknown> | null;
240
+ visualStyle: string | null;
241
+ designPrinciples: string[];
242
+ socialAccounts: unknown[];
243
+ contentStrategy: Record<string, unknown> | null;
244
+ assets: unknown[];
245
+ sections: BrandKitSection[];
246
+ brandAccounts: BrandKitAccount[];
247
+ inspirationAccounts: BrandKitAccount[];
248
+ knowledge: BrandKitKnowledge[];
249
+ }
250
+ /** A studio output's media kind. */
251
+ export type MediaType = 'image' | 'video' | 'audio' | 'transcript';
252
+ /** One variation (slot) of a studio output. */
253
+ export interface MediaVariation {
254
+ /** 1-based variation number (matches the UI and a share link's ?v=N). */
255
+ variation: number;
256
+ url: string | null;
257
+ status: string;
258
+ isFavorited: boolean;
259
+ }
260
+ /** A studio output as returned by `listMedia` (the list projection). */
261
+ export interface MediaSummary {
262
+ id: string;
263
+ type: MediaType;
264
+ model: string | null;
265
+ prompt: string | null;
266
+ status: string;
267
+ createdAt: string | null;
268
+ variationCount: number;
269
+ /** Resolved (non-null) variation URLs. */
270
+ urls: string[];
271
+ }
272
+ /** Full studio output detail as returned by `getMedia`. */
273
+ export interface MediaItem extends MediaSummary {
274
+ script: string | null;
275
+ aspectRatio: string | null;
276
+ resolution: string | null;
277
+ duration: number | null;
278
+ creditsUsed: number | null;
279
+ variations: MediaVariation[];
280
+ /** Set when the requested token addressed a single variation; else null. */
281
+ selectedVariation: number | null;
282
+ }
283
+ /** Options for `listMedia`. */
284
+ export interface ListMediaOptions {
285
+ contentType?: MediaType | MediaType[];
286
+ status?: string;
287
+ limit?: number;
288
+ offset?: number;
289
+ }
290
+ /** The operation a model performs within its content type. */
291
+ export type ModelKind = 'generate' | 'upscale' | 'lip-sync' | 'voice';
292
+ /**
293
+ * A model's capability surface, as advertised by the discovery endpoint. Typed
294
+ * loosely (an index signature for the long tail) because the full contract is
295
+ * validated server-side; the fields below are the stable ones clients reason
296
+ * about.
297
+ */
298
+ export interface ModelCapabilities {
299
+ kind: ModelKind;
300
+ outputType: 'image' | 'video' | 'audio' | 'text' | 'voice';
301
+ promptMode: 'required' | 'optional' | 'none';
302
+ [key: string]: unknown;
303
+ }
304
+ /** A model in the discovery catalog returned by `listModels`. */
305
+ export interface ModelInfo {
306
+ modelId: string;
307
+ displayName: string;
308
+ description: string | null;
309
+ contentType: 'image' | 'video' | 'audio';
310
+ kind: ModelKind;
311
+ tags: string[];
312
+ capabilities: ModelCapabilities;
313
+ }
314
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Public request/response types for the ContentHero SDK.
3
+ *
4
+ * These mirror the server contract in the ContentHero app
5
+ * (lib/studio/v1-request.ts and the /api/v1 route responses). The request is a
6
+ * thin envelope: a typed core of universal fields, a `references` object, and a
7
+ * model-specific `parameters` passthrough for the long tail. Per-model
8
+ * capabilities (which models accept which fields) are validated server-side
9
+ * against the same registry that drives the Studio UI.
10
+ */
11
+ export {};
12
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG"}
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@contenthero/sdk",
3
+ "version": "0.1.0",
4
+ "description": "Official ContentHero SDK. Programmatic media generation (image, video, audio) on the ContentHero Studio API. The shared kernel the ContentHero MCP and CLI sit on.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "README.md"
17
+ ],
18
+ "scripts": {
19
+ "build": "tsc",
20
+ "clean": "rm -rf dist",
21
+ "test": "tsx --test \"src/**/*.test.ts\"",
22
+ "prepublishOnly": "npm run clean && npm run build"
23
+ },
24
+ "publishConfig": {
25
+ "access": "public"
26
+ },
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "git+https://github.com/contenthero-ai/contenthero-packages.git",
30
+ "directory": "packages/sdk"
31
+ },
32
+ "keywords": [
33
+ "contenthero",
34
+ "ai",
35
+ "image-generation",
36
+ "video-generation",
37
+ "text-to-speech",
38
+ "generative-media",
39
+ "sdk"
40
+ ],
41
+ "engines": {
42
+ "node": ">=20"
43
+ },
44
+ "license": "MIT",
45
+ "private": false,
46
+ "devDependencies": {
47
+ "@types/node": "^22.19.19",
48
+ "tsx": "^4.22.3"
49
+ }
50
+ }