Async Steps

Start long-running or queue-backed work with an HTTP request and complete it through an idempotent callback.

Protocol

Register a service Step with the same HTTP and Attribute contract as a synchronous one, but set "mode": "async" on the invoke action:

{
  "id": "process-payment",
  "type": "service",
  "http": {
    "invoke": {
      "method": "POST",
      "endpoint": "https://payments.example.com/process",
      "timeout": 5000,
      "mode": "async"
    }
  },
  "attributes": {
    "order_id": { "role": "required", "type": "string" },
    "transaction_id": { "role": "output", "type": "string" }
  }
}
  1. Argyll invokes the Step and sends Argyll-Webhook-URL and Argyll-Receipt-Token headers.
  2. The service accepts the work with a 2xx response.
  3. A worker posts the result to the webhook URL.

The action’s HTTP timeout covers the initial request. After the service accepts the work, the Flow remains active until the callback reports its result.

The supplied invocation URL uses /callbacks/{flow_id}/{step_id}/{token}/invoke under WEBHOOK_BASE_URL. Workers should post to the header value directly rather than constructing it themselves. Async compensation uses the same route shape with /compensate, as described in Compensation.

Complete Work

Post output Attributes directly:

{
  "transaction_id": "txn-abc123"
}

Post application/problem+json to report a permanent failure:

{
  "type": "about:blank",
  "title": "Payment Declined",
  "status": 422,
  "detail": "Card was declined"
}

The receipt token and action identify one callback. Repeating a completion callback is safe: the engine accepts an already-recorded completion and returns 200. Workers can therefore retry network and 5xx failures until they receive success, while treating 4xx as permanent.

See HTTP Steps for the invocation body and headers, and Retries for engine retry behavior.