Skip to content
Ledgerline Help

Webhooks overview

Updated 21 September 20263 min read

On this page

Webhooks push events to your server the moment something happens, so you never have to poll. Register an HTTPS endpoint, choose the events you care about and Ledgerline sends a signed POST request for each one.

How it works

  1. Something changes in Ledgerline, for example a payout is paid.
  2. Ledgerline records an event with a unique id and a snapshot of the object.
  3. We deliver the event to each subscribed endpoint as a JSON POST.
  4. Your endpoint verifies the signature, stores the event and answers with a 2xx status within 10 seconds.
  5. If it does not, we retry on a schedule.

Register an endpoint

In the dashboard, open Developers > Webhooks, or use the API:

curl https://api.ledgerline.dev/v1/webhook_endpoints \
  -H "Authorization: Bearer $LEDGERLINE_API_KEY" \
  -H "Idempotency-Key: 9a1c5e7b-3d20-4b8a-8f66-7e2c1d0a4b35" \
  -d url="https://example.com/hooks/ledgerline" \
  -d "enabled_events[]=payout.paid" \
  -d "enabled_events[]=payout.failed" \
  -d "enabled_events[]=payout.returned"

The response includes the signing secret, which starts with whsec_. It is shown once. Use it to verify signatures.

Endpoints must use HTTPS with a certificate from a public authority. Plans allow 5 endpoints on Starter, 25 on Growth and 100 on Scale. See Limits and quotas.

The event envelope

{
  "id": "evt_01JA7E2Q9R",
  "type": "payout.paid",
  "api_version": "2026-09-01",
  "created_at": "2026-09-21T11:20:05Z",
  "livemode": true,
  "data": {
    "object": {
      "id": "pay_01JA6D4H2K",
      "status": "paid",
      "amount": 1250000,
      "currency": "USD"
    }
  }
}

api_version is the version used to render the object, which is the version your endpoint is configured for and not necessarily your account default. livemode is false for sandbox events. Payloads are at most 256 KB.

Event types

Event Fired when
transaction.posted A transaction becomes posted.
transaction.reversed A transaction is reversed.
transfer.created An internal transfer completes.
payout.created A payout is accepted.
payout.submitted A payout is sent to the bank or network.
payout.paid Delivery is confirmed.
payout.failed A payout is rejected before delivery.
payout.returned A delivered payout is sent back.
payout.canceled A payout is canceled.
counterparty.verified A counterparty bank account passes verification.
kyb.status_changed Your business verification status changes.
statement.ready A monthly statement can be downloaded.
reconciliation.completed A daily reconciliation run finishes.
reconciliation.discrepancy A run finds a difference that needs review.
fx.conversion.completed A currency conversion is booked.
api_key.rolled An API key is rolled.

Subscribe only to what you handle. Use enabled_events[]=* to receive everything, including events added later.

Handling events well

  • Respond fast, work later. Store the event, return 200 and process it from a queue. A slow handler times out at 10 seconds and gets retried.
  • Expect duplicates. Delivery is at least once. Deduplicate on event.id.
  • Do not rely on order. payout.paid can arrive before payout.submitted after a retry. Use the object's status and timestamps, or fetch the latest state from the API.
  • Verify first. Reject unsigned or incorrectly signed requests with 400.

Tip

Fetch the object from the API when ordering matters. The event tells you something changed; GET /v1/payouts/{id} tells you what is true now.

Testing

In the sandbox, endpoints receive events for sandbox activity. From the dashboard you can send a test event of any type to an endpoint. To rehearse a failure path, advance a sandbox payout as described in Sandbox.

Listing and replaying events

GET /v1/events lists events from the last 30 days. Replay one with POST /v1/events/{id}/redeliver. More in Webhook delivery and retries.