Domo AI API Integration Tutorial

Want to generate Domo AI videos automatically inside your own app? This guide shows how to integrate the Domo AI API step by step create text-to-video or image-to-video tasks, track progress with task IDs (polling or webhooks), and return finished video URLs in a clean, production ready workflow.

Business Innovation

Domo AI API Integration Tutorial (Step-by-Step) - 2026 Developer Guide

This tutorial shows how to integrate the DomoAI Enterprise API into your app or backend to generate videos programmatically using:

  • Text → Video (POST /v1/video/text2video)

  • Image → Video (POST /v1/video/image2video)

  • Template → Video (POST /v1/video/template2video)

  • Task status polling (GET /v1/tasks/{task_id})

  • Optional webhook callbacks (callback_url)

The official docs describe the base URL as https://api.domoai.app and API-key auth via Authorization: Bearer <YOUR_API_KEY>


1) How the Domo AI API works (the mental model)

DomoAI’s API is asynchronous:

  1. You send a request (text2video / image2video / template2video).

  2. The API returns a task_id immediately.

  3. You either:

    • Poll the task endpoint until status becomes SUCCESS, or

    • Provide a callback_url so Domo AI can notify your server when status changes.

  4. When complete, the task payload contains one or more output video URLs plus metadata like width/height and credit usage.


2) Prerequisites

What you need

  • A DomoAI Enterprise API account + API Key (created in the Dashboard → API Keys).

  • A backend environment (Node.js / Python / any language that can call HTTPS)

  • (Optional) A public HTTPS endpoint if you want webhook callbacks (callback_url)

Auth method

Every request uses:

  • Authorization: Bearer <YOUR_API_KEY>


3) Base URL + endpoints

Docs list the base URL as: 

  • https://api.domoai.app

Core endpoints:

  • POST /v1/video/text2video

  • POST /v1/video/image2video

  • POST /v1/video/template2video

  • GET /v1/tasks/{task_id}

Note: Some examples in the docs show api.domoai.com in curl snippets while the “Base URL” section says api.domoai.app. Use the base URL stated in the docs (api.domoai.app) unless your account documentation specifies otherwise.


4) Integration pattern options

Option A - Polling (simplest)

  • Best for: scripts, cron jobs, internal tools, small apps

  • Flow: Create task → poll GET /v1/tasks/{task_id} until finished

Option B - Webhook callback (callback_url) (most scalable)

  • Best for: production systems, queues, high volume

  • Flow: Create task with callback_url → DomoAI calls your endpoint when status changes (SUCCESS / FAILED)

The callback schema includes status, category, output_videos, credits, etc.


5) Quick Start: Text to Video with cURL

The docs provide a simple text-to-video request like this:

 
curl -X POST "https://api.domoai.app/v1/video/text2video" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer <YOUR_API_KEY>" \ -d '{ "prompt": "A beautiful sunrise over mountains with flowing clouds", "model": "v2-4-faster", "duration": 5 }'

Response returns a task id:

 
{ "data": { "task_id": "<YOUR_TASK_ID>" } }

Then check status:

 
curl -H "Authorization: Bearer <YOUR_API_KEY>" \ "https://api.domoai.app/v1/tasks/<YOUR_TASK_ID>"

6) A production-ready workflow (recommended)

Here’s a reliable pattern used in real systems:

  1. Receive request from your user (prompt or image).

  2. Create task in Domo AI.

  3. Store:

    • task_id

    • user_id / project_id

    • input metadata (prompt, template, etc.)

    • timestamps

  4. Either:

    • Start polling in a worker, or

    • Wait for webhook callback

  5. When SUCCESS:

    • Store output URL(s)

    • Trigger next step (download, transcode, publish, notify user)

DomoAI task statuses include PENDING, QUEUING, PROCESSING, SUCCESS, FAILED, CANCELED.


7) Text-to-Video API details (deep dive)

Endpoint

POST /v1/video/text2video

Key request fields (from docs)

  • prompt (required, 1–2000 chars)

  • seconds (required, 1–10)

  • model (default provided; options include t2v-2.4-faster, t2v-2.4-advanced)

  • Optional:

    • style (japanese_anime, realistic, pixel, cartoon_game, flat_color_anime, 90s_style)

    • aspect_ratio (16:9, 9:16, 1:1, 4:3, 3:4

    • callback_url for webhook delivery

Example request (9:16 YouTube Shorts / TikTok / Reels)

 
{ "prompt": "Anime-style close-up of a character smiling in soft sunlight, gentle breeze, cinematic, stable face, smooth motion", "model": "t2v-2.4-faster", "seconds": 5, "style": "japanese_anime", "aspect_ratio": "9:16", "callback_url": "https://yourdomain.com/webhooks/domoai" }

8) Image-to-Video API details (deep dive)

