Skip to content

Video & music

Guides

Video and music

Queue video, music and sound-effect jobs, collect the files, the daily cutoff before 00:00 UTC, and automatic refunds of failed jobs.

Generate video, music and sound effects with the same key, the same balance and the same live discount as every other endpoint. These jobs take minutes, not seconds, so they work in steps: you quote (optional), queue the job, retrieve it until it is ready, and get the file back. The request and response bodies are the ones Venice’s video and audio queue APIs use, so existing code only needs the Tokentide base URL and key.

StepVideoMusic and sound effectsCost
Price itPOST /v1/video/quotePOST /v1/audio/quoteFree
Start itPOST /v1/video/queuePOST /v1/audio/queueCharged once, when the job is queued
Collect itPOST /v1/video/retrievePOST /v1/audio/retrieveFree; returns the file when it is ready
Clean upPOST /v1/video/completePOST /v1/audio/completeFree; only needed if you kept the media

Models are the video and music types of GET /v1/models?type=video and ?type=music. All music models, and most video models, are Anonymized: they need an API key whose privacy mode is all. Private video models (for example grok-imagine-text-to-video-private) work with any key.

How a job runs

A queued video job
  1. 1.Your client → Tokentide API: POST /v1/video/queue

  2. 2.Tokentide API → Venice: Quote the exact parameters

  3. 3.Tokentide API: Lock the multiplier, check the reset cutoff, reserve credit

  4. 4.Tokentide API → Venice: Queue the job

  5. 5.Tokentide API → Your client: queue_id (charged now)

  6. 6.Your client → Tokentide API: POST /v1/video/retrieve, every ~5 s

  7. 7.Tokentide API → Your client: {"status": "PROCESSING", …}

  8. 8.Your client → Tokentide API: POST /v1/video/retrieve

  9. 9.Tokentide API → Venice: Retrieve, delete the media after delivery

  10. 10.Tokentide API → Your client: The MP4 itself

Quote a job

A quote is free and changes nothing. quote is what queueing the same parameters now would cost you at Tokentide (the API list price times the current multiplier), and tokentide adds the detail:

curl
curl https://api.tokentide.app/v1/video/quote \
  -H "Authorization: Bearer $TOKENTIDE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "model": "grok-imagine-text-to-video-private", "duration": "5s", "resolution": "720p" }'
200 OK
{
  "quote": 0.125,
  "tokentide": {
    "list_cost_usd": "0.25",
    "charge_usd": "0.125",
    "multiplier": "0.5",
    "lane": "standard",
    "queue_open": true,
    "queue_closes_at": "2026-11-01T23:14:45.000Z"
  }
}
  • queue_open says whether a job can be queued right now (see The daily cutoff), and queue_closes_at when today’s queueing closes for this kind of job.
  • Prices move with the tide: queue soon after quoting, or cap the price with X-Tokentide-Max-Multiplier.

Queue a job

curl
curl https://api.tokentide.app/v1/video/queue \
  -H "Authorization: Bearer $TOKENTIDE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "grok-imagine-text-to-video-private",
    "prompt": "A lighthouse at dusk, waves rolling in, slow aerial shot",
    "duration": "5s",
    "resolution": "720p"
  }'
200 OK (X-Tokentide-Charge-USD: 0.125)
{ "model": "grok-imagine-text-to-video-private", "queue_id": "123e4567-e89b-12d3-a456-426614174000" }
  • Charged once, up front. The job is priced with the exact quote for its parameters and the multiplier locked when you queue it. X-Tokentide-List-Cost-USD, X-Tokentide-Charge-USD and X-Tokentide-Multiplier report it. Polling, retrieving and completing are free.
  • Buyer controls work as usual: X-Tokentide-Max-Multiplier, X-Tokentide-Max-Cost-USD, X-Tokentide-Lane (Low Tide where the model allows it) and Idempotency-Key to make retries safe.
  • Explicit durations. Send a fixed duration (for example "5s"). With reference_video_urls, a derived duration ("auto" or "-1") is refused, because the price could not be known before the job runs.
  • A queue id, never a download link. Some video models deliver through a pre-signed download URL. Tokentide never returns it: you collect every job through retrieve, so your network never reaches the provider’s storage.

Collect the result

Poll retrieve every few seconds (at most every 2 s; about 5 s is enough). While the job runs you get JSON with status: "PROCESSING", average_execution_time and execution_duration in milliseconds. When it is ready you get the file itself: video/mp4 for video, and audio/mpeg, audio/wav or audio/flac for music and sound effects.

Python
import os, time, requests
 
