HTTP 202 generation jobs: persist acceptance before announcing completion
An accepted response is a useful milestone, but it is not a completed video. In a production application, the moment that matters is when your own durable record contains the remote identifier. Announcing success before that write leaves a user with an apparently finished action that your workers cannot recover after a restart.
Establish an application operation before dispatch
Create a local operation with your user identity, requested media type, reviewed parameters, and an application operation ID. This is your record of intent. It is separate from a Genace job, and its identifier should never be passed to the upstream status route as though the resources were interchangeable.
The current Genace submission service validates the selected adapter, atomically reserves credits and inserts its queued job, then calls the provider. A successful public POST returns HTTP 202 with job_id, state, model, creation timestamp, and held credits. It may already report running. Do not require its state to equal queued before accepting the identifier.
{
"operation_id": "application-operation-42",
"phase": "accepted",
"remote_job_id": "saved-genace-job-id",
"media_type": "video",
"delivery_state": "not_collected"
}
This is an example application record, not a Genace response schema. Store it in your own durable database and link it to the local user who authorized the operation. The delivery field lets you distinguish a finished render from an asset that your application has actually downloaded and published.
Commit the accepted reference before responding locally
After receiving the accepted response, validate that job_id is a nonempty string and write it to the existing operation. Only then tell your UI that submission is accepted. If the database write fails, retain the response in a restricted recovery channel and surface an operational incident. Do not automatically submit another generation to repair a local persistence error.
The same discipline applies to the HTTP 502 submission-failure envelope, which can include error.job_id. That reference leads to a failed local job whose refund may still need settlement. A generic network exception without an ID is a different uncertainty branch and requires reconciliation rather than a guessed status URL.
Observe rendering and delivery independently
GET the saved remote identifier and inspect the snapshot’s id, state, outputs, and error. A successful HTTP read may describe a failed generation. Null outputs are valid before completion. Mark local rendering complete only after a terminal state is observed, and mark delivery complete only after your storage and publishing checks pass.
If downloading later fails, retry delivery of the existing output rather than creating another render. If the interface reloads, read the durable operation first and resume observation. These choices prevent an accepted workflow from depending on a browser connection remaining open for minutes.
Acceptance criteria
Inject a crash immediately after receipt of the 202 and another immediately after your database commit. Verify the first creates a visible reconciliation case and the second resumes the saved job. Test a running initial state, a failed job read, and a completed render whose storage upload fails. Confirm none of those branches silently reuses a creation action as recovery.
Continue with operation status links, job states, and output storage for the next stages.
Continue with code and integration
Where these facts come from
- Editorial keyword hypothesis; search volume not measured
- https://www.rfc-editor.org/rfc/rfc9110.html#name-202-accepted
- codebase: src/app/api/v1/video/generations/route.ts
- codebase: src/ai/jobs/service.ts