Endpoint

POST /v1/video/image2video

What’s different here?

You must send an image using an ImageInput object with base64 content (example is shown in docs). 

Key fields:

  • model required (animate-2.4-faster, animate-2.4-advanced)

  • image.bytes_base64_encoded required

  • seconds required (1–10)

  • Optional prompt (default empty string)

  • Optional aspect_ratio (if null, API may auto-detect based on image)

  • Optional callback_url

Converting an image file to base64

Most languages can do this quickly. The important part is: send raw bytes encoded as base64, not a data URL prefix.

Example shape:

 
{ "prompt": "subtle blink, gentle smile, smooth motion, stable face", "model": "animate-2.4-faster", "image": { "bytes_base64_encoded": "..." }, "seconds": 5, "aspect_ratio": "9:16" }

9) Template-to-Video API details (deep dive)

Endpoint

POST /v1/video/template2video

Templates are great when you want “viral” formats in your app quickly (e.g., zoom, loop, hug/kiss styles).

Fields:

  • template required — examples include:

    • kissing_screen, looping_animation, hug, groove_dance, kiss, french_kiss, 360_view, zoom_in, zoom_out, crane_up 

  • images required (array; docs note it currently supports only one image)

  • seconds required (1–10)

  • Optional prompt, aspect_ratio, callback_url

Example request:

 
{ "template": "zoom_in", "prompt": "cinematic zoom toward the subject, smooth motion", "images": [{ "bytes_base64_encoded": "..." }], "seconds": 5, "aspect_ratio": "9:16" }

10) Getting task results

Endpoint

GET /v1/tasks/{task_id}

The task response includes:

  • status (PENDING / QUEUING / PROCESSING / SUCCESS / FAILED / CANCELED)

  • category (TEXT_TO_VIDEO, IMAGE_TO_VIDEO, VIDEO_TO_VIDEO, TEMPLATE_TO_VIDEO)

  • output_videos array with url, width, height

  • credits consumed

  • created_at

When status is SUCCESS, you should be able to use the output_videos[*].url.


11) Webhooks (callback_url) - production best practice

If you include callback_url in a create request, DomoAI will POST updates to that URL when status changes.

Callback payload essentials

The callback protocol defines fields like:

  • task_id, status, category

  • output_videos, credits

  • inputs, created_at

What your webhook endpoint must do

A solid webhook handler should:

  1. Verify the request (see “Security tips” below)

  2. Parse JSON

  3. Look up your internal record by task_id

  4. If SUCCESS → store output URLs, mark job complete

  5. If FAILED → store error state, notify user

The docs specify callbacks are sent as POST JSON with Content-Type: application/json.


12) Full Node.js integration example (create → poll)

Below is a clean integration example you can adapt for Express, Next.js API routes, Cloudflare Workers, etc.

 
// domoai-client.js // Node 18+ recommended (built-in fetch) const DOMOAI_BASE = "https://api.domoai.app"; export async function createTextToVideo({ apiKey, prompt, seconds = 5, aspect_ratio = "9:16" }) { const res = await fetch(`${DOMOAI_BASE}/v1/video/text2video`, { method: "POST", headers: { "Content-Type": "application/json", "Authorization": `Bearer ${apiKey}`, }, body: JSON.stringify({ prompt, seconds, aspect_ratio, // model/style optional; set them if you want deterministic defaults model: "t2v-2.4-faster", style: "japanese_anime", }), }); if (!res.ok) { const text = await res.text(); throw new Error(`createTextToVideo failed: ${res.status} ${text}`); } const json = await res.json(); return json?.data?.task_id; } export async function getTask({ apiKey, taskId }) { const res = await fetch(`${DOMOAI_BASE}/v1/tasks/${taskId}`, { headers: { "Authorization": `Bearer ${apiKey}` }, }); if (!res.ok) { const text = await res.text(); throw new Error(`getTask failed: ${res.status} ${text}`); } return res.json(); } export async function waitForTask({ apiKey, taskId, timeoutMs = 180000, pollEveryMs = 2000 }) { const start = Date.now(); while (true) { if (Date.now() - start > timeoutMs) { throw new Error(`Timeout waiting for task ${taskId}`); } const task = await getTask({ apiKey, taskId }); const data = task?.data; const status = data?.status; if (status === "SUCCESS") { return data; } if (status === "FAILED" || status === "CANCELED") { throw new Error(`Task ${taskId} ended with status: ${status}`); } await new Promise(r => setTimeout(r, pollEveryMs)); } }

