Skip to main content
Built for accounting apps, ERPs, and platforms that manage invoicing for many businesses under a single integration. Modeled on Stripe Connect: you authenticate with your own platform API key and name the tenant to act on with an Invoice-Account header — no per-tenant keys to store.

Model

  • A platform is any organization. A connected account is an organization owned by it (parent). Each connected account is fully isolated: its invoices, fiscal profiles, downloads, events, and webhooks are scoped to it — the platform (and sibling accounts) can’t read them except by explicitly acting as that account.
  • One level only: a connected account cannot own connected accounts.
  • Connected accounts have no API keys. You always authenticate with the platform key.

1. Create connected accounts

Use your platform key, no header:
GET /v1/accounts lists them (cursor-paginated); GET /v1/accounts/:id retrieves one.

2. Act on behalf of a connected account

Send your platform key plus the Invoice-Account header with the connected account id. Every endpoint then reads/writes that account’s data:
Notes:
  • Prefer a query param? ?account=org_client123 works too; the header wins if both are sent.
  • Test vs live is still decided by the key (sk_test_ → sandbox, sk_live_ → live). A platform test key acting on a connected account operates on that account’s test data.
  • Naming your own platform org (or omitting the header) acts as the platform itself.
  • Acting on an account you don’t own returns 403 connect.account_not_authorized.

3. Manage a connected account

Rename, attach metadata, suspend, or delete an account with your platform key (no Invoice-Account header — you are managing the account, not acting as it):
metadata is string→string, merged on PATCH (send a key with an empty-string value to delete it).

4. Connect webhooks — every client’s events on one endpoint

Instead of registering a webhook per client, register one endpoint on the platform with connect: true. It receives events from all your connected accounts, and each delivery’s account field tells you which one:
Delivery body:
A non-connect endpoint only receives the owning org’s own events. (Every delivery carries account; for a normal endpoint it’s just the org itself.)

Reading a connected account’s event log / resources

Use the same acting-as header: GET /v1/events -H "Invoice-Account: org_client123", GET /v1/invoices -H "Invoice-Account: org_client123", etc.

Replaying a delivery

If your endpoint was down, replay an event to your endpoints with POST /v1/events/:id/resend. An empty body re-fans-out to every matching endpoint; pass { "webhook_endpoint_id": "we_..." } to target one. For a connect endpoint, act with the same Invoice-Account header as the account that owns the event. See Webhooks.