AI Status Webhook
POST /api/v1/webhooks/ai-status is called by Guinness workers with X-API-Key (checked with a timing-safe comparison). Workers never write PostgreSQL; the backend validates the callback and applies lifecycle changes.
The implemented type union is:
design-import,code-import,des2code: standard camelCase envelope.wf2des: WF2Des worker envelope.page_import: independent Page Import terminal envelope.code2des: independent Code2Des terminal envelope.
page-import and code2wf are not accepted discriminator values.
Page Import
{
"type": "page_import",
"job_id": "page-import-id",
"attempt": 1,
"nonce": "enqueue-nonce",
"status": "succeeded",
"result_manifest_url": "s3://bucket/1/7/page-import/page-import-id/manifest.json",
"manifest_schema_version": 1
}
status is succeeded or failed; failure may include error.message. The backend:
- Resolves
job_idto the Page Import row and checks the persisted nonce. - Requires the manifest bucket and key to match the row's tenant/project/import prefix.
- Checks manifest job ID, attempt, nonce, and
row_effects.page_import. - Compare-and-sets the processing row to completed or failed.
On success, the row effect supplies result_url, capture_hash, and screenshot_url. Page Import completion does not create, fail, or dispatch Code2Des. Duplicate terminal callbacks are idempotent.
Code2Des
{
"type": "code2des",
"job_id": "code2des-id",
"attempt": 1,
"nonce": "enqueue-nonce",
"status": "succeeded",
"result_manifest_url": "s3://bucket/1/7/code2des/code2des-id/manifest.json",
"manifest_schema_version": 1
}
The same identity and tenant-prefix checks apply. On success, row_effects.code2des supplies result_url and warning_count; on failure it supplies the failure result pointer and the callback may include error.message.
WF2Des
The wf2des generation worker writes its DesignSpec and result manifest to
DocumentDB/S3 and then reports run progress through this webhook. This handler
is the sole completion-time writer to the wf2des PostgreSQL row: it
advances the row through the parse checkpoint and flips it to its terminal
status. Only the two generation phases (parse, assemble) call this webhook โ
the internal wf2des runs (wf_parse, rule_process, component_sweep,
component_capture) never do.
WF2Des uses job_id (the wf2des row id), a positive attempt, nonce, and status of parse_started, parse_done, assemble_started, succeeded, or failed. result_manifest_url is required for terminal states; the phase signals carry none. The backend applies the manifest's guarded row_effects.wf2des transition.
status |
wf2des row effect |
|---|---|
parse_started |
Set phase to parse |
parse_done |
Set phase to awaiting_confirm; the row stays status '0' processing. Not sent on the auto-confirm path |
assemble_started |
Set phase to assemble on the auto-confirm path; a no-op after an interactive confirm |
succeeded |
Read the S3 manifest; flip status to '1' completed with result_url + flag_count from row_effects.wf2des; clear phase |
failed |
Flip status to '2' failed; record error and the failure result pointer; clear phase |
Every transition is attempt-guarded and gated on the row's current state, so a redelivered or superseded callback is a no-op. A missing wf2des row returns 404 so SQS redelivers; an unreadable or malformed manifest returns 500.
Standard envelope
design-import, code-import, and des2code use recordId, projectId, organizationId, status: success|failed, optional result, optional error.message, andโfor Des2Codeโoptional artifact metadata. The backend verifies tenant scope before applying the existing type-specific behavior.
Response
{
"message": "Status updated successfully",
"type": "page_import",
"recordId": "page-import-id",
"status": "success"
}
| Name | Type | Description |
|---|---|---|
message |
string | Human-readable status message |
type |
string | Echoes the request type |
recordId |
string | Echoes the request record ID (for job_id envelopes such as wf2des, echoes job_id) |
status |
string | Echoes the request status as success or failed |
The acknowledgement normalizes worker succeeded (and the WF2Des phase signals) to success.
Error Handling
| Description | Status Code | Status Name |
|---|---|---|
| Invalid or missing API key | 401 |
Unauthorized |
| Invalid request body | 422 |
Unprocessable Entity |
| Organization/project/record scope not found | 404 |
Not Found |
| Internal server error | 500 |
Internal Server Error |
Workers treat non-2xx webhook responses as retryable processing failures so SQS can redeliver the message.