curl --request POST \
--url https://api.next.orenda.finance/v1/batch-payments/submit \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"action": "initiate",
"batchId": "3f1c8f9e-1d2b-4a3c-9e5f-6a7b8c9d0e1f",
"payments": [
{
"payer": {
"account": {
"type": "uk",
"sortCode": "010203",
"accountNumber": "12345678"
}
},
"payee": {
"name": "Ada Lovelace",
"account": {
"type": "uk",
"sortCode": "040506",
"accountNumber": "87654321"
}
},
"reference": "Invoice 1024",
"amount": "150.00"
},
{
"payer": {
"account": {
"type": "iban",
"iban": "DE89370400440532013000"
}
},
"payee": {
"name": "Grace Hopper",
"account": {
"type": "iban",
"iban": "FR7630006000011234567890189",
"bic": "AGRIFRPP"
}
},
"reference": "Invoice 1025",
"amount": "275.50"
}
]
}
'{
"success": true,
"data": {
"totalAmount": "350.00",
"currency": "GBP",
"scaChallenge": {
"hash": "9f86d0...",
"nonce": "b1946ac9",
"timestamp": "2026-06-05T10:00:00Z"
}
}
}Pay a batch (multi-customer)
Steps 3 and 4, multi-customer form. Pays a verified batch. The SCA challenge has to round-trip through the user, so this is a multi-step exchange against this one route and the action field says which step you’re on:
initiatereturnstotalAmount,currency, and anscaChallengefor the items you send.passkey-challenge(only if the user confirms with a passkey) returns apasskeySessionandfido2optionsto complete on the device. Send theOriginheader; it’s carried into the WebAuthn ceremony and a mismatch fails verification.submitsends the same items back with thescaChallengeand aconfirmation:{ "method": "passkey", "passkeySession", "assertion" },{ "method": "totp", "totp", "accessToken" }(theaccess_tokenfrom sign-in), or{ "method": "pin", "pin" }on programs with PIN step-up. Returns thebatchId.
Send exactly the items you sent to initiate. The challenge is bound to every row’s payee account and amount, in order, so adding, removing, reordering, or re-pricing a row between the two calls invalidates it. verify is rejected with 403; it belongs to the verify route.
A verified batch is required. batchId, the id verify returned, is required on both initiate and submit here; omitting it is a 400, not a new batch. The draft is checked for expiry and ownership and can be paid once: a second submit of the same draft is rejected before any money moves. passkey-challenge needs no batchId. The single endpoint keeps the older contract, where batchId is optional and omitting it creates a new batch.
Retries. Pass idempotencyKey (a UUID) as a body field; this route doesn’t read an Idempotency-Key header. Mint a fresh UUID for every batch. A batch key is not a replay key and isn’t scoped to the customer: two submissions that share a key land on the same batchId and run the submission again, reserving funds and sending the payments a second time, and a reused key with a different list of payments isn’t rejected. If a submit response is lost, don’t resend; fetch the batch, or list the customer’s batches, to see whether it landed. Optional today, required in a future release.
Rollout. The split verify and submit routes are enabled per program and return 403 until yours is. Until then, send the same action to the path-less single endpoint POST /v1/batch-payments; the request and response bodies are identical, except that the single endpoint doesn’t accept a file.
Back office only, multi-customer. No customerId in the path: each item’s payer account is resolved globally and authorised per item against the caller, so one batch can pay from the accounts of any customers the caller is responsible for. An account the caller isn’t responsible for, including an unassigned account, is rejected with 401, as is a management role that resolves to no customers. A non-management caller can’t use this route.
The passkey is always the operator’s own. The challenge is issued against the signed-in user, never the customer being paid. The ceremony is identical to the single-customer route; only the tenant the credential is looked up in differs: a customer’s passkey is resolved against their own program (honouring the sandbox flag), a management operator’s against the shared management pool, production only. So a management passkey ceremony always resolves to production, even for a sandbox batch.
curl --request POST \
--url https://api.next.orenda.finance/v1/batch-payments/submit \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"action": "initiate",
"batchId": "3f1c8f9e-1d2b-4a3c-9e5f-6a7b8c9d0e1f",
"payments": [
{
"payer": {
"account": {
"type": "uk",
"sortCode": "010203",
"accountNumber": "12345678"
}
},
"payee": {
"name": "Ada Lovelace",
"account": {
"type": "uk",
"sortCode": "040506",
"accountNumber": "87654321"
}
},
"reference": "Invoice 1024",
"amount": "150.00"
},
{
"payer": {
"account": {
"type": "iban",
"iban": "DE89370400440532013000"
}
},
"payee": {
"name": "Grace Hopper",
"account": {
"type": "iban",
"iban": "FR7630006000011234567890189",
"bic": "AGRIFRPP"
}
},
"reference": "Invoice 1025",
"amount": "275.50"
}
]
}
'{
"success": true,
"data": {
"totalAmount": "350.00",
"currency": "GBP",
"scaChallenge": {
"hash": "9f86d0...",
"nonce": "b1946ac9",
"timestamp": "2026-06-05T10:00:00Z"
}
}
}Authorizations
The caller's access_token from authentication. Management API callers send the id_token. The program and environment come from the token.
Query Parameters
Required on the Management API, where the token carries no program: omitting it returns 400. Customer API callers resolve the program from their token and should omit it; a value sent there is ignored.
Body
Required: initiate, passkey-challenge or submit. verify is rejected with 403; it belongs to the /batch-payments/verify route.
initiate, passkey-challenge, submit Management only. Targets a single customer on this path-less route: the only way to scope to one customer here. Omit to act across every customer the caller is responsible for.
"customer-123"
The payment items. Required for initiate and submit, and must be identical between them or SCA verification fails.
Show child attributes
Show child attributes
The strong-customer-authentication challenge from initiate. Pass it back on submit.
Show child attributes
Show child attributes
Step-up confirmation (for submit). Set method to passkey, totp, or pin and include that method's fields. pin is a program capability: see Program capabilities.
- Passkey
- 2FA code
- PIN
Show child attributes
Show child attributes
Optional UUID, and mint a fresh one for every batch. This is not a replay key: two submissions that share it land on the same batch and run it again, so a retry can pay twice. If a response is lost, don't resend; fetch the batch instead.
Required. The draft returned by verify. This route only pays a batch that was verified first, so initiate and submit both need it. It is checked for expiry and ownership and cannot be paid twice.
Legacy step-up credential. Superseded by confirmation.
Legacy TOTP step-up code. Superseded by confirmation.
Legacy passkey session id. Superseded by confirmation.
Legacy passkey assertion. Superseded by confirmation.