Docs
API 1.39
Status
Reference

Events

Every event type Kaabist emits, with the shape of its data.

Every event is delivered to your webhook endpoints and kept in the event log with the same envelope: id (evt_…), type, created_at, org_id, mode and data. See the WebhookEvent object for the envelope and the webhooks guide for signatures and retries.

#job.queued

A job was accepted, re-queued after a worker lost it, resumed, or escalated to a heavier tier.

{
  "type": "job.queued",
  "data": {
    "job": "job_01j9zqk3q7m4n5p6r7s8t9v0wx",
    "program": "acme-report@3"
  }
}

#job.blocked

A queued job is being held back because the organisation is out of credits; reason is insufficient_credits. Sent once per blocked stretch.

{
  "type": "job.blocked",
  "data": {
    "job": "job_01j9zqk3q7m4n5p6r7s8t9v0wx",
    "program": "acme-report@3",
    "reason": "insufficient_credits"
  }
}

#job.started

A worker began running the job, sent on its first run only.

{
  "type": "job.started",
  "data": {
    "job": "job_01j9zqk3q7m4n5p6r7s8t9v0wx",
    "program": "acme-report@3"
  }
}

#job.awaiting_input

The job paused at an await_input step and needs a value.

{
  "type": "job.awaiting_input",
  "data": {
    "job": "job_01j9zqk3q7m4n5p6r7s8t9v0wx",
    "program": "acme-report@3"
  }
}

#job.needs_attention

The job paused and needs a decision; reason is the attention reason.

{
  "type": "job.needs_attention",
  "data": {
    "job": "job_01j9zqk3q7m4n5p6r7s8t9v0wx",
    "program": "acme-report@3",
    "reason": "obstacle"
  }
}

#job.succeeded

The job finished and its result can be read.

{
  "type": "job.succeeded",
  "data": {
    "job": "job_01j9zqk3q7m4n5p6r7s8t9v0wx",
    "program": null
  }
}

#job.failed

The job ended without a result; reason is the error code.

{
  "type": "job.failed",
  "data": {
    "job": "job_01j9zqk3q7m4n5p6r7s8t9v0wx",
    "program": "acme-report@3",
    "reason": "blocked"
  }
}

#job.canceled

The job was canceled or aborted; reason is canceled.

{
  "type": "job.canceled",
  "data": {
    "job": "job_01j9zqk3q7m4n5p6r7s8t9v0wx",
    "program": "acme-report@3",
    "reason": "canceled"
  }
}

#batch.completed

Every job of a batch has finished. total is the number of jobs in it.

{
  "type": "batch.completed",
  "data": {
    "batch": "bat_01j9zqk3q7m4n5p6r7s8t9v0wx",
    "total": 120
  }
}

#proposal.created

Kaabist proposed a fix for review, such as a relocated locator or a dismiss recipe. kind says which.

{
  "type": "proposal.created",
  "data": {
    "proposal": "prp_01j9zqk3q7m4n5p6r7s8t9v0wx",
    "program": "acme-report@3",
    "job": "job_01j9zqk3q7m4n5p6r7s8t9v0wx",
    "kind": "relocate"
  }
}

#proposal.decided

Somebody approved or rejected a proposal; decision says which.

{
  "type": "proposal.decided",
  "data": {
    "proposal": "prp_01j9zqk3q7m4n5p6r7s8t9v0wx",
    "program": "acme-report@3",
    "job": null,
    "kind": "relocate",
    "decision": "approved"
  }
}

#schedule.run

A scheduled job ended with nothing to report: the result matched the previous run (changed: false), or the job did not succeed (status).

{
  "type": "schedule.run",
  "data": {
    "schedule": "sch_01j9zqk3q7m4n5p6r7s8t9v0wx",
    "job": "job_01j9zqk3q7m4n5p6r7s8t9v0wx",
    "status": "succeeded",
    "changed": false
  }
}

#schedule.changed

A scheduled run's watched fields differ from the previous run's. changed_paths lists up to 50 JSON Pointers and diff_url links to the diff.

