Webhooks & Events

Understand how Penny delivers resource changes to your integration.

Penny uses webhooks to notify your integration when supported resources or platform activity changes.

Penny ResourceSOURCEWebhook EventEVENTNotification EndpointENDPOINTDeliveryDELIVERYCustomer ApplicationRECEIVER

Webhook Events

A Webhook Event represents a supported resource or platform event generated by Penny.

Events identify what happened and provide the information required for your integration to process the change.

What it’s for: a fact record of one change — for example card.issued or transaction.created — that your integration reacts to instead of polling for changes.

See the Event Catalog for supported event types.

Notification Endpoints

A Notification Endpoint is an HTTPS endpoint registered by your integration to receive webhook events.

An endpoint defines where Penny sends events and which supported event types it subscribes to.

What it’s for: one registered destination, scoped to exactly the event types (trigger_events) and, optionally, the specific object IDs (filter_identifiers) you care about — so you don’t have to filter out irrelevant events on your own side.

How it behaves: registration is asynchronous — creating one returns pending_setup while Penny provisions delivery infrastructure, then moves to pending_verification once ready. An endpoint won’t deliver events until it’s verified: Penny sends a challenge to the URL, and you submit the code back. Only a verified, active endpoint receives deliveries — it can also be deactivated (paused, resumable), suspended (by Penny), or archived (archived with DELETE; no longer delivers). Add or remove subscribed event types afterward without recreating the endpoint (PATCH/DELETE on trigger-events).

See Subscribing to Webhooks.

Deliveries

A Delivery tracks Penny’s attempts to send one event to one Notification Endpoint.

Delivery behavior includes:

  • request signing;
  • successful and failed attempts;
  • retry behavior;
  • delivery history.

What it’s for: treat the event and its delivery separately — an event records what happened inside Penny, while a delivery records Penny’s attempts to notify your endpoint about it. One event can produce multiple deliveries (one per matching endpoint), each with its own independent retry state.

How it behaves: when the endpoint has a signing secret (created separately from the endpoint, returned once, and rotatable), each request carries a Penny-Webhook-Timestamp header and a Penny-Webhook-Signature header: an HMAC-SHA256 over the timestamp and body, keyed with that secret. Status belongs to the delivery, not the event: each delivery is pending, pending_retry, delivered, or failed. A failed attempt is retried up to 10 times on a fixed schedule before the delivery is marked failed. List an event’s deliveries with GET /notifications/webhooks/events/{notification_event_id}/deliveries.

Receiving events

Your application should:

  1. receive the raw webhook request;
  2. verify the Penny signature where signing is enabled;
  3. acknowledge the delivery;
  4. process the event safely;
  5. handle duplicate or retried deliveries.

See Overview & Delivery Behavior for the webhook lifecycle and security model.

Live Decisioning

Everything above describes asynchronous events — Penny tells you something already happened, and there’s nothing to respond with. Live Decisioning is different: it’s a synchronous approve/decline request Penny sends to one of your webhook endpoints in the middle of authorizing a transaction, configured through a Spend Control’s live_decisioning rule rather than an endpoint subscription.

See Live Decisioning for the full request/response contract, and Spend Controls for where it fits in the authorization hierarchy.