Platform Invoices Guide
The Platform Invoice API lets you create, manage, and send invoices on behalf of businesses that have granted your platform access. Invoices are sent to recipients via email and can be paid through the Oncade payment flow.
Required scopes
invoice:create, invoice:read, invoice:update,invoice:send, invoice:cancel
All requests require the X-Target-Business-Id header and a grant from the target business.
Invoice lifecycle
Invoices move through a defined set of states. Understanding the lifecycle helps you integrate the correct API calls at the right time.
| Status | Meaning |
|---|---|
draft | Invoice created but not yet delivered to the recipient. Not visible via the public invoice link. |
sent | Invoice delivered to the recipient via email. The recipient can now view and pay it. |
processing | An ACH payment has been initiated and is awaiting settlement. |
paid | Payment received. Terminal state. |
cancelled | Invoice cancelled by the creator. Terminal state. |
Draft invoices must be sent. When you create an invoice without setting status to "sent", it defaults to draft. Draft invoices are not visible to the recipient and no email is sent. You must explicitly send them via POST /v1/platform/invoices/{id}/send or create the invoice with "status": "sent" in the request body.
Creating invoices
Step 1: Create a draft invoice
Create an invoice in draft status to review it before delivering to the recipient. Omit the status field or set it to "draft".
curl -s -X POST \
-H "Authorization: Bearer $PLATFORM_KEY" \
-H "X-Target-Business-Id: $BIZ_ID" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"receiverName": "Acme Corp",
"receiverEmail": "billing@acme.com",
"date": "2026-04-12",
"dueDate": "2026-05-12",
"payToTarget": "BUSINESS",
"items": [
{
"description": "Consulting — April 2026",
"quantity": 1,
"rate": 5000,
"amount": 5000
}
]
}' \
https://<host>/api/v1/platform/invoicesRequired fields
| Field | Type | Description |
|---|---|---|
receiverName | string | Name of the invoice recipient |
receiverEmail | string | Email address where the invoice will be delivered |
date | string | Invoice date (ISO 8601) |
payToTarget | string | BUSINESS — payment goes to the business payout wallet |
items | array | At least one line item with description, quantity, rate (dollars), amount (dollars) |
Environment is derived from your API key. The invoice environment (test or live) is automatically determined by which API key you authenticate with. You do not need to pass environment in the request body. Currency defaults to USD and does not need to be specified.
Optional fields
| Field | Type | Description |
|---|---|---|
invoiceNumber | string | Custom invoice number. Auto-generated if omitted. |
dueDate | string | Payment due date (ISO 8601). Must be on or after date. |
tax | number | Tax amount in dollars. Added on top of the subtotal. |
total | number | Expected total for validation. Server rejects if it differs by more than $0.01. |
note | string | Free-text note displayed to the recipient. |
metadata | object | Arbitrary key-value data stored with the invoice. |
status | string | Set to "sent" to create and immediately send. Defaults to "draft". |
fees | array | Platform fee line items (see Fees below). |
Pay-to target
The payToTarget field determines where the invoice payment is routed.
Use BUSINESS for platform invoices. When creating invoices via the Platform API, payToTarget should be set to "BUSINESS". This routes payment to the business's configured payout wallet. The MY_ACCOUNT target is not supported for platform-created invoices.
The business must have a payout wallet configured before invoices can be created with the BUSINESS target. If the wallet is not set, the API returns a 400 error.
Step 2: Send the invoice
If you created the invoice as a draft, send it to the recipient with a separate call. This transitions the status to sent and triggers the delivery email.
curl -s -X POST \
-H "Authorization: Bearer $PLATFORM_KEY" \
-H "X-Target-Business-Id: $BIZ_ID" \
https://<host>/api/v1/platform/invoices/$INVOICE_ID/sendCreate and send in one step
To skip the draft phase, include "status": "sent" in the create request. The invoice is created and the email is sent immediately.
curl -s -X POST \
-H "Authorization: Bearer $PLATFORM_KEY" \
-H "X-Target-Business-Id: $BIZ_ID" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"receiverName": "Acme Corp",
"receiverEmail": "billing@acme.com",
"date": "2026-04-12",
"payToTarget": "BUSINESS",
"status": "sent",
"items": [
{ "description": "Widget license", "quantity": 10, "rate": 25, "amount": 250 }
]
}' \
https://<host>/api/v1/platform/invoicesInvoice fees
Invoice fees work the same way as distribution fees. There are two categories applied on top of the invoice total:
| Type | Source | When applied |
|---|---|---|
| Oncade service fee | Auto-applied from the business's pricing configuration (or the global default) | Always — cannot be opted out of |
| Platform fees | Passed by your platform in the fees array at creation time | Only when included in the request |
The response includes a paymentSummary with the breakdown: invoiceAmount (the invoice total), payerFee (sum of all fees), and totalCharged (what the payer pays). Fees are charged to the payer, not the business.
Attaching platform fees
Pass a fees array in the create request. Each entry requires a recipientWallet — the wallet address that receives this fee payment.
curl -s -X POST \
-H "Authorization: Bearer $PLATFORM_KEY" \
-H "X-Target-Business-Id: $BIZ_ID" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"receiverName": "Acme Corp",
"receiverEmail": "billing@acme.com",
"date": "2026-04-12",
"payToTarget": "BUSINESS",
"items": [
{ "description": "Service agreement", "quantity": 1, "rate": 10000, "amount": 10000 }
],
"fees": [
{
"label": "Platform Processing Fee",
"percentage": 2.5,
"flat": 50,
"recipientWallet": "0xYourPlatformWallet"
}
]
}' \
https://<host>/api/v1/platform/invoices| Fee field | Type | Description |
|---|---|---|
label | string | Display name for this fee |
percentage | number | Percentage of the invoice total (0–100). Defaults to 0. |
flat | number | Flat fee in cents. Defaults to 0. |
recipientWallet | string | Wallet address that receives this fee |
Heads up: Fee amounts are calculated at creation time and stored on the invoice. The payer sees the full totalCharged (invoice amount + all fees) at payment time.
Managing invoices
Listing invoices
Retrieve invoices for a business with optional pagination and status filtering.
curl -s \
-H "Authorization: Bearer $PLATFORM_KEY" \
-H "X-Target-Business-Id: $BIZ_ID" \
"https://<host>/api/v1/platform/invoices?page=1&limit=20&status=sent"Supports page, limit (max 100), and status query parameters.
Getting a single invoice
curl -s \
-H "Authorization: Bearer $PLATFORM_KEY" \
-H "X-Target-Business-Id: $BIZ_ID" \
https://<host>/api/v1/platform/invoices/$INVOICE_IDUpdating an invoice
Use PUT to update any non-terminal invoice (draft or sent). The full invoice body is required (this is a full replacement, not a partial update). Totals and payouts are recalculated server-side, but fee line items are determined at creation time and are not recalculated on update.
curl -s -X PUT \
-H "Authorization: Bearer $PLATFORM_KEY" \
-H "X-Target-Business-Id: $BIZ_ID" \
-H "Content-Type: application/json" \
-d '{
"receiverName": "Acme Corp",
"receiverEmail": "billing@acme.com",
"date": "2026-04-12",
"payToTarget": "BUSINESS",
"items": [
{ "description": "Consulting — April 2026", "quantity": 1, "rate": 7500, "amount": 7500 }
]
}' \
https://<host>/api/v1/platform/invoices/$INVOICE_IDTerminal invoices cannot be modified. Once an invoice reaches paid or cancelled status, it cannot be updated.
Cancelling an invoice
Cancel a draft or sent invoice. Cancelled is a terminal state.
curl -s -X POST \
-H "Authorization: Bearer $PLATFORM_KEY" \
-H "X-Target-Business-Id: $BIZ_ID" \
https://<host>/api/v1/platform/invoices/$INVOICE_ID/cancelAPI Quick Reference
All invoice endpoints are under /v1/platform/invoices.
| Method | Path | Scope | Purpose |
|---|---|---|---|
GET | /invoices | invoice:read | List invoices (paginated, filterable by status) |
POST | /invoices | invoice:create | Create invoice (draft or sent) |
GET | /invoices/{id} | invoice:read | Get invoice details |
PUT | /invoices/{id} | invoice:update | Update a non-terminal invoice |
POST | /invoices/{id}/send | invoice:send | Send a draft invoice (triggers email) |
POST | /invoices/{id}/cancel | invoice:cancel | Cancel a non-terminal invoice |
GET | /invoices/export | invoice:read | Export invoices as CSV |