Genace

Video generation API resume jobs: recover work after a process restart

For a video generation API, resume jobs by saving their identifiers and reading them again. A new application process does not need the original connection, browser tab, or SSE history. It needs the job ID, credentials belonging to the job owner, and enough local context to deliver the result to the correct user.

The important recovery boundary is the moment your application receives the submission response. Genace returns job_id there. Save it before marking the user request as accepted, and normalize subsequent GET snapshots, which use id, into the same local record.

Design the smallest useful recovery record

FieldWhy it survives a restart
local_request_idConnects the render to a user action
remote_job_idIdentifies the existing Genace job
owner_referenceSelects credentials and checks application authorization
collection_statusDistinguishes waiting, terminal, and delivery work
next_read_atPrevents every restarted worker polling at once
output_manifestMakes file delivery resumable separately

Keep the API key in your secret store rather than storing it in every record. If several users share an application account, your backend must still enforce its own user-level ownership before returning saved jobs.

Resume with a read-only operation

This Python example reads an identifier supplied through the environment. It uses only the standard library and performs no generation request.

import json
import os
import urllib.error
import urllib.parse
import urllib.request

job_id = os.environ['GENACE_JOB_ID']
url = 'https://genace.ai/api/v1/jobs/' + urllib.parse.quote(job_id, safe='')
request = urllib.request.Request(url + '?wait=0', headers={
    'Authorization': 'Bearer ' + os.environ['GENACE_API_KEY'],
})
try:
    with urllib.request.urlopen(request, timeout=20) as response:
        snapshot = json.load(response)
    print(json.dumps({'id': snapshot['id'], 'state': snapshot['state']}))
except urllib.error.HTTPError as error:
    print(json.dumps({'read_status': error.code}))

A queued or running response schedules another read. A succeeded response schedules file collection. Failed and canceled responses finish the local render record after preserving diagnostic and accounting fields. Save the snapshot before acknowledging your queue message so a crash does not lose the result.

Handle missing and inaccessible jobs carefully

The public read route returns 404 when the job does not exist and 403 when it belongs to another user. Neither status means that starting a new generation is automatically appropriate. Check the environment, stored identifier, and account mapping first. A production worker using staging credentials is a common source of misleading recovery failures.

A harder case is a process crash before the POST response was saved. That is an ambiguous submission, not a known resumable job. Mark it for reconciliation and consult the duplicate-request workflow rather than inventing an identifier or blindly replaying creation.

Verification checklist

Restart the collector after saving an accepted job and verify that it performs only GET requests. Repeat after terminal success but before file copying. Confirm that the second restart resumes delivery rather than generation, and that unauthorized users cannot retrieve another user’s saved snapshot.

Read duplicate request handling, output storage, and serverless architecture.

Continue with production operations

Where these facts come from

  • codebase: src/app/api/v1/video/generations/route.ts
  • codebase: src/app/api/v1/jobs/[id]/route.ts
  • codebase: src/ai/jobs/http.ts
  • Editorial keyword hypothesis; search volume not measured