Documentation

Synchronous vs. asynchronous

When to use the inline synchronous endpoints and when to submit an asynchronous task.

Fotovid offers the same media capabilities two ways. Pick based on how big the input is and how long you're willing to wait in one request.

Synchronous

Resource endpoints — POST /v1/image/watermark, POST /v1/video/extract-cover, POST /v1/video/watermark, POST /v1/video/trim, POST /v1/audio/trim, POST /v1/video/extract-audio, POST /v1/video/probe — process the job and return the result inline in one response. No polling, no webhook. The body is just { source_url, params }; the capability comes from the URL.

Best for small, fast jobs:

  • Light work (image watermark, cover extraction) finishes in seconds.
  • Roughly a 10-second budget for light work, 30 seconds for heavy video watermarking.
  • Source caps: 128 MiB for images; sync video watermarking is additionally capped at 720p and a 15 second duration (larger or longer goes async, up to 4K). video.trim is the exception — it runs up to 4K synchronously (it only re-encodes the trimmed window); other sync video still tops out at 720p.

If a heavy job is too long or too large, the sync endpoint rejects it up front with 409 and points you to the async API — you won't sit through a timeout.

A sync 503 (SERVICE_UNAVAILABLE) now signals transient saturation after bounded queueing — your request waited for a worker slot but the pool stayed full. Honor the Retry-After header (seconds) before retrying.

Asynchronous

POST /v1/tasks queues the job and returns immediately with status: "starting". You then poll GET /v1/tasks/{id} or receive a signed webhook.

Best for anything large, long, or that you'd rather not block on:

  • Larger inputs — video up to 500 MiB, audio.trim up to 200 MiB.
  • A generous overall processing budget (up to ~10 minutes).
  • Multiple outputs, returned as outputs[{ kind, url }].

Any capability can run async — synchronous is just an optional fast lane. (Video watermarking still tops out at 4K; sources above 4K aren't supported.)

Choosing

Rule of thumb: if the input comfortably fits the time-and-size budget, call the synchronous endpoint and read the result inline. If it's big, long, or you're not sure, submit an async task and poll or use a webhook.

SynchronousAsynchronous
EndpointPOST /v1/{image,video,audio}/…POST /v1/tasks
ResultInline in the responsePoll GET /v1/tasks/{id} or webhook
OutputFlat urloutputs[].url (multi-output)
Budget~10s light / ~30s heavyup to ~10 min
Max sourceimage 128 MiB / heavy-video gatedvideo 500 MiB, audio 200 MiB
Over budget409 → use async

Next: the full async flow in Tasks & polling.