Usage:

 
import { createTextToVideo, waitForTask } from "./domoai-client.js"; const apiKey = process.env.DOMOAI_API_KEY; const taskId = await createTextToVideo({ apiKey, prompt: "A cozy anime cafe scene, warm lighting, steam rising from coffee, cinematic close-up, smooth motion", seconds: 5, aspect_ratio: "9:16", }); const result = await waitForTask({ apiKey, taskId }); console.log("Done:", result.output_videos);

This matches the official flow: create task → use task_id to query status.


13) Python integration example (image → video)

 
import base64 import json import requests DOMOAI_BASE = "https://api.domoai.app" def file_to_b64(path: str) -> str: with open(path, "rb") as f: return base64.b64encode(f.read()).decode("utf-8") def create_image_to_video(api_key: str, image_path: str, prompt: str = "", seconds: int = 5): payload = { "model": "animate-2.4-faster", "image": {"bytes_base64_encoded": file_to_b64(image_path)}, "seconds": seconds, "prompt": prompt, "aspect_ratio": "9:16" } r = requests.post( f"{DOMOAI_BASE}/v1/video/image2video", headers={"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}, data=json.dumps(payload), timeout=60, ) r.raise_for_status() return r.json()["data"]["task_id"] def get_task(api_key: str, task_id: str): r = requests.get( f"{DOMOAI_BASE}/v1/tasks/{task_id}", headers={"Authorization": f"Bearer {api_key}"}, timeout=30, ) r.raise_for_status() return r.json()["data"] # Example # api_key = "YOUR_KEY" # task_id = create_image_to_video(api_key, "portrait.jpg", "subtle blink, gentle smile, stable face") # print(get_task(api_key, task_id))

The request matches the docs: model, image.bytes_base64_encoded, seconds, optional prompt.


14) Error handling (common issues)

Docs list common quick start errors:

401 Unauthorized

  • Cause: invalid/revoked key or wrong Authorization header format

  • Fix: ensure Authorization: Bearer <YOUR_API_KEY> is correct

402 Payment Required

  • Cause: insufficient credits

  • Fix: check billing/credits in dashboard

422 Unprocessable Entity

  • Cause: request body didn’t match schema (bad seconds range, missing required field, wrong JSON shape)

  • Fix: validate payload (e.g., seconds range 1–10 is enforced)


15) Security tips (important for production)

Even though the API uses Bearer tokens, your integration still needs safe defaults:

  1. Never expose your API key in frontend code

    • Keep calls server-side only.

  2. Use a secrets manager

    • Environment variables are OK for small apps; secrets managers are better for production.

  3. Webhook safety

    • Put your callback endpoint behind HTTPS

    • Add a shared secret query param or custom header on your callback URL (and verify it)

    • Rate-limit your webhook endpoint

  4. Store minimal input data

    • Store only what you need (task_id, user_id, output URLs, timestamps)

The docs emphasize secure access per org via API keys.


16) How to design a “Domo AI generation” feature in your app

Here are three proven product patterns:

Pattern 1 - “Generate Shorts” button (text-to-video)

  • User enters prompt + selects style + aspect ratio

  • Backend calls text2video

  • Frontend shows progress via polling

  • Final: show download link + “Publish” CTA

Pattern 2 - “Animate this photo” (image-to-video)

  • User uploads image

  • Backend stores image (S3/R2) OR base64 encodes temporarily

  • Backend calls image2video

  • Final: add an “Upscale” option (post-processing step in your pipeline)

Pattern 3 - Viral templates

  • User selects template (zoom/loop/360/hug/kiss)

  • Backend calls template2video

  • Great for social apps and quick meme workflows

Template names like zoom_in, looping_animation, and 360_view are listed in the API reference.


17) Performance and scaling tips

When you scale beyond a handful of videos per day:

  • Use a job queue (BullMQ, RabbitMQ, SQS, etc.)

  • Run workers that:

    • create tasks

    • store task IDs

    • poll (or wait for callback) and update job records

  • Use callbacks when possible to reduce polling load

  • Make your UI resilient:

    • show “Queued / Processing / Done”

    • allow users to close the tab and come back later

The API is built around task management and callbacks for exactly this reason.