Webhook Event Registry

Event schemas, webhook delivery, and idempotency for connected apps.

Use this registry to see which inbound event types LedgerLine accepts, which outbound webhook events are active, which provider webhook paths are optional, and which event patterns remain planned. The page is static documentation only: no live webhook tester, no secret input, and no external provider calls.

Inbound events

API-key authenticated events sent to /api/v1/events.

Outbound webhooks

Signed JSON POST deliveries to active endpoints.

Idempotency

Stable event ids and Idempotency-Key values keep retries safe.

Provider inputs

Stripe paths are optional; core accounting is provider-neutral.

Inbound event request

The active public API request uses `event_type`, `external_event_id`, and `payload`. Unsupported event types return validation errors.

POST /api/v1/events
Authorization: Bearer ll_test_replace_me
Content-Type: application/json
Idempotency-Key: evt_example_123

{
  "event_type": "payment.received",
  "external_event_id": "evt_example_123",
  "payload": {
    "external_payment_id": "pay_example",
    "external_invoice_id": "inv_example",
    "amount_cents": 25000,
    "currency": "USD",
    "processor": "other",
    "received_at": "2026-01-01T00:00:00.000Z"
  }
}

Inbound Event Registry

Event typeStatusBehavior
customer.createdaccepted/storedStores the event. It does not create a LedgerLine customer.
customer.updatedaccepted/storedStores the event. It does not update a LedgerLine customer.
invoice.createdaccepted/storedStores the event. It does not create or post an invoice.
invoice.voidedaccepted/storedStores the event. It does not void or reverse an invoice.
payment.receivedactiveStores the event and can process into the existing payment flow when payload validation and invoice matching pass.
payment.refundedaccepted/stored; active when mappedPublic API ingest stores it. Verified Stripe refund mapping can process supported full refunds.
credit.appliedaccepted/storedStores the event. Credit memo behavior remains future.
expense.createdaccepted/storedStores the event. It does not create expenses or journal entries.
estimate.createdplannedRecommended future pattern only; not accepted by /api/v1/events today.
vendor.createdplannedRecommended future pattern only; use the Vendor API today.
bill.postedplannedRecommended future pattern only; use the Bills API posting route today.
vendor_payment.postedplannedRecommended future pattern only; use the Vendor Payments API posting route today.
document.uploadedplannedRecommended future pattern only; use Document Center APIs today.

Outbound Webhook Registry

Event typeStatusBehavior
webhook.testactiveSent from the dashboard test action for active webhook endpoints.
invoice.postedactiveEmitted after successful invoice posting when connected app context exists.
payment.postedactiveEmitted after successful payment posting when connected app context exists.
invoice.paidactiveEmitted after payment posting when an invoice reaches paid status.
invoice.partially_paidactiveEmitted after payment posting when an invoice remains partially paid.
processor_payout.postedplannedType exists, but current manual payout flow does not emit it because dashboard-created payouts do not have connected app context.
journal_entry.postedplannedType exists for future ledger notifications; not broadly emitted today.
bill.postedplannedPlanned future outbound notification for A/P posting.
vendor_payment.postedplannedPlanned future outbound notification for vendor payment posting.
api_key.revokedplannedPlanned future security/audit notification.

Outbound webhook payload

{
  "id": "evt_delivery_uuid",
  "type": "payment.posted",
  "created_at": "2026-01-01T00:00:00.000Z",
  "environment": "test",
  "organization_id": "org_example",
  "connected_app_id": "app_example",
  "data": {
    "payment_id": "pay_example",
    "invoice_id": "inv_example",
    "amount_cents": 25000,
    "currency": "USD"
  }
}

Signature headers

Ledgerline-Signature: hex_hmac_signature
Ledgerline-Timestamp: 1767225600
Ledgerline-Event-Id: evt_delivery_uuid

Verify HMAC-SHA-256 over timestamp + "." + raw JSON payload. Respond quickly with 2xx, enqueue slow work, and deduplicate using the webhook event id. Review these rules in test mode before relying on webhooks for live-mode workflows.

Receiver example

The repo includes a fake-only Node receiver example at examples/webhook-receiver. It demonstrates server-side HMAC verification, sample payload signing, safe logs, and demo-only in-memory idempotency. It does not call LedgerLine APIs, mutate LedgerLine data, upload files, or connect providers.

External provider inputs

  • Stripe payment_intent.succeeded can map to payment.received when configured and verified.
  • Stripe invoice.paid can map to payment.received when LedgerLine invoice metadata and a Stripe payment reference are present.
  • Stripe charge.refunded can map to payment.refunded for supported full refunds.
  • Stripe payout.paid can process payout clearing when explicit gross, fee, and net metadata is present.
  • Stripe Checkout/payment collection, Plaid/bank feeds, OCR/AI parsing, IRS e-filing, and payroll/HR remain deferred unless implemented later.

Product boundaries

  • Core accounting does not require external provider webhooks.
  • The API Reference is read-only and never asks for real API keys or webhook secrets.
  • Webhook secrets must stay server-side and must not be logged.
  • Outbound webhook receivers should verify signatures and deduplicate event ids.
  • Production approval still requires setup/testing/security QA.

Registry docs

The repo registry gives deeper status labels, examples, retry behavior, error handling, and QA coverage.

Developer Docs

Build with the full developer surface

Pair event schemas with setup guidance, API recipes, OpenAPI, the read-only API Reference, and security boundaries.