how to use Veo 3 API: submit, poll, and handle the failure case
Submit
curl -X POST https://genace.ai/api/v1/video/generations \
-H "Authorization: Bearer $GENACE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"veo3","prompt":"..."}'
The model id is exactly veo3 — a typo here returns
400 UNKNOWN_MODEL naming what you sent.
You get 202 Accepted with a job, not a video:
{
"job_id": "abc123",
"state": "queued",
"model": "veo3",
"credits_held": 100
}
credits_held is what this call reserved. It comes back in full if the job
fails or you cancel it.
Collect the result
curl "https://genace.ai/api/v1/jobs/abc123?wait=30" \
-H "Authorization: Bearer $GENACE_API_KEY"
wait blocks server-side for up to N seconds. There are three other ways to
collect — webhook, SSE and a cron backstop — and which to use depends on what
is calling you. See
webhook vs polling.
The failure that will not throw
A failed job is a successful HTTP response describing a failure:
{ "state": "failed", "error": { "code": "UPSTREAM_EMPTY_RESULT" } }
raise_for_status() and equivalents see a 200 and move on. Check state,
not the status code.
Parameters worth setting
duration_sec is fixed at 8 — do not send it. Setting resolution to 720p halves the cost while you iterate.
Full reference in Veo 3 API parameters.
Models covered on this page
Where these facts come from
- codebase: src/ai/providers/veo3.ts — pricing() and paramsSchema
- codebase: src/app/api/v1/video/generations/route.ts — request and response shape