Webhooks

Configure a webhook URL to receive HTTP POST notifications as each node executes and when the workflow completes.

How webhooks work

When you provide a webhookUrl with your workflow, Graph Compose sends an HTTP POST request to that URL at two points:

  1. After each node executes (or fails, or is skipped). The payload includes the node ID, execution state, and result or error.
  2. When the workflow completes. The payload includes the final workflow result or error.

Webhook delivery is fire-and-forget. If your endpoint is unreachable or returns an error, the failure is logged but does not affect workflow execution. Nodes continue to run regardless of whether webhook delivery succeeds.

Configure a webhook

You can set the webhook URL on the GraphCompose instance with .withWebhookUrl(), or pass it as an option to .execute(). Both approaches are equivalent. If you provide a URL in both places, the .execute() option takes precedence.

import { GraphCompose } from '@graph-compose/client'

const graph = new GraphCompose({
  token: process.env.GRAPH_COMPOSE_TOKEN
})

graph
  .node('fetch_data')
    .get('https://api.example.com/data')
  .end()
  .withWebhookUrl('https://api.your-app.com/webhooks')

const result = await graph.execute()

Payload structure

Every webhook POST request sends a JSON body with this top-level structure:

Top-level payload

{
  "workflowId": "wf_abc123",
  "runId": "run_def456",
  "type": "node",
  "data": { }
}
FieldTypeDescription
workflowIdstringThe unique ID of the workflow definition
runIdstringThe unique ID for this specific execution run
type"node" or "completion"Whether this payload is for a single node event or the final workflow completion
dataobjectThe event-specific payload. Shape depends on the type field.

Node events

A node event (type: "node") is sent after each node finishes executing, fails, or is skipped. The data field contains:

FieldTypeDescription
timestampnumberUnix timestamp in milliseconds when the event occurred
nodeIdstringThe ID of the node
nodeTypestringThe type of the node (e.g., "http", "error_boundary")
executionStatestringThe node's execution state. See execution states.
resultunknown (optional)The node's result data, present when the node executed successfully
errorobject (optional)Error details, present when the node failed

The error object, when present, has this shape:

FieldTypeDescription
messagestringThe error message
typestring (optional)The error category, if available
detailsunknown (optional)Additional error-specific information
{
  "workflowId": "wf_abc123",
  "runId": "run_def456",
  "type": "node",
  "data": {
    "timestamp": 1709347200000,
    "nodeId": "get_user",
    "nodeType": "http",
    "executionState": "executed",
    "result": {
      "data": { "id": "u_1", "name": "Alice" },
      "statusCode": 200,
      "headers": {}
    }
  }
}

Completion events

A completion event (type: "completion") is sent once when the entire workflow finishes, whether it succeeded or failed. The data field contains:

FieldTypeDescription
timestampnumberUnix timestamp in milliseconds when the workflow completed
resultunknown (optional)The final workflow result, present on success
errorunknown (optional)Error details, present if the workflow failed

Completion event

{
  "workflowId": "wf_abc123",
  "runId": "run_def456",
  "type": "completion",
  "data": {
    "timestamp": 1709347205000,
    "result": {
      "get_user": {
        "data": { "id": "u_1", "name": "Alice" },
        "statusCode": 200,
        "headers": {}
      },
      "send_email": {
        "data": { "sent": true },
        "statusCode": 200,
        "headers": {}
      }
    }
  }
}

Execution states

The executionState field on node events indicates what happened to the node:

StateMeaning
pendingThe node has not started executing yet
executedThe node completed successfully
executed_and_failedThe node executed but returned a failure (HTTP error, network error, or validation failure)
terminatedThe node was terminated (e.g., by a terminateWhen condition)
skippedThe node was skipped because an upstream dependency failed

Operational details

Webhooks are delivered with these characteristics:

  • HTTP method: POST with Content-Type: application/json
  • No retries: Each webhook is sent once. If the request fails, the failure is logged and no retry is attempted.
  • Non-blocking: Webhook delivery failures do not affect workflow execution. Nodes continue to run regardless.
  • Delivery order: Node events are sent as each node completes. The completion event is sent last, after all nodes have finished.

Best practices

  • Return a 2xx response from your endpoint as fast as possible. Offload processing to a background job or queue.
  • Store incoming payloads before processing them. This lets you replay events if your processing logic fails.
  • Use the workflowId and runId fields to correlate node events with the final completion event.
  • Use executionState to filter events. For example, if you only care about failures, check for "executed_and_failed" and ignore "executed" or "skipped".
  • Ensure your endpoint is idempotent. Although Graph Compose does not retry webhooks, network conditions can occasionally cause duplicate delivery.

Next steps