txtovid API v1
Generate AI videos programmatically with the same models that power the txtovid generator — HappyHorse 1.1 and Wan 2.7: text-to-video, image-to-video, reference-images-to-video and AI video editing. Transparent per-second pricing — you are only charged for successful generations (failures are refunded automatically).
Create keys under Settings → API keys · every request appears under Settings → API activity and in My Generations.
Pass your key in the Authorization header of every request: Authorization: Bearer txtovid_sk_…. Keys are shown once at creation and stored hashed. Keys can be restricted to specific models and to specific request domains (matched against the Origin/Referer header). Never expose a key in client-side code — call the API from your backend.
Identical to the web generator and always charged against your account balance. List price per engine: HappyHorse 1.1 — 720P $0.14/second · 1080P $0.18/second; Wan 2.7 — 720P $0.10/second · 1080P $0.15/second. A flat $0.05/second platform fee is added on top — e.g. a 5-second 720P HappyHorse video costs $0.95, the same video with Wan 2.7 costs $0.75. API generations are private (no public-share discount). Failed or moderation-blocked generations are refunded automatically; the effective charge applies only to successful videos.
Every create-generation request accepts an optional engine field: "happyhorse" (default) or "wan" (Wan 2.7). Wan 2.7 supports longer prompts (up to 5,000 characters) and an optional negative_prompt (up to 500 characters) describing what should NOT appear in the video. All other parameters are identical across engines.
POST https://txtovid.com/api/v1/generations — returns 202 with the generation id. Video generation takes 1–5 minutes; poll the status endpoint (below) every 10–15 seconds.
| Field | Type | Description |
|---|---|---|
| model | string, required | "t2v" |
| engine | string, optional | "happyhorse" (default) or "wan" — selects HappyHorse 1.1 or Wan 2.7 |
| prompt | string, required | 3–2,000 characters (happyhorse) / 3–5,000 characters (wan) describing the video. |
| negative_prompt | string, optional | Wan 2.7 only — up to 500 characters describing what to exclude. |
| resolution | string, optional | "720P" (default) or "1080P" |
| ratio | string, optional | "16:9" (default), "9:16" or "1:1" |
| duration_sec | integer, optional | 3, 5, 8, 10 or 15 (default 5) |
curl -X POST https://txtovid.com/api/v1/generations \
-H "Authorization: Bearer $TXTOVID_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "t2v",
"prompt": "A golden retriever surfing a turquoise wave at sunset, cinematic slow motion",
"resolution": "720P",
"ratio": "16:9",
"duration_sec": 5
}'Same request with the Wan 2.7 engine and a negative prompt:
curl -X POST https://txtovid.com/api/v1/generations \
-H "Authorization: Bearer $TXTOVID_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "t2v",
"engine": "wan",
"prompt": "A golden retriever surfing a turquoise wave at sunset, cinematic slow motion",
"negative_prompt": "low resolution, worst quality, deformed",
"resolution": "720P",
"ratio": "16:9",
"duration_sec": 5
}'| Field | Type | Description |
|---|---|---|
| model | string, required | "i2v" |
| engine | string, optional | "happyhorse" (default) or "wan" |
| prompt | string, required | 3–2,000 characters (happyhorse) / 3–5,000 characters (wan) describing the motion. |
| negative_prompt | string, optional | Wan 2.7 only — up to 500 characters describing what to exclude. |
| image_url | string, required | Publicly reachable first-frame image URL. JPEG/JPG/PNG/BMP/WEBP, ≤20 MB, every edge ≥300 px, aspect ratio between 2:5 and 5:2. |
| resolution | string, optional | "720P" (default) or "1080P" |
| duration_sec | integer, optional | 3, 5, 8, 10 or 15 (default 5) |
No ratioparameter — per the model docs the output follows the input image's aspect ratio.
curl -X POST https://txtovid.com/api/v1/generations \
-H "Authorization: Bearer $TXTOVID_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "i2v",
"prompt": "Slow push-in, steam rising from the cup, warm morning light shifting",
"image_url": "https://example.com/product-shot.jpg",
"resolution": "720P",
"duration_sec": 5
}'| Field | Type | Description |
|---|---|---|
| model | string, required | "r2v" |
| engine | string, optional | "happyhorse" (default) or "wan" |
| prompt | string, required | 3–2,500 characters (happyhorse) / 3–5,000 characters (wan). Reference images with "[Image 1]", "[Image 2]" … in array order. |
| negative_prompt | string, optional | Wan 2.7 only — up to 500 characters describing what to exclude. |
| reference_image_urls | string[], required | 1–9 publicly reachable images of the same subject. JPEG/JPG/PNG, ≤20 MB each, shorter side >400 px. |
| resolution | string, optional | "720P" (default) or "1080P" |
| ratio | string, optional | "16:9" (default) or "9:16" — 1:1 is not supported by this model |
| duration_sec | integer, optional | 3, 5, 8, 10 or 15 (default 5) |
curl -X POST https://txtovid.com/api/v1/generations \
-H "Authorization: Bearer $TXTOVID_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "r2v",
"prompt": "The character from [Image 1] walks through a neon-lit alley at night, rain reflections, cinematic tracking shot",
"reference_image_urls": [
"https://example.com/character-front.jpg",
"https://example.com/character-side.jpg"
],
"resolution": "720P",
"ratio": "9:16",
"duration_sec": 5
}'| Field | Type | Description |
|---|---|---|
| model | string, required | "ve" |
| engine | string, optional | "happyhorse" (default) or "wan" |
| prompt | string, required | 3–2,500 characters (happyhorse) / 3–5,000 characters (wan) describing the edit (style transfer, object swap, weather change…). |
| negative_prompt | string, optional | Wan 2.7 only — up to 500 characters describing what to exclude. |
| video_url | string, required | Publicly reachable input video URL. MP4/MOV/WEBM, 1–15 seconds. |
| reference_image_urls | string[], optional | 0–5 images guiding the edit (e.g. the outfit or product to apply). |
| resolution | string, optional | "720P" (default) or "1080P" |
| duration_sec | integer, required | The input video's length in seconds (1–15) — the billing basis; the output keeps this duration. |
No ratio— the output keeps the input video's aspect ratio and duration per the model docs.
curl -X POST https://txtovid.com/api/v1/generations \
-H "Authorization: Bearer $TXTOVID_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "ve",
"prompt": "Turn the entire video into a watercolor animation, keep the camera motion unchanged",
"video_url": "https://example.com/clip.mp4",
"reference_image_urls": [],
"resolution": "720P",
"duration_sec": 5
}'{
"data": {
"id": "cmrk4gpbf0005lj04…",
"status": "SUBMITTED",
"model": "t2v",
"cost": "$0.95",
"cost_cents": 95,
"created_at": "2026-07-17T10:30:00.000Z",
"poll_url": "https://txtovid.com/api/v1/generations/cmrk4gpbf0005lj04…"
}
}GET https://txtovid.com/api/v1/generations/{id} — poll every 10–15 seconds until status is SUCCEEDED (video URLs included) or a failure state (error object included, charge refunded). Download the video promptly and store it on your side.
curl https://txtovid.com/api/v1/generations/GENERATION_ID \
-H "Authorization: Bearer $TXTOVID_API_KEY"{
"data": {
"id": "cmrk4gpbf0005lj04…",
"status": "SUCCEEDED",
"cost": "$0.95",
"cost_cents": 95,
"duration_sec": 5,
"resolution": "720P",
"generation_time_sec": 84,
"created_at": "2026-07-17T10:30:00.000Z",
"completed_at": "2026-07-17T10:31:24.000Z",
"error": null,
"video": {
"id": "vid_…",
"url": "https://media.txtovid.com/videos/…/original.mp4",
"thumbnail_url": "https://media.txtovid.com/videos/…/thumb.jpg",
"width": 1280,
"height": 720
}
}
}Every error is JSON with a stable machine-readable code: { "error": { "code", "message" } }. Provider errors from Model Studio are translated into clear messages and correct HTTP codes.
| HTTP | code | Meaning |
|---|---|---|
| 401 | missing_api_key / invalid_api_key | No key sent, or the key does not exist / was revoked. |
| 402 | insufficient_credits | Account balance is below the generation cost. The message contains both amounts. |
| 403 | model_not_allowed | The key is restricted and this model is not on its allow-list. |
| 403 | domain_not_allowed | The key is domain-restricted and the request Origin/Referer does not match. |
| 422 | validation_error | The request body violates the schema (unknown fields, wrong types, out-of-range values). The message lists every violation. |
| 422 | provider_rejected_input | The video model rejected the input (e.g. media URL unreachable, image too small). Forwarded from Model Studio with detail. |
| 422 | content_moderation_blocked | Prompt or media blocked by content moderation. Not charged. |
| 429 | rate_limited | 20 generations/hour per key; 120 status polls/minute. |
| 429 | too_many_active | Too many generations running in parallel on the account. |
| 429 | provider_busy | The video model is at capacity. Retry with backoff. |
| 502 | provider_error | Upstream failure at the video service. Automatically refunded. |
provider_busy and rate_limited with exponential backoff.