Skip to content

Cancel Generation

Method

This API follows the REST methodology.

HTTP Method

POST: Cancel a wf2des Generation

Naming Convention

To ensure consistency and readability, JSON nodes in requests and responses use camelCase. SQS payload nodes use snake_case.

Request and Response

Headers

Meta information is set in HTTP headers, not in the response body.

Request Headers

  • Authorization
  • Content-Type
  • Accept
  • Accept-language

Response Headers

  • Content-Type

Cancel a wf2des Generation

URI

POST /api/v1/organizations/{organization_id}/projects/{project_id}/wf2des/{wf2des_id}/cancel

Path Parameters

Name Type Required Description
organization_id integer Required Organization ID
project_id integer Required Project ID
wf2des_id string Required wf2des ID

Request Body

No request body is required. Any body is ignored; cancellation is fully addressed by the path.

Response

The response is JSON (HTTP status: 200 OK).

{
  "projectId": "proj-123",
  "wf2desId": "wf2des-001",
  "status": "4",
  "phase": null,
  "attempt": 1,
  "cancelledAt": "2026-07-06T09:35:00Z"
}

Response Fields

Name Type Description
projectId string Project ID
wf2desId string wf2des ID
status string Terminal status after cancellation โ€” always "4" (cancelled)
phase string | null Generation phase โ€” cleared to null once the row reaches a terminal status
attempt integer Fencing counter of the cancelled run (unchanged by cancellation)
cancelledAt string ISO 8601 timestamp when the row was flipped to cancelled (updatedAt mirror)

A repeated cancel on a row already at status "4" returns 200 OK with the same body (idempotent). A cancel on any other terminal row ("1" completed / "2" failed / "3" rejected) returns 409 Conflict.

Authentication

Authentication is performed using JSON Web Tokens (JWT) issued by Amazon Cognito.

Any authenticated session with Write access to the project may cancel a generation โ€” cancellation is not restricted to the session that triggered it. The generation is parked at phase "1" awaiting_confirm and no confirm decision is required to cancel it.

Error Handling

The following status codes are returned for errors.

Description Status Code Status Name
Missing authentication credentials 401 Unauthorized
Insufficient permissions 403 Forbidden
wf2des, project, or organization not found 404 Not Found
Generation is not cancellable โ€” already terminal ("1" / "2" / "3") 409 Conflict
Internal server error 500 Internal Server Error

Processing Flow

The backend owns the wf2des PostgreSQL row and is the sole writer. Cancellation is a single attempt-guarded state transition applied backend-side โ€” the worker holds no PostgreSQL credentials and never participates. The transition is a CAS on the current row: it lands status "4" (cancelled) and clears phase to NULL only when the row is still status "0" (processing) and parked at phase "1" (awaiting_confirm).

  1. Extract organization ID, project ID, and wf2des_id from path parameters
  2. Verify the user has Write access to the project
  3. Fetch the wf2des row by wf2des_id; if it does not exist (or is soft-deleted), return 404
  4. Verify the row's organization_id and project_id match the path; otherwise return 404
  5. Inspect the current status / phase:
  6. Already status "4" (cancelled) โ†’ return 200 with the existing row (idempotent, no write)
  7. Any other terminal status ("1" completed / "2" failed / "3" rejected) โ†’ return 409 (not cancellable)
  8. status "0" (processing) but not parked at phase "1" awaiting_confirm โ†’ return 409 (not cancellable)
  9. status "0" and phase "1" awaiting_confirm โ†’ proceed
  10. Apply the CAS update in one PostgreSQL transaction โ€” set status = "4", clear phase to NULL, stamp updated_at / updated_by; the CAS is guarded on the row still being status "0" + phase "1" (a concurrent confirm / webhook that already moved the row loses the race and yields 409)
  11. Return the cancelled wf2des information

No SQS message is emitted by this endpoint. The generation was parked at the confirm checkpoint with no in-flight worker to signal; cancelling simply retires the row so the confirm endpoint can no longer advance it to phase "2" (assemble). A late or superseded ai-status webhook targeting the cancelled row is a no-op under its own attempt guard.

Detailed Flowchart

flowchart TD
    Start([POST Request]) --> Auth[Auth & Parameter Extraction]
    Auth --> Service[Service Layer]

    Service --> AccessCheck[Access Check]
    AccessCheck --> HasAccess{Write Access?}
    HasAccess -->|No| Err403[403 Forbidden]
    HasAccess -->|Yes| FetchRow[Fetch wf2des Row<br/>WHERE id = :wf2des_id]

    FetchRow --> RowExists{Exists &<br/>org/project match?}
    RowExists -->|No| Err404[404 Not Found]
    RowExists -->|Yes| StatusCheck{Current status?}

    StatusCheck -->|status '4' cancelled| Idempotent[200 OK<br/>existing row, no write]
    StatusCheck -->|status '1' / '2' / '3'<br/>terminal| Err409[409 Conflict<br/>not cancellable]
    StatusCheck -->|status '0' processing| PhaseCheck{phase '1'<br/>awaiting_confirm?}

    PhaseCheck -->|No| Err409
    PhaseCheck -->|Yes| CAS[CAS Update in one PG txn<br/>status = '4' cancelled<br/>phase = NULL<br/>guard: status '0' + phase '1']

    CAS --> CASResult{CAS won?}
    CASResult -->|No โ€” concurrent confirm/webhook| Err409
    CASResult -->|Yes| Success[200 OK<br/>cancelled wf2des info]