Giselle SDK
Learn how to use the Giselle SDK to integrate your apps with external applications and services.
This feature is currently in Private Preview. Access is limited to selected users. Features and APIs may change without notice.
Overview
The Giselle SDK (@giselles-ai/sdk) provides a simple, type-safe way to interact with the Giselle API from your Node.js applications. It handles authentication, request formatting, and polling for task completion automatically.
The SDK is designed for server-side use only. Never use it in client-side code (browsers) as this would expose your API key.
Installation
The Giselle SDK is published on npm at @giselles-ai/sdk.
Install the SDK using your preferred package manager:
npm install @giselles-ai/sdkyarn add @giselles-ai/sdkpnpm add @giselles-ai/sdkQuick Start
import Giselle from "@giselles-ai/sdk";
// Initialize the client
const client = new Giselle({
apiKey: process.env.GISELLE_API_KEY,
});
// Run an app and wait for results
const { task } = await client.apps.runAndWait({
appId: "app_xxxxx",
input: { text: "Hello, Giselle!" },
});
console.log(task.status); // "completed"
console.log(task.outputs); // Array of output resultsConfiguration
Constructor Options
const client = new Giselle({
apiKey: string; // Required: Your API key
baseUrl?: string; // Optional: API base URL (default: "https://studio.giselles.ai")
fetch?: typeof fetch; // Optional: Custom fetch implementation
});| Option | Required | Default | Description |
|---|---|---|---|
apiKey | Yes | - | Your Giselle API key. Get one from API Keys settings. |
baseUrl | No | https://studio.giselles.ai | The base URL for API requests. |
fetch | No | Global fetch | Custom fetch implementation for specific runtime environments. |
Environment Variables
We recommend storing your API key in an environment variable:
# .env
GISELLE_API_KEY=gsk_your_api_key_hereconst client = new Giselle({
apiKey: process.env.GISELLE_API_KEY,
});Never commit API keys to version control. Use environment variables or a secrets manager.
API Reference
client.apps.run()
Starts an app execution and returns immediately with a task ID. Use this when you want to handle polling yourself or don't need to wait for results.
const { taskId } = await client.apps.run({
appId: "app_xxxxx",
input: { text: "Your input text" },
});
console.log(taskId); // "tsk_xxxxx"Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
appId | string | Yes | The ID of the app to run (format: app_xxxxx) |
input.text | string | Yes | The text input for the app |
Returns:
{
taskId: string; // The ID of the created task
}client.apps.runAndWait()
Starts an app execution and polls until the task completes. This is the recommended method for most use cases.
const { task } = await client.apps.runAndWait({
appId: "app_xxxxx",
input: { text: "Your input text" },
pollIntervalMs: 1000, // Optional: polling interval (default: 1000ms)
timeoutMs: 60000, // Optional: timeout (default: 1200000ms / 20 minutes)
});Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
appId | string | Yes | - | The ID of the app to run |
input.text | string | Yes | - | The text input for the app |
pollIntervalMs | number | No | 1000 | How often to check for completion (ms) |
timeoutMs | number | No | 1200000 | Maximum time to wait (ms) |
schema | StandardSchemaV1 | No | - | Validation schema for the output. Standard Schema v1 compatible (Zod, Valibot, etc.). Only applied when the End Node has JSON (Structured Output) configured. |
Returns:
The task type in the return value differs depending on the End Node's Output Format setting.
Raw (passthrough):
{
task: {
id: string;
workspaceId: string;
name: string;
status: "completed" | "failed" | "cancelled";
outputType: "passthrough";
steps: Array<{
title: string;
status: string;
items: Array<{
id: string;
title: string;
status: string;
generationId: string;
outputs?: unknown[];
error?: string;
}>;
}>;
outputs: Array<{
title: string;
generationId: string;
outputs: unknown[];
}>;
};
}JSON (object):
{
task: {
id: string;
workspaceId: string;
name: string;
status: "completed" | "failed" | "cancelled";
outputType: "object";
output: T; // Typed by schema if provided, otherwise Record<string, unknown>
steps: Array<{
title: string;
status: string;
items: Array<{
id: string;
title: string;
status: string;
generationId: string;
outputs?: unknown[];
error?: string;
}>;
}>;
};
}Finding Your App ID and Code Snippet
The easiest way to get your App ID and a ready-to-use code snippet is from the Workspace:
- Open your app in the Workspace
- Click the Run button in the top-right corner
- In the dialog that appears, select the Code tab
- You'll see a complete code snippet with your
appIdalready filled in. Simply copy this code and use it in your application. - If the End Node has JSON (Structured Output) enabled, the Code tab also displays a code snippet with schema definitions and a preview of the Response JSON structure
The App ID format is app_ followed by a unique identifier (e.g., app_abc123xyz).
Error Handling
The SDK throws specific error types for different failure scenarios:
import Giselle, {
ConfigurationError,
ApiError,
TimeoutError,
UnsupportedFeatureError,
SchemaValidationError,
} from "@giselles-ai/sdk";
try {
const { task } = await client.apps.runAndWait({
appId: "app_xxxxx",
input: { text: "Hello" },
});
} catch (error) {
if (error instanceof ConfigurationError) {
// Missing or invalid configuration (e.g., no API key)
console.error("Configuration error:", error.message);
} else if (error instanceof ApiError) {
// API request failed
console.error("API error:", error.status, error.responseText);
} else if (error instanceof TimeoutError) {
// Task didn't complete within the timeout
console.error("Task timed out:", error.message);
} else if (error instanceof UnsupportedFeatureError) {
// Attempted to use an unsupported feature
console.error("Unsupported feature:", error.message);
} else if (error instanceof SchemaValidationError) {
// Schema validation failed
console.error("Schema validation error:", error.message);
}
}Error Types
| Error Type | Description |
|---|---|
ConfigurationError | Missing or invalid configuration (e.g., API key not provided) |
ApiError | HTTP request to the API failed. Includes status and responseText properties. |
TimeoutError | Task didn't complete within the specified timeout |
UnsupportedFeatureError | Attempted to use a feature not yet supported (e.g., file inputs) |
SchemaValidationError | Schema validation failed for the output |
Examples
Basic Usage
import Giselle from "@giselles-ai/sdk";
const client = new Giselle({
apiKey: process.env.GISELLE_API_KEY,
});
async function runMyApp(userInput: string) {
const { task } = await client.apps.runAndWait({
appId: "app_xxxxx",
input: { text: userInput },
});
if (task.status === "completed") {
return task.outputs;
} else {
throw new Error(`Task failed: ${task.status}`);
}
}Receiving Structured Output
When the End Node has JSON (Structured Output) enabled, task.outputType === "object" and task.output contains the structured result.
Pass a Standard Schema v1 compatible schema to the schema parameter to automatically validate the output and get type inference.
Supported libraries: Zod (3.24+), Valibot (1.0+), ArkType (2.0+), Yup (1.7+), Effect Schema (3.13+)
import { z } from "zod";
const BlogCardSchema = z.object({
title: z.string(),
summary: z.string(),
tags: z.array(z.string()),
});
async function runMyAppWithStructuredOutput(userInput: string) {
const { task } = await client.apps.runAndWait({
appId: "app_xxxxx",
input: { text: userInput },
schema: BlogCardSchema,
});
if (task.status === "completed" && task.outputType === "object") {
// task.output is typed based on BlogCardSchema
return task.output;
}
throw new Error(`Task failed: ${task.status}`);
}With Custom Timeout
const { task } = await client.apps.runAndWait({
appId: "app_xxxxx",
input: { text: "Complex query that may take time" },
timeoutMs: 300000, // 5 minutes
pollIntervalMs: 2000, // Check every 2 seconds
});Fire and Forget
// Start the task but don't wait for completion
const { taskId } = await client.apps.run({
appId: "app_xxxxx",
input: { text: "Background processing" },
});
console.log(`Task started: ${taskId}`);
// You can check the task status later via the API or in the GiselleExpress.js Integration
import express from "express";
import Giselle from "@giselles-ai/sdk";
const app = express();
const client = new Giselle({
apiKey: process.env.GISELLE_API_KEY,
});
app.use(express.json());
app.post("/api/process", async (req, res) => {
try {
const { task } = await client.apps.runAndWait({
appId: "app_xxxxx",
input: { text: req.body.text },
timeoutMs: 60000,
});
res.json({
success: true,
outputs: task.outputs,
});
} catch (error) {
res.status(500).json({
success: false,
error: error.message,
});
}
});
app.listen(3000);Current Limitations
- Text input only: Currently, only text input is supported. File inputs will be supported in a future release.
- Server-side only: The SDK should only be used in server-side environments to protect your API key.
Next Steps
- Create an API key to get started
- Test your apps in the Playground before integrating
- Check out Cookbooks for example apps and workflows