Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/DecartAI/sdk/llms.txt

Use this file to discover all available pages before exploring further.

The Decart AI SDK works in any JavaScript runtime, including Node.js, Bun, Deno, and edge runtimes like Cloudflare Workers. This guide shows server-side usage patterns.

Installation

npm install @decartai/sdk

When to Use Server-Side

Use the SDK server-side for:
  • Securing your API key - Keep credentials out of client code
  • Image/video generation APIs - Build REST endpoints for generation
  • Token generation - Create client tokens for real-time features
  • Batch processing - Process multiple requests efficiently
  • Edge functions - Deploy globally on edge runtimes

Express API Example

Here’s a complete Express server with image and video generation endpoints:
import "dotenv/config";
import express from "express";
import { createDecartClient, models } from "@decartai/sdk";

const app = express();
app.use(express.json());

const client = createDecartClient({
  apiKey: process.env.DECART_API_KEY!,
});

// Generate image from text (sync - returns immediately)
app.post("/api/image/generate", async (req, res) => {
  try {
    const { prompt } = req.body;

    const blob = await client.process({
      model: models.image("lucy-pro-t2i"),
      prompt,
    });

    const buffer = Buffer.from(await blob.arrayBuffer());
    res.setHeader("Content-Type", "image/png");
    res.send(buffer);
  } catch (error) {
    res.status(500).json({ error: String(error) });
  }
});

// Transform image (sync - returns immediately)
app.post("/api/image/transform", async (req, res) => {
  try {
    const { prompt, imageUrl } = req.body;

    const blob = await client.process({
      model: models.image("lucy-pro-i2i"),
      prompt,
      data: imageUrl,
    });

    const buffer = Buffer.from(await blob.arrayBuffer());
    res.setHeader("Content-Type", "image/png");
    res.send(buffer);
  } catch (error) {
    res.status(500).json({ error: String(error) });
  }
});

// Submit video generation job (async - returns job ID)
app.post("/api/video/generate", async (req, res) => {
  try {
    const { prompt } = req.body;

    const job = await client.queue.submit({
      model: models.video("lucy-pro-t2v"),
      prompt,
    });

    res.json({ jobId: job.job_id, status: job.status });
  } catch (error) {
    res.status(500).json({ error: String(error) });
  }
});

// Check video job status
app.get("/api/video/status/:jobId", async (req, res) => {
  try {
    const status = await client.queue.status(req.params.jobId);
    res.json(status);
  } catch (error) {
    res.status(500).json({ error: String(error) });
  }
});

// Get video result (when completed)
app.get("/api/video/result/:jobId", async (req, res) => {
  try {
    const blob = await client.queue.result(req.params.jobId);
    const buffer = Buffer.from(await blob.arrayBuffer());
    res.setHeader("Content-Type", "video/mp4");
    res.send(buffer);
  } catch (error) {
    res.status(500).json({ error: String(error) });
  }
});

// Generate video with automatic polling (convenience endpoint)
app.post("/api/video/generate-sync", async (req, res) => {
  try {
    const { prompt, videoUrl } = req.body;

    const result = await client.queue.submitAndPoll({
      model: videoUrl ? models.video("lucy-pro-v2v") : models.video("lucy-pro-t2v"),
      prompt,
      ...(videoUrl && { data: videoUrl }),
    });

    if (result.status === "completed") {
      const buffer = Buffer.from(await result.data.arrayBuffer());
      res.setHeader("Content-Type", "video/mp4");
      res.send(buffer);
    } else {
      res.status(500).json({ error: result.error });
    }
  } catch (error) {
    res.status(500).json({ error: String(error) });
  }
});

const port = process.env.PORT || 3000;
app.listen(port, () => {
  console.log(`Server running at http://localhost:${port}`);
});

Hono Edge Runtime Example

Hono works great for edge runtimes like Cloudflare Workers:
import { createDecartClient, type DecartClient, models } from "@decartai/sdk";
import { Hono } from "hono";

type Bindings = {
  DECART_API_KEY: string;
};

type Variables = {
  decart: DecartClient;
};

const app = new Hono<{ Bindings: Bindings; Variables: Variables }>();

