Documentation Index
Fetch the complete documentation index at: https://docs.lumx.io/llms.txt
Use this file to discover all available pages before exploring further.
Build a payroll product where your customers (employers) pay their employees and contractors anywhere in the world using stablecoin rails. Each employer is onboarded as a business customer. You register their payees as destinations and trigger payouts on their behalf; Lumx converts stablecoin to local fiat and settles into each payee’s account.
Step 1: Generate your API key
Head over to dashboard.lumx.io. Once logged in, generate a new API key and store it securely. See Authentication for details.
Step 2: Onboard the employer
For each employer using your product, create a business customer.
curl -X POST https://api-sandbox.lumx.io/customers \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"type": "BUSINESS",
"legalName": "Acme Inc.",
"taxId": "42.887.120/0001-00",
"incorporationDate": "2020-01-01",
"country": "BRA",
"email": "finance@acme.com",
"accounts": ["USD"]
}'
Before the employer can transact, they must accept Lumx’s terms of service (POST /customers/{id}/tos) and complete KYB. See Business verification for the full onboarding flow.
Step 3: Fund the employer’s wallet
Once the employer’s USD account is ACTIVE, create an on-ramp transaction with the exact amount the employer plans to deposit. The response includes wire instructions for that specific deposit. Share them with the employer’s finance team. When the wire lands matching the amount, Lumx converts USD to stablecoin and credits the employer’s wallet.
curl -X POST https://api-sandbox.lumx.io/transactions/on-ramp \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"customerId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"rail": "FEDWIRE",
"sourceCurrency": "USD",
"sourceAmount": "50000.00",
"targetCurrency": "USDC",
"purpose": "PERSONAL_ACCOUNT"
}'
Each deposit must be matched to an on-ramp transaction created in advance with the exact amount.
If the employer already holds stablecoin on-chain, they can also transfer it directly to the wallet returned at customer creation, no on-ramp needed.
Subscribe to the onramp.success webhook to know the moment the wallet is funded and ready to run payouts. For the full deposit flow by rail, see Global accounts.
Step 4: Register each payee’s destination
For each employee or contractor the employer wants to pay, register a destination under the employer’s customer record. Set holder.relationship to EMPLOYEE so the destination is correctly categorized for compliance. The taxId format varies by country; see Tax IDs by country and Coverage for the full list of supported rails and currencies.
PIX (BRL)
SPEI (MXN)
ACH (USD)
FEDWIRE (USD)
SEPA (EUR)
SWIFT (international)
curl -X POST https://api-sandbox.lumx.io/destinations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"customerId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "Maria Santos - Engineering",
"rail": "PIX",
"currency": "BRL",
"identifier": {
"keyType": "CPF",
"keyValue": "123.456.789-00"
},
"holder": {
"type": "INDIVIDUAL",
"relationship": "EMPLOYEE",
"name": "Maria Santos",
"taxId": "123.456.789-00",
"birthDate": "1990-05-15",
"email": "maria.santos@acme.com",
"address": {
"line1": "Rua Augusta 100",
"city": "São Paulo",
"state": "SP",
"postalCode": "01304-000",
"country": "BRA"
}
}
}'
curl -X POST https://api-sandbox.lumx.io/destinations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"customerId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "Carlos Hernández - Operations",
"rail": "SPEI",
"currency": "MXN",
"identifier": {
"keyType": "CLABE",
"keyValue": "012180001234567897"
},
"holder": {
"type": "INDIVIDUAL",
"relationship": "EMPLOYEE",
"name": "Carlos Hernández",
"taxId": "HEGC900515ABC",
"birthDate": "1990-05-15",
"email": "carlos.hernandez@acme.com",
"address": {
"line1": "Calzada de Tlalpan 3465",
"city": "Mexico City",
"state": "CDMX",
"postalCode": "04650",
"country": "MEX"
}
}
}'
curl -X POST https://api-sandbox.lumx.io/destinations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"customerId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "Jane Doe - Marketing",
"rail": "ACH",
"currency": "USD",
"identifier": {
"type": "CHECKING",
"accountNumber": "123456789012",
"routingNumber": "021000021"
},
"bank": {
"name": "JPMorgan Chase Bank",
"address": {
"line1": "383 Madison Avenue",
"city": "New York",
"state": "NY",
"postalCode": "10179",
"country": "USA"
}
},
"holder": {
"type": "INDIVIDUAL",
"relationship": "EMPLOYEE",
"name": "Jane Doe",
"taxId": "123-45-6789",
"birthDate": "1985-09-12",
"email": "jane.doe@acme.com",
"address": {
"line1": "350 5th Avenue",
"city": "New York",
"state": "NY",
"postalCode": "10118",
"country": "USA"
}
}
}'
curl -X POST https://api-sandbox.lumx.io/destinations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"customerId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "Sarah Lee - Executive",
"rail": "FEDWIRE",
"currency": "USD",
"identifier": {
"type": "CHECKING",
"accountNumber": "987654321098",
"routingNumber": "021000021"
},
"bank": {
"name": "JPMorgan Chase Bank",
"address": {
"line1": "383 Madison Avenue",
"city": "New York",
"state": "NY",
"postalCode": "10179",
"country": "USA"
}
},
"holder": {
"type": "INDIVIDUAL",
"relationship": "EMPLOYEE",
"name": "Sarah Lee",
"taxId": "234-56-7890",
"birthDate": "1982-04-08",
"email": "sarah.lee@acme.com",
"address": {
"line1": "1 Market Street",
"city": "San Francisco",
"state": "CA",
"postalCode": "94105",
"country": "USA"
}
}
}'
curl -X POST https://api-sandbox.lumx.io/destinations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"customerId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "Lucas Martin - Engineering",
"rail": "SEPA",
"currency": "EUR",
"identifier": {
"iban": "FR1420041010050500013M02606",
"bic": "BNPAFRPP"
},
"bank": {
"name": "BNP Paribas",
"address": {
"line1": "16 Boulevard des Italiens",
"city": "Paris",
"state": "IDF",
"postalCode": "75009",
"country": "FRA"
}
},
"holder": {
"type": "INDIVIDUAL",
"relationship": "EMPLOYEE",
"name": "Lucas Martin",
"taxId": "1850612345678",
"birthDate": "1991-11-30",
"email": "lucas.martin@acme.com",
"address": {
"line1": "45 Avenue Montaigne",
"city": "Paris",
"state": "IDF",
"postalCode": "75008",
"country": "FRA"
}
}
}'
curl -X POST https://api-sandbox.lumx.io/destinations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"customerId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "John Doe - Design",
"rail": "SWIFT",
"currency": "USD",
"identifier": {
"iban": "GB29NWBK60161331926819",
"bic": "NWBKGB2L"
},
"bank": {
"name": "NatWest Bank",
"address": {
"line1": "250 Bishopsgate",
"city": "London",
"postalCode": "EC2M 4AA",
"country": "GBR"
}
},
"holder": {
"type": "INDIVIDUAL",
"relationship": "EMPLOYEE",
"name": "John Doe",
"taxId": "AB123456C",
"birthDate": "1988-03-22",
"email": "john.doe@acme.com",
"address": {
"line1": "10 Downing Street",
"city": "London",
"postalCode": "SW1A 2AA",
"country": "GBR"
}
}
}'
Destinations go through verification before they can be used. Subscribe to the destinations.approved webhook to know when a payee is ready to receive payouts. See Destinations for the full reference.
Step 5: Run payroll
For each approved payee, create an off-ramp transaction debiting the employer’s wallet. Use purpose: "PROFESSIONAL_SERVICES" for contractor and salary payments (the closest available code; there’s no dedicated payroll purpose), or EXPENSES_REIMBURSEMENT for reimbursements. See Purpose codes for the full list.
curl -X POST https://api-sandbox.lumx.io/transactions/off-ramp \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"destinationId": "e80d3137-eddd-4791-b9b8-6e36b289f284",
"sourceCurrency": "USDC",
"sourceAmount": "5000.00",
"purpose": "PROFESSIONAL_SERVICES"
}'
{
"id": "9b1c5b8a-3d1f-4a8f-b6e0-2c1b6a7e9f33",
"customerId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"type": "OFF_RAMP",
"request": {
"destinationId": "e80d3137-eddd-4791-b9b8-6e36b289f284",
"sourceCurrency": "USDC",
"sourceAmount": "5000.00",
"purpose": "PROFESSIONAL_SERVICES"
},
"state": {
"status": "TRANSFERRING_STABLECOIN"
}
}
Repeat the request per payee using a fresh Idempotency-Key each time. There’s no batch endpoint, so run the calls in parallel from your job runner if you need to push a full payroll cycle at once.
Lock in an exchange rate before the payout to guarantee the amount the payee receives. See Exchange Rates.
Step 6: Track payout status
Each off-ramp transaction follows this lifecycle:
TRANSFERRING_STABLECOIN → TRADING → TRANSFERRING_FIAT → SUCCESS
Subscribe to the offramp.success and offramp.failed webhooks to reconcile payouts as they complete and surface status back to the employer in your product. See Webhooks and the Transactions lifecycle reference.
Global accounts
Fund the employer’s wallet via local fiat rails.
Destinations
Holder relationships and verification.
Transactions
Off-ramp lifecycle and purpose codes.
Off-ramp API
Full API reference for off-ramp transactions.