Migrate from a situation
Migrate manual bank payouts to the Lumx API
A copy-paste prompt that turns a spreadsheet and a bank portal into an API payout run — beneficiaries become destinations, with no double payment.
// PROMPT
{ "type": "INDIVIDUAL", "name": "William Default", "taxId": "100.100.100-01", "birthDate": "1990-01-01" }
You are a senior backend engineer replacing a manual payout process — a spreadsheet of beneficiaries and a human in a bank portal — with the Lumx API, without paying anyone twice during the cutover.
Ground truth. Read both before writing any code and follow them over any prior knowledge:
1. https://docs.lumx.io/llms.txt — the documentation index. Every page has a .md twin at its own path.
2. https://lumx-docs-public-prod.s3.us-east-1.amazonaws.com/api-production.yaml — the OpenAPI 3.1 spec. Take field names, required flags and enum values from here.
Work against sandbox at https://api-sandbox.lumx.io with a server-side key sent as "Authorization: Bearer <key>". Do not touch production in this task.
1. Read the current spreadsheet and produce a mapping table before writing code: one row per column, with the destination field it maps to, or "no equivalent". Flag every unmapped column instead of guessing — that table is the deliverable a human reviews.
2. Onboard the paying entity with POST /customers and take it to APPROVED. Payouts debit that customer's own wallet; there is no pooled balance.
3. Convert each beneficiary to a destination with POST /destinations. The body is a union, one branch per rail, so the required identifier differs: PIX takes keyType and keyValue, SPEI takes clabe, ACH and FEDWIRE take accountNumber and routingNumber with a bank object, SWIFT and SEPA take iban or bic with a bank object.
4. Set holder.relationship per beneficiary from the closed enum — SUPPLIER, EMPLOYEE, CREDITOR, CUSTOMER and the rest, or SELF for the company's own account. A spreadsheet rarely records this. Leave a row unmigrated and report it rather than picking a value.
5. Pay with POST /transactions/off-ramp, one call per beneficiary, each carrying an Idempotency-Key that is a UUID v4 generated once per row and written to the run record before the call. Rerunning after a crash reads the stored key back; minting a new one pays twice. The same key with a different body returns 409.
6. Walk the run sequentially and paginate reads with size and cursor. Collect failures into an exception list keyed on the error code — INSUFFICIENT_BALANCE, RAIL_NOT_ENABLED, HOLDER_TAX_ID_MISMATCH, DESTINATION_NOT_FOUND — never on the message, which changes. Confirm each settled payout with GET /transactions/{id}.
7. Run both processes for one cycle: the manual run stays the source of truth while the API run writes to a shadow ledger, and reconcile the two on amount, beneficiary and date before you cut over.
Constraints:
- Do not state a rate limit for the batch. None is published. Handle 429 TOO_MANY_REQUESTS with exponential backoff and keep the run resumable.
- Every payout must be your own obligation to your own counterparty. Read /compliance/nested-payments and stop if the spreadsheet contains someone else's beneficiaries.
- purpose comes from the request schema enum, and PERSONAL_ACCOUNT is only valid with a SELF destination.
Deliverables:
- The column mapping table, including the unmapped columns.
- A resumable batch runner with deterministic idempotency keys.
- An exception report grouped by error code.
- A reconciliation script comparing the shadow run against the manual one.
Export the current spreadsheet to CSV and hand the agent a redacted copy — real beneficiary data does not need to be in the prompt for the mapping to work.
Decide the holder relationship for every row the agent leaves unmigrated. This is the step that cannot be automated and the one that blocks a real cutover.
Keep the manual process running for the first full cycle. Cut over only after the reconciliation script is quiet.
Discover how our infrastructure can seamlessly integrate stablecoins into your financial operations quickly, securely, and efficiently.

