Skip to content

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:

  1. Resolves job_id to the Page Import row and checks the persisted nonce.
  2. Requires the manifest bucket and key to match the row's tenant/project/import prefix.
  3. Checks manifest job ID, attempt, nonce, and row_effects.page_import.
  4. 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.