Jobs and events

Every event type, its data, and how to list and replay events: what webhooks deliver, kept for a month.

An event records something that happened in your account, such as a job that ended or a balance that ran low. Each one is delivered to the webhook endpoints subscribed to its type, and GET /v1/events lists every event for 30 days, whether or not a webhook endpoint received it.

RouteWhat it doesKey scope
GET /v1/eventsList events, newest firstaccount:read
GET /v1/events/{id}Get an eventaccount:read
POST /v1/events/{id}/redeliverDeliver an event againadmin

The event object

The body of a webhook delivery is the event object, exactly as GET /v1/events/{id} returns it:

FieldTypeDescription
objectstringAlways event.
One of event
idstringThe event ID (evt_…): the webhook-id header of every delivery, the same on retries. Deduplicate on it.
typestringThe event type (event types table); new types may be added.
timestampstring (date-time)When it happened.
dataanyThe type's data object (small: a summary plus links).

Event types

TypeWhendata
job.completedA job ended with every item ended (check request_counts: items fail individually).JobEventData
job.canceledA canceled job ended: its running items finished.JobEventData
job.expiredA job reached its deadline; its unfinished items expired.JobEventData
credits.lowA balance change took the balance from above the account's low_balance_threshold to at or below it (once per crossing; the owner is emailed too).CreditsLowData
credits.depletedThe balance reached 0 (once, until credits are added). The owner is also emailed, at most once a day, whatever the notification settings say: it is how a leaked key is noticed.CreditsDepletedData
auto_topup.succeededAuto top-up bought its pack: the charge was paid and the pack's credits added (once).AutoTopupCharge
auto_topup.failedAn auto top-up charge failed (declined, or the bank asked the cardholder to confirm it): nothing was charged, auto top-up turned off and the owner was emailed why. It never retries: a person turns it back on.AutoTopupCharge
auto_topup.skippedThe balance crossed the auto top-up threshold, but buying the pack would have passed the monthly cap (the owner is emailed, once a month) or the account's limit per {trust_window_days} days (the owner is emailed how to lift it, once per {trust_window_days} days): nothing was charged. Auto top-up stays on.AutoTopupCharge
plan.renewedA monthly plan's payment went through: its credits were added and what was left of last month's ended (the first payment of a plan too).PlanEventData
plan.changedAn upgrade was paid: the new plan and a new month started now, and its credits were added.PlanEventData
plan.payment_failedA monthly plan's renewal payment failed: no new credits were added and the owner was emailed. Stripe retries it; the plan ends if the retries fail.PlanEventData
plan.endedA monthly plan ended (canceled, or its payment retries failed): the monthly credits left ended with it, pack and top-up credits stay, and the account is pay as you go.PlanEventData
api_key.spend_limit_reachedAn API key's request (or job) was refused for its spend limit, the first time in the limit's interval.SpendLimitReachedData
api_key.createdAn API key was created (not an account's first keys).APIKeyEventData
api_key.revokedAn API key was revoked.APIKeyEventData
api_key.secret_rotatedAn API key's secret was rotated: the key has a new secret (prefix), the old one works until its overlap ends.APIKeyEventData
webhook.testSent by POST /v1/webhook_endpoints/{id}/test to that endpoint only.WebhookTestData

New types may be added; ignore the ones you don't handle. Subscribe an endpoint to a family with a wildcard (job.*) or to everything with *, and filter GET /v1/events the same way with its type parameter.

Job events

job.completed, job.canceled and job.expired carry the job's summary and links, never its results:

FieldTypeDescription
objectstringOne of job
idstring
statusstringOne of queued, running, canceling, completed, canceled, expired
request_countsobject
request_counts.totalinteger
request_counts.queuedintegerNot started.
request_counts.runningintegerStarted (fetching, waiting for a retry or walking pages).
request_counts.succeededinteger
request_counts.failedinteger
request_counts.canceledinteger
request_counts.expiredinteger
creditsobject
credits.maxintegermax_credits: the most the job may spend.
credits.reservedintegerCredits its running pages may still use (0 once the job ends).
credits.chargedintegerCredits charged so far, each page once (items' prices; failed items are free).
metadataobject
created_atstring (date-time)
finished_atstring (date-time) or null
urlstringGET this (with your API key) for the job.
results_urlstringEvery result as JSON Lines, the job's signed results_url: it works without the API key for 1 hour after the event; GET url for a fresh one. Reading the event with a key without jobs:read, this is url instead: the link is a job's results, whatever key holds it.

url is the job (GET it with your API key); results_url is the job's own signed JSON Lines link to every result, which works without the key until it expires (GET url for a fresh one). GET /v1/events and GET /v1/events/{id} answer it only to a key that can read jobs (jobs:read); for any other it holds url.

Account events

The balance and spend events come from the account itself, api_key.created, api_key.revoked and api_key.secret_rotated from managing keys, and webhook.test from a test delivery. Their data:

credits.low

FieldTypeDescription
balanceintegerThe balance after the change that crossed the threshold.
low_balance_thresholdintegerThe account's low_balance_threshold at the time.

credits.depleted

FieldTypeDescription
balanceintegerThe balance: 0.

auto_topup.succeeded, auto_topup.failed, auto_topup.skipped

FieldTypeDescription
objectstringAlways auto_topup_charge.
One of auto_topup_charge
idstringTop-up ID (atu_…): the ref of its credit_transaction, and on the Stripe payment's metadata.
statusstringprocessing (the charge is under way), succeeded (paid: its credits were added, once), failed (nothing charged: auto top-up turned off, see reason) or skipped (it would have passed the monthly cap or the 7-day limit: nothing charged, auto top-up stays on).
One of processing, succeeded, failed, skipped
packstringThe credit pack (catalog pack ID).
creditsintegerCredits the pack adds.
amount_totalinteger or nullCharged, tax included, in cents of currency; null when nothing was charged or before it is known.
amount_taxinteger or nullThe tax in amount_total (Stripe Tax: only where SocialTap collects it); null when amount_total is.
currencystringamount_total's currency (ISO 4217).
One of usd
reasonstring or nullWhy it failed (the off_reason it set) or was skipped (monthly_cap, trust_limit: it would have passed rolling_limit_cents); null otherwise.
One of card_declined, authentication_required, no_card, billing_address_required, payment_failed, disputed, monthly_cap, trust_limit
messagestring or nullWhat the bank or Stripe said, for people; null when reason is.
created_atstring (date-time)When the balance crossed the threshold, RFC 3339 UTC.

plan.renewed, plan.changed, plan.payment_failed, plan.ended

FieldTypeDescription
planstringThe monthly plan (catalog plan ID).
creditsintegerCredits this event added; 0 when it added none.
current_period_endstring (date-time) or nullWhen the plan renews next, RFC 3339 UTC; null when it has ended.

api_key.spend_limit_reached

FieldTypeDescription
api_key_idstringThe key (key_…) whose spend limit was reached.
api_key_name?string or nullIts name (null if unreadable; absent from events sent before 2026-10-31).
spend_limitobjectIts spend limit.
spend_limit.amountintegerMost credits the key may spend per interval.
spend_limit.intervalstringCalendar day or month, UTC.
One of day, month
usedintegerCredits the key had used this interval (spent plus held by its requests in flight).
resets_atstring (date-time)Start of the next interval, RFC 3339 UTC: the key can spend again then.

api_key.created, api_key.revoked, api_key.secret_rotated

FieldTypeDescription
api_key_idstringThe key (key_…).
namestringIts label.
prefixstringThe secret's first characters, to recognize it.

webhook.test

FieldTypeDescription
webhook_endpoint_idstring

Last updated