curl --request POST \
--url https://api.next.orenda.finance/v1/customers/{customerId}/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"
}
]
}
'{
"success": true,
"data": {
"totalAmount": "350.00",
"currency": "GBP",
"scaChallenge": {
"hash": "9f86d0...",
"nonce": "b1946ac9",
"timestamp": "2026-06-05T10:00:00Z"
}
}
}Pay a batch (single customer)
Steps 3 and 4. 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 single endpoint POST /v1/customers/{customerId}/batch-payments; the request and response bodies are identical, except that the single endpoint doesn’t accept a file.
initiatorId is ignored here; the path customerId is authoritative. Use POST /v1/batch-payments/submit to target customers by initiatorId.
curl --request POST \
--url https://api.next.orenda.finance/v1/customers/{customerId}/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"
}
]
}
'{
"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.
Path Parameters
The customer id.
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 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.