Skip to main content

Status values and exceptions

These are the values you read out of the tables and the exceptions you may catch. All of them are public API: the string values are what is stored, so a migration or a report can rely on them.

Status values

DeliveryStatus — the outbound delivery log

Stored in webhook_deliveries.status.

CaseStoredMeans
PendingpendingQueued, not yet attempted or awaiting a retry
SucceededsucceededThe endpoint answered with a success status
FailedfailedAn attempt failed and another is still due
ExhaustedexhaustedEvery attempt is spent; nothing more will be tried

Failed and Exhausted are the distinction that matters when you alert: Failed is in flight, Exhausted is final and needs a human or a redelivery.

WebhookCallStatus — the inbound call log

Stored in webhook_calls.status.

CaseStoredMeans
ReceivedreceivedVerified and stored; the handler job has not finished
ProcessedprocessedYour handler completed
FailedfailedYour handler threw

A request whose signature does not verify is answered 401 and never stored, so it has no status — see Receiving.

VerificationStatus — the result of checking a signature

Returned inside a VerificationResult, not stored.

CaseStoredMeans
ValidvalidSignature matches and is inside the tolerance window
InvalidinvalidSignature does not match
ExpiredexpiredSignature matches but the timestamp is outside the window
MalformedmalformedThe header could not be parsed at all

Expired and Invalid are deliberately distinct: a clock-skew problem and a wrong-secret problem look identical if you collapse them, and they have different fixes.

HealthStatus — endpoint health scoring

Stored in webhook_subscriptions.health_status while health scoring is on.

CaseStoredMeans
HealthyhealthyDelivering normally
DegradeddegradedFailing enough to be worth watching
FailingfailingFailing badly enough to act on
UnknownunknownNot enough recent deliveries to judge

Unknown is not a mild Healthy — it means the score has no basis yet, so do not page on it.

OwnerKeyType — the shape of your tenant key

bigint, uuid or ulid. It is a configuration choice made before the first migration, because it decides the column type of every owner_id — see Choosing your database.

Exceptions

Worth catching

ExceptionThrown when
Webhooks\Exceptions\InvalidPayloadExceptionAn event payload fails the JSON Schema declared for its type. Thrown at dispatch, so you can reject the bad payload where it originates rather than discovering it in the delivery log
Webhooks\Core\Http\Exceptions\BlockedDestinationThe SSRF guard refused the destination — a private, loopback or link-local address, or a host outside your allowlist. See Security
Webhooks\Server\Exceptions\MissingSigningKeyAsymmetric signing is switched on but no key material is configured. A configuration error, not a runtime condition
Webhooks\Server\Exceptions\UnknownSignatureSchemeA configured scheme class does not resolve to a real scheme. Also a configuration error
Webhooks\Client\Exceptions\CorruptRawBodyA stored inbound call cannot return the bytes it received. Relevant if you replay from webhook_calls

Thrown inside the delivery engine

You will see these in logs and failed-job payloads; catching them in application code is usually the wrong layer, because the engine already handles them.

ExceptionThrown when
Webhooks\Core\Http\Exceptions\NonRetryableA failure that must not be retried. The delivery job marks the delivery final instead of scheduling another attempt
Webhooks\Server\Exceptions\DeliveryRefusedA queued delivery was refused before it left — its endpoint was switched off or deleted between queueing and sending
Webhooks\Core\Payload\Exceptions\OffloadFailedA large body could not be written to, or read back from, the offload disk. See Reliability
Webhooks\Core\Signing\Exceptions\InvalidMessageA WebhookMessage was constructed with inconsistent parts — a programming error in a custom scheme

The engine turns a failed attempt into a delivery row and a lifecycle event; listen to the events rather than catching inside the job.