Skip to main content
Every event arrives in the same envelope. This page lists each type, when it is sent and what its data holds. The examples are the exact JSON a signed webhook endpoint receives. Slack and Discord get the same event drawn as a message (see Slack and Discord).

Versioning

Each event carries api_version, a date naming the format it follows. The examples below show the current one. Within one version:
  • data is open. New keys can appear in any event at any time, so ignore keys you do not use and never reject an event for having one you do not know.
  • An existing key never changes its meaning or its type.
  • New event types can be added. An endpoint set to All events receives them; one set to Choose events only gets what it picked.
A change that would break a receiver comes with a new api_version.

Choosing events

In Settings > Webhooks, each endpoint has an Events setting: All events, or Choose events to pick from the groups below. webhook.test is the exception: it goes to the endpoint you test, whatever it subscribes to. Fields are snake_case. Money is in USD as a number (412.37), times are ISO 8601 in UTC, and ids are UUIDs. In instance events, deployment_id is the instance id you get from the API, CLI and MCP tools.

Budgets

budget.threshold_reached

An environment’s month to date reached 80% of its monthly budget. When: Once per environment, month and budget amount, when the month to date first reaches 80% of the budget. Raising the budget can send it again at the new amount. Owners and admins also get an email.
Example

budget.reached

An environment spent its full monthly budget: launches are refused, instances stop and its API keys are declined. When: Once per environment, month and budget amount, when the month to date reaches the budget. From then on launches in the environment fail with HTTP 402, its running instances are terminated (each sends instance.auto_stopped with stop_reason budget) and its API keys are declined, until the next UTC month or until the budget is raised. Owners and admins also get an email.
Example

Instances

instance.ready

An instance or crate is running and reachable over SSH and its ports. When: Once per launch, when the instance or crate reaches running.
Example

instance.launch_failed

A launch did not start. Nothing was charged for it. When: When a launch ends before the instance ever ran. A launch that never ran is not billed.
Example

instance.runtime_ending

An instance is 10 minutes from its max runtime. When: Ten minutes before an instance reaches its max runtime. Changing the max runtime sends a fresh one ten minutes before the new stop time. Owners and admins also get an email.
Example

instance.auto_stopped

Runcrate stopped an instance: max runtime, idle stop, a budget or a low balance. When: When Runcrate terminates an instance on its own: stop_reason is max_runtime, idle, budget or low_balance. The same termination also sends instance.stopped. Owners and admins also get an email.
Example

instance.stopped

An instance was terminated for any reason. stop_reason says why. When: Every time an instance is terminated, whoever or whatever stopped it.
Example

Jobs

Every job event also carries attempt (1-based), attempts_count, group_id (null for a single job) and tags. A job’s own webhook_url gets its job.started and job.finished too, signed the same way (see Jobs: idempotency and callbacks).

job.queued

A job is waiting: no GPU it asked for has capacity yet, or its environment’s budget is spent. When: Once per attempt, when the job starts waiting. It is tried again until its capacity_wait_minutes are over, then it fails.
Example

job.started

A job’s command started running on its machine. When: When a job’s machine is ready and its command starts: once per attempt.
Example

job.finished

A job ended: succeeded, failed, timed out or cancelled. When: Once per job, when it reaches a final status (a retried attempt does not end the job). A job whose machine never started gets one too, with status failed or cancelled and null for what never happened.
Example

Schedules

schedule.failed

A scheduled launch did not start. When: When a scheduled run was due and did not start. Nothing is charged for it. When the failure is the 5th scheduled run in a row, the schedule is paused and schedule.paused is sent instead. See schedules. Owners and admins also get an email.
Example

schedule.paused

A schedule was turned off: 5 scheduled runs in a row failed, or who it runs as lost access. When: When Runcrate turns a schedule off: 5 scheduled runs in a row failed, the person it runs as left the workspace, or the API key or agent sign-in behind it was revoked or ended. It does not run again until someone resumes it. Owners and admins also get an email.
Example

Billing

balance.low

The balance is running low. When stops_at is set, running instances stop then unless money is added. When: When the workspace balance falls under $10, and again when it falls under $1 and a grace period starts: running instances stop at stops_at unless funds arrive. Add funds or turn on auto-recharge to keep instances running. Workspace-wide: the envelope’s environment_id is null.
Example

balance.depleted

The balance ran out and running instances were stopped. When: When the workspace balance runs out. Running instances are terminated, each with stop_reason low_balance. Workspace-wide: the envelope’s environment_id is null.
Example

credits.added

A payment or top-up was added to the workspace balance. When: When money is added to the workspace balance: a top-up, an auto-recharge or an adjustment. Workspace-wide: the envelope’s environment_id is null.
Example

Storage

storage.suspended

A storage volume was suspended because its storage could not be paid for. When: When a storage volume is suspended because the workspace could not pay for it. storage.reactivated follows once it is paid for. Workspace-wide: the envelope’s environment_id is null.
Example

storage.reactivated

A suspended storage volume is available again. When: When a suspended volume is paid for and can be attached again. Workspace-wide: the envelope’s environment_id is null.
Example

Webhooks

webhook.test

Sent by Send a test event. Never sent on its own. When: Only when someone presses Send a test event, and only to that one endpoint, whatever events it subscribes to. You cannot subscribe to it. Each person can send 10 tests per 10 minutes. Workspace-wide: the envelope’s environment_id is null.
Example

webhook.disabled

An endpoint kept failing (3 days with no success and at least 10 failed attempts, or 20 events in a row given up on), so Runcrate turned it off. When: When Runcrate turns an endpoint off (see automatic turn-off). It goes to your other endpoints that subscribe to it, never to the one turned off. Owners and admins also get an email. Workspace-wide: the envelope’s environment_id is null.
Example

Verifying signatures

Check that an event came from Runcrate.

Retries and the delivery log

What happens when your endpoint does not answer.

Spend guardrails

Max runtime, idle stop and monthly budgets, which send the budget and auto stop events.

Best practices

Dedupe, ordering and keeping the secret safe.