Prerequisites
API key from Dashboard
Get your API key from the Cadana Dashboard. See Authentication for details.
Compliance-approved business
Your business must have completed KYB verification. See KYB Requirements.
Account funded
Your business account must have sufficient funds to cover the payroll. See Fund Your Account.
Onboarded workers
Workers must be onboarded as Persons with payment methods configured — you’ll use their
personId to set up pay entries. See Onboard Workers.Step 1: Create a Payroll
Start by creating an empty payroll shell. Specify the worker type and whether this is a one-off or regular payroll. Response:payrollId — you’ll use it in the next steps.
Payroll Types
| Field | Values | Description |
|---|---|---|
workerType | EMPLOYEE, CONTRACTOR | Type of workers being paid |
type | ONE_OFF, REGULAR | One-off payment or recurring payroll |
Step 2: Save Entries
Add the pay date, pay period, and compensation entries for each worker. Each entry requires apersonId and salary amount.
If you set compensation info (compInfo) when onboarding the worker, you can retrieve it from the Person profile with GET /v1/persons/{personId} and use those values for the salary entry.
Returns 204 on success. The payroll status moves to saved. Fetch the payroll with GET /v1/payrolls/{id} to see the calculated debit — the total amount that will be debited from the business account.
Amounts are in the lowest denomination of the currency. For USD,
100000 = $1,000.00. For GHS, 500000 = GHS 5,000.00.Custom Metadata
You can pass atags object on both the create and save requests to store custom metadata against the payroll (e.g., internal reference IDs, department codes). This is a free-form object — any key-value pairs you include will be persisted and returned when you retrieve the payroll.
Custom Fees (Platforms)
Platforms can pass acustomFees array on the save request to add platform-specific fee line items to the payroll invoice. Each item requires a name and amount. These are additive — they supplement standard per-seat subscription fees and are included in the total amount collected by Cadana on your behalf.
Custom fee items do not participate in revenue share calculations. Validation returns
400 for empty names, non-positive amounts, or missing currency.Save Errors
When saving entries fails validation, the API returns400 with an invalid_request_body code. Each error in the params object is prefixed with a [ErrorType] tag you can use to programmatically filter or map errors.
Response format:
| Error Type | Description |
|---|---|
NoPaymentMethod | Person has no payment method configured |
PersonNotFound | Person ID does not match any person in the system |
EmptyWalletDetails | Wallet details are missing when payment method is wallet |
InvalidPreferredMethod | Preferred method is not a supported type |
RestrictedCountry | Beneficiary country is restricted for payments |
InvalidBankDetails | Bank payment validation failed (e.g., missing account name, invalid IBAN) |
InvalidMomoDetails | Mobile money validation failed (e.g., missing phone number, provider) |
InvalidWalletDetails | Wallet validation failed (e.g., invalid currency) |
InvalidCryptoDetails | Crypto wallet validation failed (e.g., missing address, unsupported chain) |
InvalidAchDetails | ACH payment validation failed |
InvalidSwiftDetails | SWIFT payment validation failed |
InvalidCardDetails | Card payment validation failed |
InvalidProxyDetails | Proxy payment validation failed |
InvalidPaymentDetails | Catch-all for unrecognized payment method types |
Step 3: Approve
Once you’re satisfied with the entries, approve the payroll. This triggers fund collection and schedules disbursement. Returns204 on success. The payroll status moves to approved.
After approval:
- If the business has insufficient funds, the payroll moves to
awaiting funds. If a bank account is connected, an ACH debit initiates automatically. - If the scheduled date is in the future, the payroll will be processed on the scheduled day.
- Once funds are available, the payroll processes and disburses payments to workers automatically.
Tracking Payroll Status
Poll the payroll to check its current status and see calculated totals. Response:List All Payrolls
Response:Status Flow
| Status | Meaning |
|---|---|
created | Empty payroll shell, no entries yet |
saved | Entries added, ready for approval |
approved | Approved, Cadana is collecting funds |
awaiting funds | Insufficient balance — payroll will proceed once funded |
scheduled | Funds collected, scheduled for the payroll date |
processing | Disbursements being sent to workers |
completed | All disbursements confirmed |
Webhooks
Subscribe to payroll and transaction events to track progress without polling. Payroll status changes:JSON
transaction.initiated, transaction.succeeded, transaction.failed) fire for each worker’s payment.
See Webhooks to configure your endpoint and Events for all event types.
Troubleshooting
| Issue | Cause | Solution |
|---|---|---|
401 Unauthorized | Invalid or missing API key | Check your API key in the Dashboard |
400 on save | Missing required fields | Ensure payrollDate, payPeriod, and at least one entry with personId and salary are provided |
Stuck in awaiting funds | Insufficient business account balance | Fund your business account, then the payroll will proceed automatically |
| Payroll won’t approve | Entries not saved | Save entries (Step 2) before approving |
Next Steps
Payroll Lifecycle
Full status flow, webhooks, and multi-currency handling
Onboard Workers
Set up Person records and payment methods
Webhooks
Real-time notifications for payroll and transactions
Workforce API Reference
Full API documentation