Skip to main content
Komos can push run lifecycle events to your infrastructure so you do not need to poll the public API. Configure webhook endpoints from Settings → API & Webhooks in the dashboard, then use the API key issued to your organization to manage runs.

Supported events

Each endpoint can subscribe to one or more event types:
  • task-run.started — Emitted when a run transitions from PENDING to RUNNING.
  • task-run.completed — Sent after successful completion; payload mirrors the run resource.
  • task-run.failed — Delivered when a run exits with FAILED status and includes error context.
  • task-run.cancelled — Triggered after a run is cancelled (manual API call or dashboard action).
  • task-run.log — Streams batches of new log entries while the run executes.
If you do not choose specific events, Komos defaults to all of the above.

Payloads

task-run.* events reuse the run resource. A typical task-run.completed payload looks like this:
{
  "id": "220a501c-82f4-43e2-8107-3d8e0c0f4c1b",
  "taskId": "79c6b1aa-24d1-45b3-8c94-9a2e2a2f55bc",
  "status": "COMPLETED",
  "triggerType": "api",
  "timestamps": {
    "createdAt": "2025-10-13T15:02:44.812Z",
    "startedAt": "2025-10-13T15:02:47.001Z",
    "finishedAt": "2025-10-13T15:03:28.559Z"
  },
  "progress": {
    "currentStep": 5,
    "stepsTotal": 5
  },
  "inputs": {
    "url": "https://example.com/orders/48190"
  },
  "outputs": {
    "summary": "Completed order checkout scrape"
  },
  "logsUrl": "https://api.komos.ai/public/v1/task-runs/220a501c-82f4-43e2-8107-3d8e0c0f4c1b/logs",
  "error": null,
  "cancelReason": null
}
task-run.log carries the same structure as GET /public/v1/task-runs/{runId}/logs:
{
  "runId": "9c77d908-7bf4-4e7f-9a20-2c5e7fdf2e94",
  "logEntries": [
    {
      "id": "8c160f06-72c3-44d1-b0bb-0cb7284987b1",
      "timestamp": "2025-10-14T18:22:03.489Z",
      "level": "info",
      "message": "Navigated to https://example.com/orders/48219",
      "nodeId": "navigate_orders"
    }
  ]
}

Request headers

Every webhook delivery includes the following headers:
  • x-komos-event — Event type string (for example task-run.completed).
  • x-komos-signature — Verification metadata formatted as t=<ISO timestamp>,v1=<hex signature>.
  • x-komos-endpoint-id — UUID of the endpoint that received the event.
  • x-komos-run-id (optional) — Present for run-related events.
  • x-komos-task-id (optional) — Present when the endpoint is scoped to a single task.
  • content-type: application/json

Signature verification

Webhook signatures help confirm Komos sent the request. Use the signing secret shown when you create an endpoint (format wh_<prefix>_<secret>). The verification process matches the server-side logic:
  1. Split the secret on the first underscore. The portion after the underscore is the raw secret.
  2. Derive the signing key with HMAC-SHA256(key=WEBHOOK_SIGNING_PEPPER, message=raw_secret). Komos uses the default pepper komos-webhook-pepper unless your organization overrides it.
  3. Parse x-komos-signature into the timestamp (t) and signature (v1).
  4. Build the payload string <timestamp>.<raw_request_body>.
  5. Compute HMAC-SHA256(key=derived_signing_key, message=payload_string) and compare the hex digest with v1 using a constant-time comparison.

Python example

import hmac
import hashlib

WEBHOOK_SIGNING_PEPPER = b"komos-webhook-pepper"

def derive_signing_key(signing_secret: str) -> bytes:
    # signing_secret looks like "wh_ab12cd34_FQ7..."
    parts = signing_secret.split('_', 1)
    if len(parts) != 2:
        raise ValueError('invalid signing secret format')
    raw_secret = parts[1].encode('utf-8')
    return hmac.new(WEBHOOK_SIGNING_PEPPER, raw_secret, hashlib.sha256).digest()

def verify_signature(signing_secret: str, signature_header: str, body: bytes) -> bool:
    timestamp_fragment, signature_fragment = signature_header.split(',', 1)
    timestamp = timestamp_fragment.split('=', 1)[1]
    expected = signature_fragment.split('=', 1)[1]
    payload = f"{timestamp}.{body.decode('utf-8')}".encode('utf-8')
    key = derive_signing_key(signing_secret)
    candidate = hmac.new(key, payload, hashlib.sha256).hexdigest()
    return hmac.compare_digest(candidate, expected)
Rotate the signing secret from the dashboard if verification fails or credentials leak. Whenever you generate a new secret, reconfigure your integration with the updated value.

Retry policy

  • Komos retries failed deliveries up to 6 times.
  • The initial retry waits 60 seconds, doubling each attempt with up to ±30 seconds of jitter.
  • Backoff is capped at 30 minutes. After the final attempt the event is marked dead_lettered and surfaces in the dashboard along with the last error.
To re-enqueue dead-lettered events, toggle the endpoint back to active after resolving the issue or contact support to trigger a replay.