Replay a failed webhook
When a Lago webhook arrives but the downstream dispatch fails — a Lago customer didn’t update, a subscription change didn’t propagate, an invoice event didn’t reconcile — you can replay the persisted event from the admin console. Replay clones the original event row, attributes the replay to your operator account, and runs the clone through the same dispatch pipeline as the original. Use this runbook when triaging billing discrepancies reported by support, or when a known dispatch bug has been patched and you need to re-process events received during the outage window.
Prerequisites
Section titled “Prerequisites”- You are signed in with an account that has
role = "admin". Non-admin sessions are rejected with403. - You know the webhook event ID, or you can locate it in the admin webhook event log by filtering on customer, event type, or failure status.
- You have confirmed the original failure mode is no longer present. Replaying into the same broken state will just create a second failed event.
Procedure
Section titled “Procedure”-
Open the webhook event log
In the admin console sidebar, go to Billing → Webhook events.
Screenshot pending
Admin console webhook events list
-
Locate the failed event
Filter by Status: failed and narrow further by Lago customer or event type if needed. Click the event row to open its detail drawer. Confirm:
- The
event_typematches what you expect to replay. - The
payloadandreceived_atlook correct. replayed_from_idis empty. (If it’s already set, this row is itself a replay — find and replay the original instead, or replay this clone knowingly.)
- The
-
Replay the event
In the event detail drawer, click Replay.
The console posts to POST
/api/admin/webhook-events/[id]/replayand waits for the dispatch result inline. A200response means the clone dispatched successfully; a502means the clone was created but dispatch failed again — the response body contains theerrorstring and thenewEventIdof the clone.Screenshot pending
Replay confirmation showing new event ID
-
Open the replayed clone
From the success toast, click View replayed event, or navigate to the event log and open the row with
id = newEventId. Confirm:replayed_from_idpoints to the original event.replayed_by_user_idis your user ID.replayed_atis set to the moment you clicked Replay.
Verify
Section titled “Verify”- The replayed event row exists in Billing → Webhook events with
status = successand thereplayed_from_id/replayed_by_user_id/replayed_atfields populated. - The downstream effect landed. Depending on
event_type, check:- Lago customer / subscription events — the relevant Lago customer or Lago subscription record in the Polaris admin reflects the change.
- Invoice events — the invoice appears (or updates) under the customer’s billing tab.
- Metric events — the relevant Lago metric counters move on the next sync run.
- The original event row is unchanged. Replay never mutates the source row — it only writes a new clone.
If something goes wrong
Section titled “If something goes wrong”403 Forbidden: admin access required — your session isn’t an admin session. Sign out and back in with an admin account, or ask another operator to perform the replay.
400 Invalid event id — the event ID in the URL isn’t a valid integer. This usually means a malformed link; navigate back to the event log and click into the event row directly.
401 Unauthorized — your session expired mid-action. Re-authenticate and retry.
502 with success: false and an error string — the clone was written but dispatch failed again. The clone’s newEventId is returned in the response so you can inspect it.
Dispatch succeeded but the downstream record didn’t change — the handler may have treated the event as a no-op (for example, an idempotency_key already seen, or a state transition that’s already applied). Compare the payload against the current state of the target record before assuming the replay failed.
Audit and reversibility
Section titled “Audit and reversibility”Replay is not reversible. The clone runs through the same dispatch pipeline as a fresh inbound webhook, and any side effects it produces (Lago API calls, database writes, notifications) cannot be rolled back from this surface.
What gets logged:
- A new row in
lago_webhook_eventswithreplayed_from_id,replayed_at, andreplayed_by_user_idset. This is your audit trail — every replay is attributable to the operator who triggered it. - The dispatch pipeline’s own logs and any audit log entries the downstream handlers write.
If a replay produced an incorrect side effect, you will need to correct it through the relevant surface (manual Lago adjustment, customer-facing refund, etc.) rather than by “undoing” the replay.