{
  "type": "schedule.changed",
  "data": {
    "schedule": "sch_01j9zqk3q7m4n5p6r7s8t9v0wx",
    "job": "job_01j9zqk3q7m4n5p6r7s8t9v0wx",
    "changed_paths": [
      "/products/3/price",
      "/products/7/price"
    ]
  }
}

#schedule.paused

A schedule was paused, by a person or because the organisation ran out of credits; reason is manual or credits.

{
  "type": "schedule.paused",
  "data": {
    "schedule": "sch_01j9zqk3q7m4n5p6r7s8t9v0wx",
    "reason": "credits"
  }
}

#schedule.failing

Five runs of a schedule in a row did not succeed. The schedule keeps running; failure_streak counts the failures.

{
  "type": "schedule.failing",
  "data": {
    "schedule": "sch_01j9zqk3q7m4n5p6r7s8t9v0wx",
    "job": "job_01j9zqk3q7m4n5p6r7s8t9v0wx",
    "failure_streak": 5
  }
}

#session.expired

A stored session stopped working and needs a new sign-in.

{
  "type": "session.expired",
  "data": {
    "session": "ses_01j9zqk3q7m4n5p6r7s8t9v0wx",
    "name": "acme"
  }
}

#program.drift_detected

A field of a published program version stopped filling, parsing or keeping its length, or the version's canary failed, before your next job notices. Sent once per version, field and kind while the finding stays open.

{
  "type": "program.drift_detected",
  "data": {
    "program": "prg_01j9zqk3q7m4n5p6r7s8t9v0wx",
    "program_version_id": "pv_01j9zqk3q7m4n5p6r7s8t9v0wx",
    "field": "products[].price",
    "kind": "fill_rate_drop",
    "detail": "products[].price: fill rate 97% → 20% over the last 340 samples",
    "source": "statistics",
    "at": "2026-09-18T10:00:00.000Z"
  }
}

#credits.low

Allowance consumption crossed 80 % or 95 % this period; level says which. Sent once per level per period.

{
  "type": "credits.low",
  "data": {
    "balance": 120,
    "level": 80
  }
}

#credits.exhausted

Nothing more can be consumed: schedules and canaries pause and new jobs are refused. Sent once, until credits arrive.

{
  "type": "credits.exhausted",
  "data": {
    "balance": 0
  }
}

#credits.recharged

Credits arrived after the organisation ran out, or an auto-recharge completed. Paused schedules and canaries resume.

{
  "type": "credits.recharged",
  "data": {
    "balance": 5000
  }
}

#byo.unhealthy

One of your own providers (proxy, model or captcha solver) started failing its health checks.

{
  "type": "byo.unhealthy",
  "data": {
    "byo": "byo_01j9zqk3q7m4n5p6r7s8t9v0wx",
    "kind": "proxy",
    "status": "failing",
    "detail": "probe answered 407 Proxy Authentication Required"
  }
}

#byo.recovered

A BYO provider that was failing or degraded passed two health checks in a row and is healthy again.

{
  "type": "byo.recovered",
  "data": {
    "byo": "byo_01j9zqk3q7m4n5p6r7s8t9v0wx",
    "kind": "proxy",
    "status": "healthy"
  }
}

#webhook.disabled

Kaabist switched one of your webhook endpoints off after its last 100 deliveries failed over at least a day. Fix the receiver and set the endpoint's status to active again.

{
  "type": "webhook.disabled",
  "data": {
    "webhook": "whk_01j9zqk3q7m4n5p6r7s8t9v0wx",
    "reason": "auto",
    "failure_streak": 100,
    "failing_since": "2026-09-17T10:00:00.000Z"
  }
}

#ping

A test delivery you asked for. It goes only to that endpoint, and no event pattern selects it.

{
  "type": "ping",
  "data": {
    "webhook": "whk_01j9zqk3q7m4n5p6r7s8t9v0wx"
  }
}

Was this page helpful?