Before you start: You need a sandbox API key (see the Quickstart) and at least one funding source on file — the bank accounts and cards you’ve connected in the Nickel dashboard. Step 4 shows where to add one. Amounts are in cents throughout.
Create the vendor
A vendor is who you pay. Create one with
POST /vendor:Pass
"syncToQbo": true to also create the vendor in QuickBooks Online if your account has it connected — see QuickBooks.Add a delivery method
A delivery method is how the vendor receives funds. Set it yourself if you have their details — or better, let the vendor enter their own bank details so you never handle them.
- ACH (bank transfer)
- Check (mailed)
- Wire (international)
Create the bill
Record what you owe with Note the naming shift: the
POST /bill:billNumber you send comes back as reference. A new bill is Open and flips to Paid once a payment covers it — or as soon as one is scheduled (see step 5). The scheduledWithdrawalDate field distinguishes the two: non-null means scheduled, not settled.Pick your funding source
A funding source is one of your own payment methods — the bank account or card the bill is paid from. Funding sources are added in the dashboard, not through the API: in the Nickel dashboard, go to Settings → Bill Pay and click Add new, then either connect a bank account (Nickel walks you through linking it with Plaid) or enter a credit card.Once added, list the payment methods your organization can pay from with The
GET /billPaymentMethods:id is the merchantPaymentMethodId for the next step.Pay it
POST /bill/pay is a batch: each item names the bill, the vendor, your funding source, the vendor’s delivery method, and who to notify:- Per-bill failures land in
billErrors[]({billId, error}) while valid items still go through — check it on every call. Bills that are already paid, or that already have a pending scheduled payment, are reported here too (they no longer fail the whole batch) and are omitted frombillPayments[]so any pre-existing payments on those bills aren’t surfaced as if this batch created them. - Batch-level problems — like malformed input — fail the whole request with a top-level
{"error": "..."}instead.
withdrawalDateEpochMillis (when to debit you) or arrivalDateEpochMillis (when it should reach the vendor — Nickel back-computes the withdrawal date from the payment rail’s delivery time; dates too soon for the rail are rejected). A scheduled item creates no bill payment until the withdrawal day — instead the response acknowledges it in scheduled:GET /bill/{billId} reports the day in scheduledWithdrawalDate (and the bill already reads status: "Paid", even though nothing has moved yet). No webhook fires at scheduling time. On the withdrawal day the payment executes and rejoins the flow below — a real bill payment appears and bill_payment.succeeded or bill_payment.failed fires. A failed scheduled payment is not retried: the bill returns to Open and you submit a new POST /bill/pay. See Scheduled payments for the full contract.Track it
Poll
GET /billPayment/{billPaymentId} or subscribe to webhooks: bill_payment.succeeded, bill_payment.failed, and bill_payment.cancelled, plus the check lifecycle (check.sent → check.delivered → check.deposited, with check.returned / check.failed for problems) when paying by mailed check. An ACH bill payment sits in PENDING while the debit and transfer run their course — see the lifecycle.Cancel if you need to
A payment that hasn’t been sent to the payment network yet can be stopped with A scheduled payment has no bill payment to cancel yet — cancel it through its bill instead with The response is the refreshed bill —
POST /billPayment/{billPaymentId}/cancel:A cancelled payment currently reports
status: "FAILED" — the same terminal status as a genuine failure. Use the bill_payment.cancelled webhook (or the fact that you called cancel) to tell the two apart.POST /bill/{billId}/cancelScheduledPayment:status back to Open, scheduledWithdrawalDate back to null. A 404 means there’s no pending scheduled payment to cancel: it never existed, it already executed, or it was already cancelled (cancellation emits no webhook, so check GET /bill/{billId} when in doubt).Bills and bill payments you create through the API are never written to QuickBooks. Paying a bill that was imported from QuickBooks is — see QuickBooks for the full table.
Where to go next
Collect vendor bank details
Let vendors enter their own details on a secure form.
Receive webhooks
Hear about bill_payment and check events as they happen.
How bill payments work
The objects and lifecycle behind this guide.
QuickBooks
What does and doesn’t appear in your books.