// Middleware to create and share the Decart client
app.use("*", async (c, next) => {
  const client = createDecartClient({
    apiKey: c.env.DECART_API_KEY,
  });
  c.set("decart", client);
  await next();
});

// Text-to-image generation
app.post("/api/image/generate", async (c) => {
  const client = c.get("decart");
  const { prompt } = await c.req.json<{ prompt: string }>();

  const blob = await client.process({
    model: models.image("lucy-pro-t2i"),
    prompt,
  });

  return new Response(blob, {
    headers: { "Content-Type": "image/png" },
  });
});

// Submit video generation job (async)
app.post("/api/video/generate", async (c) => {
  const client = c.get("decart");
  const { prompt } = await c.req.json<{ prompt: string }>();

  const job = await client.queue.submit({
    model: models.video("lucy-pro-t2v"),
    prompt,
  });

  return c.json({ jobId: job.job_id, status: job.status });
});

// Check video job status
app.get("/api/video/status/:jobId", async (c) => {
  const client = c.get("decart");
  const jobId = c.req.param("jobId");
  const status = await client.queue.status(jobId);

  return c.json(status);
});

// Get video result
app.get("/api/video/result/:jobId", async (c) => {
  const client = c.get("decart");
  const jobId = c.req.param("jobId");
  const blob = await client.queue.result(jobId);

  return new Response(blob, {
    headers: { "Content-Type": "video/mp4" },
  });
});

export default app;

Next.js API Route Example

Create API routes in Next.js for server-side generation:
// app/api/image/generate/route.ts
import { createDecartClient, models } from "@decartai/sdk";
import { NextResponse } from "next/server";

export async function POST(request: Request) {
  try {
    const { prompt } = await request.json();

    const client = createDecartClient({
      apiKey: process.env.DECART_API_KEY!,
    });

    const blob = await client.process({
      model: models.image("lucy-pro-t2i"),
      prompt,
    });

    return new NextResponse(blob, {
      headers: { "Content-Type": "image/png" },
    });
  } catch (error) {
    return NextResponse.json(
      { error: String(error) },
      { status: 500 }
    );
  }
}

Token Generation for Real-Time

Generate client tokens for real-time video streaming:
import { createDecartClient } from "@decartai/sdk";

export async function POST() {
  const client = createDecartClient({
    apiKey: process.env.DECART_API_KEY!,
  });

  const token = await client.tokens.create();
  return Response.json(token);
}
The client can then use this token:
// Client-side
const response = await fetch("/api/realtime-token", { method: "POST" });
const { apiKey } = await response.json();

const client = createDecartClient({ apiKey });

Working with Blobs

The SDK returns Blob objects. Here’s how to handle them in different contexts:

Node.js (Buffer)

const blob = await client.process({ model, prompt });
const buffer = Buffer.from(await blob.arrayBuffer());
res.setHeader("Content-Type", "image/png");
res.send(buffer);

Edge Runtime (Response)

const blob = await client.process({ model, prompt });
return new Response(blob, {
  headers: { "Content-Type": "image/png" },
});

Save to File (Node.js)

import { writeFile } from "fs/promises";

const blob = await client.process({ model, prompt });
const buffer = Buffer.from(await blob.arrayBuffer());
await writeFile("output.png", buffer);

Environment Variables

Create a .env file:
DECART_API_KEY=your_api_key_here
Load it in your application:
import "dotenv/config";
// or
import { config } from "dotenv";
config();

Best Practices

  1. Reuse client instances - Create one client and reuse it across requests
  2. Use environment variables - Never hardcode API keys
  3. Handle errors properly - Return appropriate HTTP status codes
  4. Set correct Content-Type - Use image/png or video/mp4 headers
  5. Use queue API for videos - Video generation is async, use submit() and status()
  6. Consider timeouts - Set appropriate timeouts for long-running operations

Runtime Compatibility

The SDK works in:
  • Node.js (v18+)
  • Bun
  • Deno
  • Cloudflare Workers
  • Vercel Edge Functions
  • Netlify Edge Functions

Next Steps

Build docs developers (and LLMs) love