API = "https://api.tokentide.app/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['TOKENTIDE_API_KEY']}"}
MODEL = "grok-imagine-text-to-video-private"
 
job = requests.post(f"{API}/video/queue", headers=HEADERS, json={
    "model": MODEL,
    "prompt": "A lighthouse at dusk, waves rolling in, slow aerial shot",
    "duration": "5s",
    "resolution": "720p",
}).json()
 
while True:
    r = requests.post(f"{API}/video/retrieve", headers=HEADERS,
                      json={"model": MODEL, "queue_id": job["queue_id"]})
    r.raise_for_status()
    if r.headers["content-type"].startswith("video/"):
        open("lighthouse.mp4", "wb").write(r.content)  # deleted upstream once delivered
        break
    time.sleep(5)  # {"status": "PROCESSING", "average_execution_time": …, "execution_duration": …}
TypeScript
import { writeFile } from 'node:fs/promises';
 
const API = 'https://api.tokentide.app/v1';
const headers = {
  Authorization: `Bearer ${process.env.TOKENTIDE_API_KEY}`,
  'Content-Type': 'application/json',
};
const model = 'grok-imagine-text-to-video-private';
 
const job = await fetch(`${API}/video/queue`, {
  method: 'POST',
  headers,
  body: JSON.stringify({ model, prompt: 'A lighthouse at dusk', duration: '5s', resolution: '720p' }),
}).then((r) => r.json());
 
for (;;) {
  const r = await fetch(`${API}/video/retrieve`, {
    method: 'POST',
    headers,
    body: JSON.stringify({ model, queue_id: job.queue_id }),
  });
  if (!r.ok) throw new Error(`retrieve failed: ${r.status}`);
  if (r.headers.get('content-type')?.startsWith('video/')) {
    await writeFile('lighthouse.mp4', Buffer.from(await r.arrayBuffer()));
    break;
  }
  await new Promise((done) => setTimeout(done, 5_000));
}
  • Deleted as it is delivered. Tokentide sets delete_media_on_completion: true unless you send false, so the generated file is removed upstream as soon as you receive it, and Tokentide never stores it. If you send false (for example to retry a download yourself), call complete once you have the file.
  • Only your account can retrieve or complete a job it queued. Any other queue_id answers 404.

Music and sound effects

Music works the same way with the /v1/audio/* endpoints and music models. duration_seconds, lyrics_prompt, force_instrumental and the other fields follow each model’s capabilities in GET /v1/models?type=music.

curl
curl https://api.tokentide.app/v1/audio/queue \
  -H "Authorization: Bearer $TOKENTIDE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "elevenlabs-music",
    "prompt": "Calm instrumental piano for focus, soft and warm",
    "duration_seconds": 60,
    "force_instrumental": true
  }'
# → { "model": "elevenlabs-music", "queue_id": "…", "status": "QUEUED" }
 
curl https://api.tokentide.app/v1/audio/retrieve \
  -H "Authorization: Bearer $TOKENTIDE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "model": "elevenlabs-music", "queue_id": "…" }' \
  --output focus.mp3

Clean up

curl
# Only when you retrieved with "delete_media_on_completion": false
curl https://api.tokentide.app/v1/video/complete \
  -H "Authorization: Bearer $TOKENTIDE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "queue_id": "123e4567-e89b-12d3-a456-426614174000" }'
# → { "success": true }

The daily cutoff

Tokentide sells capacity that resets at 00:00 UTC. A job is billed when it is queued, and a job that failed after the reset could no longer be refunded upstream. So a job is accepted only if it would finish before the reset even in the worst case:

JobWorst-case run timeLast queue time (UTC)
Video45 minutesabout 23:14
Music and sound effects20 minutesabout 23:39

After that, queue answers 503 epoch_rollover with Retry-After until queueing reopens shortly after midnight. Quotes still work, and report queue_open: false. Jobs already running are not affected.

Failures and refunds

  • Rejected before it starts (invalid parameters, content policy at queue time): not charged.
  • Failed while running: when Venice keeps reporting the job as failed (500 on retrieve for over a minute), or rejects it for content policy with its credits refunded, Tokentide refunds the full charge automatically. The job then answers 404. The refund shows in your usage within minutes.
  • Never collected: a job you never retrieve stays charged; its media expires upstream.

Limits

LimitValue
Jobs queued and not yet collected, per account8 (429 rate_limited above it)
Polling interval per jobat least 2 s (429 faster)
Quotes, per account (including the quote each /queue call makes)60 per minute (429 above it)
Request body4.5 MB: pass images, audio and video by URL
Video prompt32,000 characters

A job stops counting toward the limit once you retrieve its file, complete it, it is refunded, or its worst-case run time has passed.