workflow_id field so you can route on your end. Register them in Settings → Webhooks by selecting “All Workflows” as the scope.
For the full list of subscribable events you can set in event_types_subscribed, see the webhook schema in the Run API reference. Maintenance recovery flows emit the lifecycle events documented below, such as execution.requeued, execution.password_updated, and the final terminal status. When the recovery agent asks a human to decide (Decision Required), agent.decision_requested and agent.decision_answered report the question’s lifecycle.
execution.start
execution.start
This event is sent once when the execution of the workflow starts. It returns a live view URL of the running browser agent embeddable as iframe.
execution.step
execution.step
This event is sent every time the workflow is executing an action like clicking on a button or filling out an input field.
execution.queued
execution.queued
This event is sent when a run is queued and waiting for an available worker.
execution.paused
execution.paused
This event is sent when a run is paused before execution (for example, when workflow-level or credential-level pause controls are active).
execution.success
execution.success
This event is sent once when the execution of the workflow has finished successfully. It includes the result data that is returned from the workflow.
execution.failed
execution.failed
This event is sent once, when the run has failed for good and will not be retried. A run that is being retried sends The
execution.requeued instead. See Run Statuses. The payload contains information about the error.llm_error_category field contains an AI-generated categorization of the error type. This field may be null if AI analysis was not performed.The llm_error_sub_type field contains a more specific sub‑classification within the category. See the error classification matrix for all possible values. This field may be null if no sub‑type applies.The llm_error_description field contains an AI-generated explanation of why this specific error happened. This field may be null if AI analysis was not performed or the analysis was not confident enough to produce a description.The original_error field contains the raw technical runtime error message before any AI analysis. This is useful for debugging and differs from message field that contains the Maintenance Agent’s analysis.When a workflow has
deny_requeue_past_dry_run_marker enabled and a failure occurs at or past the dry-run marker, the run is not retried. If no customer-configured error code matches the failure, the terminal error code is set to requeue_denied_past_dry_run_marker; otherwise the matched customer code takes precedence. See Service and Logged-Out Session Recovery for details.execution.stopped
execution.stopped
This event is sent when one or several workflow runs were cancelled. It respectively either contains Response for multiple cancelled at once:
session_id of the cancelled run or session_ids that contains all of the cancelled runs.Response for single run cancelled:execution.requeued
execution.requeued
This event is sent when an attempt hits a recoverable failure and the run is automatically requeued for retry by the Maintenance Agent (e.g., after a
SERVICE_UNAVAILABLE classification). The run is still in progress: it does not report execution.failed unless it later runs out of retries. See Run Statuses for which statuses are final. See Service Unavailable Recovery for retry schedule details.execution.password_updated
execution.password_updated
This event is sent after an automated password recovery flow succeeds and CloudCruise updates the vault credential used by the run.
agent.decision_requested
agent.decision_requested
This event is sent once when the recovery agent asks a human to make a decision during a run (Decision Required). It carries the question and what to answer; send the answer to
respond_url as described in Answer a decision. The first answer accepted from the API, Slack or the CloudCruise dashboard resolves the decision. Like the execution.* events, the payload starts with session_id and workflow_id, the run’s metadata is in the envelope, and no key is ever null (optional keys are omitted).The envelope’s
expires_at is how long the webhook signature is valid, not the decision deadline; use answer_by.agent.decision_answered
agent.decision_answered
This event is sent once when a decision requested by the recovery agent is closed. The envelope’s
timestamp is when it closed. Deliveries are independent, so it can arrive before agent.decision_requested (for example when that delivery is retried); match the two on decision_id.screenshot.uploaded
screenshot.uploaded
This event is sent when the upload of the screenshot has finished.
video.uploaded
video.uploaded
This event is sent when the upload of the workflow video has finished.
file.uploaded
file.uploaded
This event is sent when a file has been uploaded during workflow execution. The
signed_file_url expiration is configurable per workspace (default: 7 days, range: 1 hour to 7 days). Configure this in your workspace settings. See Downloading Run Files for how downloads work.interaction.waiting
interaction.waiting
This event is sent when user input is required to continue the workflow.
interaction.failed
interaction.failed
This event is sent when the user input was not provided in time or in a wrong format.
interaction.finished
interaction.finished
This event is sent when the user input was provided and the workflow continues.
Security
We sign webhook events with the secret you get when you register a webhook. We also add an expiry time. You can change the expiry time in the setting of the registered webhook. Here’s how we recommend to verify the message you receive from us:- Python
- Javascript
IP Allowlisting
All webhook requests from CloudCruise originate from the following static IP addresses. If your infrastructure requires IP-based filtering, add these to your allowlist:Payload Size
A registration can be configured to omitinput_variables from the payloads it receives. Turn on Exclude input variables from the payload in the webhook dialog in Settings → Webhooks, or send excludeInputVariables: true when creating or updating the webhook through the API.
The field is then left out of every event delivered to that endpoint. Use it when you start runs with large inputs and your endpoint enforces a body-size limit — you already hold the inputs you sent. Other registrations are unaffected, and the run result from GET /runs/{session_id} still returns the inputs.
excludeInputVariables is optional on update: leave it out and the endpoint keeps whatever setting it already has.
The setting applies from the moment you turn it on. Events recorded before then were stored with input_variables included, and replaying one re-sends it as recorded — replay never rebuilds the payload. If you enable the option to get under a body-size limit, expect replays of earlier events to still exceed it.
Deliverability
CloudCruise automatically retries failed webhook deliveries up to 3 times (4 total attempts including the initial request) with exponential backoff delays between attempts. Each delivery attempt has a 5-second request timeout. Total delivery time depends on failure mode, so retries may complete quickly for immediate network errors or take longer for repeated timeouts.Retry Conditions
A webhook delivery is retried when:- Network errors occur (connection timeout, DNS failure, etc.)
- Server errors are returned (HTTP status codes 500 and above)
- Request timeouts exceed 5 seconds
Manual Replay
If webhooks still fail after automatic retries, you can manually replay them:- Dashboard: Navigate to the run detail view and trigger a resend
- API: Send a POST request to
https://api.cloudcruise.com/webhooks/{session_id}/replay

