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.trimis 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.trimup 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.
| Synchronous | Asynchronous | |
|---|---|---|
| Endpoint | POST /v1/{image,video,audio}/… | POST /v1/tasks |
| Result | Inline in the response | Poll GET /v1/tasks/{id} or webhook |
| Output | Flat url | outputs[].url (multi-output) |
| Budget | ~10s light / ~30s heavy | up to ~10 min |
| Max source | image 128 MiB / heavy-video gated | video 500 MiB, audio 200 MiB |
| Over budget | 409 → use async | — |
Next: the full async flow in Tasks & polling.