TypeScript SDK
The recommended way to call ThankYou from JavaScript and TypeScript
The TypeScript SDK is the recommended integration path for Node.js and TypeScript applications. It wraps the Open API with typed resources, model input types, file uploads, polling helpers, quotes, usage, LLM request history, and webhook verification.
npm install @thankyouai/sdkThe SDK supports both ESM and CommonJS on Node.js 18 and newer.
Create a client
import { ThankYou } from "@thankyouai/sdk";
const thankyou = new ThankYou({
apiKey: process.env.THANKYOU_API_KEY!,
});const { ThankYou } = require("@thankyouai/sdk");
const thankyou = new ThankYou({
apiKey: process.env.THANKYOU_API_KEY,
});The default base URL is https://api.thankyouai.com/open/v1.
REST endpoints remain fully supported. Use the SDK when you want typed model inputs, automatic polling helpers, and fewer hand-written request wrappers.
Generate and wait
const result = await thankyou.run({
model: "flux/v2/pro/text-to-image",
input: {
prompt: "A mountain landscape at golden hour",
aspect_ratio: "16:9",
},
});
console.log(result.output[0]?.url);thankyou.run() creates a generation and waits until it reaches a terminal status. Use thankyou.generations.create() and thankyou.generations.wait() separately when you want to control the polling loop.
Upload a reference image
const file = await thankyou.files.upload({
file: "./photo.jpg",
});
const result = await thankyou.run({
model: "google/nano-banana/edit",
input: {
prompt: "Keep the original composition, but render it as a polished 3D app icon",
reference_assets: [{ role: "reference", url: file.url }],
},
});
console.log(result.output[0]?.url);For video models that accept reference images, use the same files.upload() flow:
const file = await thankyou.files.upload({
file: "./style-frame.jpg",
});
const result = await thankyou.run({
model: "bytedance/seedance/v2/video",
input: {
prompt: "A cinematic slow push-in through a quiet glass greenhouse at sunrise",
reference_assets: [{ role: "reference", url: file.url }],
aspect_ratio: "16:9",
duration: 4,
resolution: "720p",
generate_audio: false,
},
});
console.log(result.output[0]?.url);Quote before execute
Use quotes when you need the estimated cost before starting a generation.
const quote = await thankyou.generations.quote({
model: "bytedance/seedance/v2/video",
input: {
prompt: "A koi fish swimming through a moonlit pond",
duration: 4,
resolution: "720p",
},
});
if (quote.blocking_reasons.length > 0) {
throw new Error(quote.blocking_reasons.join(", "));
}
console.log(quote.estimated_cost, quote.currency, quote.expires_at);
const generation = await thankyou.generations.create({
quoteId: quote.quote_id,
});Discover model input schemas
Model IDs can contain /, so the SDK uses GET /models/detail?model_id=... under the hood.
const models = await thankyou.models.list();
const detail = await thankyou.models.detail("google/nano-banana/edit");
console.log(models.models.length);
console.log(detail.input_schema);Use models.detail() as the source of truth for a model's supported input fields and reference_assets[].role values.
Webhook verification
const event = thankyou.webhooks.verify({
rawBody,
signature: request.headers["x-thankyou-signature"],
timestamp: request.headers["x-thankyou-timestamp"],
secret: process.env.THANKYOU_WEBHOOK_SECRET!,
});
if (event.event === "generation.completed") {
console.log(event.generation?.output[0]?.url);
}