openapi: 3.1.0
info:
title: Grid API
description: |
API for managing global payments on the open Money Grid. Built by Lightspark. See the full documentation at https://docs.lightspark.com/.
version: '2025-10-13'
contact:
name: Lightspark Support
email: support@lightspark.com
license:
name: Proprietary
url: https://lightspark.com/terms
servers:
- url: https://api.lightspark.com/grid/2025-10-13
description: Production server
security:
- BasicAuth: []
- AgentAuth: []
tags:
- name: Platform Configuration
description: Platform configuration endpoints for managing global settings. You can also configure these settings in the Grid dashboard.
- name: Customers
description: Customer management endpoints for creating and updating customer information
- name: Contact Verification
description: Endpoints for verifying a customer's email and phone via one-time codes. Required only for customers whose payment provider mandates contact verification (e.g. EU customers); other providers return 409.
- name: Strong Customer Authentication
description: Endpoints for authorizing money-movement operations that require Strong Customer Authentication. Relevant only for customers in a region where SCA is required (e.g. EU); customers outside SCA-regulated regions never see an SCA challenge and these endpoints return 409.
- name: KYC/KYB Verifications
description: Endpoints for Know Your Customer (KYC) and Know Your Business (KYB) verification, including managing beneficial owners and triggering verification for customers.
- name: Documents
description: Endpoints for uploading and managing verification documents for customers and beneficial owners. Supports KYC and KYB document requirements.
- name: Internal Accounts
description: Internal account management endpoints for creating and managing internal accounts
- name: External Accounts
description: External account management endpoints for creating and managing external bank accounts
- name: Same-Currency Transfers
description: Endpoints for transferring funds between internal and external accounts with the same currency
- name: Cross-Currency Transfers
description: Endpoints for creating and confirming quotes for cross-currency transfers
- name: Transactions
description: Endpoints for retrieving transaction information
- name: Webhooks
description: Webhook endpoints and configuration for receiving notifications
- name: Invitations
description: Endpoints for creating, claiming and managing UMA invitations
- name: Sandbox
description: Endpoints to trigger test cases in sandbox
- name: API Tokens
description: Endpoints to programmatically manage API tokens
- name: Exchange Rates
description: Endpoints for retrieving cached foreign exchange rates. Rates are cached for approximately 5 minutes and include platform-specific fees.
- name: Discoveries
description: Endpoints for discovering available payment rails, banks, and providers for a given country and currency corridor.
- name: Embedded Wallet Auth
description: Endpoints for registering and verifying end-user authentication credentials (email OTP, OAuth, passkey) used to sign Embedded Wallet actions.
- name: Agent Management
description: 'Endpoints for creating and managing agents (experimental), called by the partner''s backend using platform credentials. Covers the full agent lifecycle: creation, policy configuration, pausing, deletion, the device code installation flow, and approving or rejecting transactions initiated by agents.'
- name: Agent Operations
description: Endpoints called by the agent itself using its own credentials (obtained via device code redemption). Scoped to the agent's associated customer — all requests automatically operate on behalf of that customer and are subject to the agent's policy. When an action requires approval, the resulting transaction enters a pending state and must be approved by the platform via `POST /transactions/{transactionId}/approve`.
- name: Cards
description: Card management endpoints. Issue debit cards against an internal account, freeze / unfreeze, close, manage card funding sources, and list card transactions.
- name: Stablecoins
description: Stablecoin issuance endpoints. Link provider accounts, register provider-created stablecoins, create mint/burn quotes, execute them, and track the resulting operations.
paths:
/config:
get:
summary: Get platform configuration
description: Retrieve the current platform configuration
operationId: getPlatformConfig
tags:
- Platform Configuration
security:
- BasicAuth: []
responses:
'200':
description: Successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/PlatformConfig'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/Error401'
'500':
description: Internal service error
content:
application/json:
schema:
$ref: '#/components/schemas/Error500'
patch:
summary: Update platform configuration
description: Update the platform configuration settings
operationId: updatePlatformConfig
tags:
- Platform Configuration
security:
- BasicAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PlatformConfigUpdateRequest'
example:
umaDomain: mycompany.com
webhookEndpoint: https://api.mycompany.com/webhooks/uma
supportedCurrencies:
- currencyCode: USD
minAmount: 100
maxAmount: 1000000
enabledTransactionTypes:
- OUTGOING
- INCOMING
requiredCounterpartyFields:
- name: FULL_NAME
mandatory: true
- name: NATIONALITY
mandatory: true
- name: BIRTH_DATE
mandatory: true
embeddedWalletConfig:
appName: Acme Wallet
sendFromEmailAddress: noreply@acme.com
sendFromEmailSenderName: Acme Notifications
replyToEmailAddress: support@acme.com
logoUrl: https://acme.com/logo.png
responses:
'200':
description: Configuration updated successfully
content:
application/json:
schema:
$ref: '#/components/schemas/PlatformConfig'
'400':
description: Bad request
content:
application/json:
schema:
$ref: '#/components/schemas/Error400'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/Error401'
'500':
description: Internal service error
content:
application/json:
schema:
$ref: '#/components/schemas/Error500'
'501':
description: Not implemented
content:
application/json:
schema:
$ref: '#/components/schemas/Error501'
/exchange-rates:
get:
summary: Get exchange rates
description: |
Retrieve cached exchange rates for currency corridors. Returns FX rates that are cached
for approximately 5 minutes. Rates include fees specific to your platform for authenticated requests.
**Filtering Options:**
- Filter by source currency to get all available destination corridors
- Filter by specific destination currency or currencies
- Provide a sending amount to get calculated receiving amounts
operationId: getExchangeRates
tags:
- Exchange Rates
security:
- BasicAuth: []
parameters:
- name: sourceCurrency
in: query
description: Filter by source currency code (e.g., USD)
required: false
schema:
type: string
example: USD
- name: destinationCurrency
in: query
description: Filter by destination currency code(s). Can be repeated for multiple currencies (e.g., &destinationCurrency=INR&destinationCurrency=GBP)
required: false
style: form
explode: true
schema:
type: array
items:
type: string
example:
- INR
- name: sendingAmount
in: query
description: Sending amount in the smallest unit of the source currency (e.g., cents for USD). If no amount is provided, the default is 10000 in the sending currency smallest unit.
required: false
schema:
type: integer
format: int64
minimum: 0
default: 10000
example: 10000
responses:
'200':
description: Successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/ExchangeRateListResponse'
examples:
allRatesFromUSD:
summary: All exchange rates from USD
value:
data:
- sourceCurrency:
code: USD
decimals: 2
name: US Dollar
symbol: $
sendingAmount: 10000
minSendingAmount: 100
maxSendingAmount: 10000000
destinationCurrency:
code: INR
decimals: 2
name: Indian Rupee
symbol: ₹
destinationPaymentRail: UPI
receivingAmount: 825000
exchangeRate: 0.012121
fees:
fixed: 100
total: 150
updatedAt: '2025-02-05T12:00:00Z'
- sourceCurrency:
code: USD
decimals: 2
name: US Dollar
symbol: $
sendingAmount: 10000
minSendingAmount: 100
maxSendingAmount: 10000000
destinationCurrency:
code: EUR
decimals: 2
name: Euro
symbol: €
destinationPaymentRail: SEPA_INSTANT
receivingAmount: 9250
exchangeRate: 1.081081
fees:
fixed: 10
total: 15
updatedAt: '2025-02-05T12:00:00Z'
'400':
description: Bad request - Invalid parameters
content:
application/json:
schema:
$ref: '#/components/schemas/Error400'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/Error401'
'500':
description: Internal service error
content:
application/json:
schema:
$ref: '#/components/schemas/Error500'
/discoveries:
get:
summary: List available receiving institution names
description: |
Retrieve available payment institution names for a given country and currency. Use this endpoint
to look up supported banks and payment providers for a specific corridor.
If no country and currency parameter are provided, all payment institutions will be returned
The `bankName` field in each result is the value to pass as `bankName` when
creating an external account via `POST /customers/external-accounts`.
operationId: getDiscoveries
tags:
- Discoveries
security:
- BasicAuth: []
parameters:
- name: country
in: query
description: ISO 3166-1 alpha-2 country code (e.g. PH)
required: false
schema:
type: string
example: PH
- name: currency
in: query
description: ISO 4217 currency code (e.g. PHP)
required: false
schema:
type: string
example: PHP
responses:
'200':
description: Successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/DiscoveryListResponse'
examples:
philippinesBanks:
summary: Payment rails for Philippines (PHP)
value:
data:
- bankName: BDO Unibank
displayName: BDO Unibank
country: PH
currency: PHP
- bankName: BPI
displayName: Bank of the Philippine Islands
country: PH
currency: PHP
'400':
description: Bad request - Invalid parameters
content:
application/json:
schema:
$ref: '#/components/schemas/Error400'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/Error401'
'500':
description: Internal service error
content:
application/json:
schema:
$ref: '#/components/schemas/Error500'
/customers:
post:
summary: Add a new customer
description: Register a new customer in the system with an account identifier and bank account information
operationId: createCustomer
tags:
- Customers
security:
- BasicAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CustomerCreateRequestOneOf'
examples:
individualCustomer:
summary: Create an individual customer
value:
customerType: INDIVIDUAL
platformCustomerId: ind-9f84e0c2
region: US
currencies:
- USD
- USDC
fullName: Jane Smith
birthDate: '1990-01-15'
nationality: US
email: jane.smith@example.com
phoneNumber: '+14155551234'
individualCustomerInferred:
summary: Create an individual customer with inferred currencies
value:
customerType: INDIVIDUAL
platformCustomerId: ind-7b3f1a9d
region: MX
fullName: Carlos García
birthDate: '1988-05-22'
nationality: MX
phoneNumber: '+525512345678'
businessCustomer:
summary: Create a business customer
value:
customerType: BUSINESS
platformCustomerId: biz-acme-001
region: US
currencies:
- USD
- USDC
email: finance@acme.com
phoneNumber: '+14155559876'
businessInfo:
legalName: Acme Corporation
doingBusinessAs: Acme
country: US
registrationNumber: '5523041'
incorporatedOn: '2018-03-14'
entityType: LLC
taxId: 47-1234567
countriesOfOperation:
- US
businessType: INFORMATION
purposeOfAccount: CONTRACTOR_PAYOUTS
sourceOfFunds: Funds derived from customer payments for software services
expectedMonthlyTransactionCount: COUNT_100_TO_500
expectedMonthlyTransactionVolume: VOLUME_100K_TO_1M
expectedRecipientJurisdictions:
- US
- MX
address:
line1: 123 Market Street
line2: Suite 400
city: San Francisco
state: CA
postalCode: '94105'
country: US
responses:
'201':
description: Customer created successfully
content:
application/json:
schema:
$ref: '#/components/schemas/CustomerOneOf'
'400':
description: Bad request
content:
application/json:
schema:
$ref: '#/components/schemas/Error400'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/Error401'
'405':
description: Method not allowed. Returned (as JSON, not HTML) when the request uses an HTTP method that is not supported on this path.
content:
application/json:
schema:
$ref: '#/components/schemas/Error405'
'409':
description: Conflict. `UMA_ADDRESS_EXISTS` when the requested UMA address is already taken; `CONFLICT` when `platformCustomerId` collides with an existing active customer on the same platform.
content:
application/json:
schema:
$ref: '#/components/schemas/Error409'
'500':
description: Internal service error
content:
application/json:
schema:
$ref: '#/components/schemas/Error500'
'501':
description: Not implemented
content:
application/json:
schema:
$ref: '#/components/schemas/Error501'
get:
summary: List customers
description: |
Retrieve a list of customers with optional filtering parameters. Returns all customers that match
the specified filters. If no filters are provided, returns all customers (paginated).
operationId: listCustomers
tags:
- Customers
security:
- BasicAuth: []
parameters:
- name: platformCustomerId
in: query
description: Filter by platform-specific customer identifier
required: false
schema:
type: string
- name: customerType
in: query
description: Filter by customer type
required: false
schema:
$ref: '#/components/schemas/CustomerType'
- name: createdAfter
in: query
description: Filter customers created after this timestamp (inclusive)
required: false
schema:
type: string
format: date-time
- name: createdBefore
in: query
description: Filter customers created before this timestamp (inclusive)
required: false
schema:
type: string
format: date-time
- name: updatedAfter
in: query
description: Filter customers updated after this timestamp (inclusive)
required: false
schema:
type: string
format: date-time
- name: updatedBefore
in: query
description: Filter customers updated before this timestamp (inclusive)
required: false
schema:
type: string
format: date-time
- name: limit
in: query
description: Maximum number of results to return (default 20, max 100)
required: false
schema:
type: integer
minimum: 1
maximum: 100
default: 20
- name: cursor
in: query
description: Cursor for pagination (returned from previous request)
required: false
schema:
type: string
- name: region
in: query
description: Filter by customer region (ISO 3166-1 alpha-2 country code)
required: false
schema:
type: string
- name: currency
in: query
description: Filter by currency code. Returns customers that have this currency in their enabled currencies list.
required: false
schema:
type: string
- name: umaAddress
in: query
description: Filter by uma address
required: false
schema:
type: string
- name: isIncludingDeleted
in: query
description: Whether to include deleted customers in the results. Default is false.
required: false
schema:
type: boolean
responses:
'200':
description: Successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/CustomerListResponse'
'400':
description: Bad request - Invalid parameters
content:
application/json:
schema:
$ref: '#/components/schemas/Error400'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/Error401'
'405':
description: Method not allowed. Returned (as JSON, not HTML) when the request uses an HTTP method that is not supported on this path.
content:
application/json:
schema:
$ref: '#/components/schemas/Error405'
'500':
description: Internal service error
content:
application/json:
schema:
$ref: '#/components/schemas/Error500'
/customers/{customerId}:
parameters:
- name: customerId
in: path
description: System-generated unique customer identifier
required: true
schema:
type: string
get:
summary: Get customer by ID
description: Retrieve a customer by their system-generated ID
operationId: getCustomerById
tags:
- Customers
security:
- BasicAuth: []
responses:
'200':
description: Successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/CustomerOneOf'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/Error401'
'404':
description: Customer not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error404'
'500':
description: Internal service error
content:
application/json:
schema:
$ref: '#/components/schemas/Error500'
patch:
summary: Update customer by ID
description: |
Update a customer's metadata by their system-generated ID.
Most customer updates complete synchronously and return `200` with the updated customer. If the request changes `email` for a customer that has one or more tied Embedded Wallet internal accounts with `EMAIL_OTP` credentials, or changes `phoneNumber` for a customer that has one or more tied Embedded Wallet internal accounts with `SMS_OTP` credentials, the contact update uses the two-step signed-retry flow so the customer's wallet session authorizes the authentication credential update. On the signed retry, Grid updates the customer contact field and every tied matching OTP credential across all tied Embedded Wallets as one logical operation. If any tied credential cannot be updated, the customer contact field is not changed.
Update `email` and `phoneNumber` in separate PATCH calls. A request that includes both fields is rejected.
For an Embedded Wallet email or SMS auth phone update:
1. Call `PATCH /customers/{customerId}` with the full update body and no signature headers. Grid returns `202` with `payloadToSign`, `requestId`, and `expiresAt`. The pending challenge binds the submitted update fields and the set of tied Embedded Wallet OTP credentials that must be updated.
2. Use the session API keypair of a verified authentication credential on one of the customer's tied Embedded Wallets to build an API-key stamp over `payloadToSign`, then retry the same request with that full stamp as the `Grid-Wallet-Signature` header and the `requestId` echoed back as the `Request-Id` header. The retry body must carry the same update fields submitted in step 1. The signed retry returns `200` with the updated customer.
operationId: updateCustomerById
tags:
- Customers
security:
- BasicAuth: []
parameters:
- name: Grid-Wallet-Signature
in: header
required: false
description: Full API-key stamp built over the prior `payloadToSign` with the session API keypair of a verified authentication credential on one of the customer's tied Embedded Wallets. Required on the signed retry for Embedded Wallet email or SMS auth phone updates; ignored on the initial call and on customer updates that complete synchronously.
schema:
type: string
example: eyJwdWJsaWNLZXkiOiIwMmExYjIuLi4iLCJzY2hlbWUiOiJTSUdOQVRVUkVfU0NIRU1FX1RLX0FQSV9QMjU2Iiwic2lnbmF0dXJlIjoiMzA0NTAyMjEwMC4uLiJ9
- name: Request-Id
in: header
required: false
description: The `requestId` returned in a prior `202` response, echoed back on the signed retry so the server can correlate it with the issued challenge. Required on the signed retry for Embedded Wallet email or SMS auth phone updates; must be paired with `Grid-Wallet-Signature`.
schema:
type: string
example: Request:019542f5-b3e7-1d02-0000-000000000010
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CustomerUpdateRequestOneOf'
examples:
individualUpdate:
summary: Update individual customer example
value:
customerType: INDIVIDUAL
fullName: John Smith
birthDate: '1985-06-15'
currencies:
- USD
- EUR
- USDC
address:
line1: 456 Market St
city: San Francisco
state: CA
postalCode: '94103'
country: US
businessUpdate:
summary: Update business customer example
value:
customerType: BUSINESS
currencies:
- USD
- USDC
businessInfo:
legalName: New Tech Solutions LLC
registrationNumber: BRN-987654321
taxId: EIN-123456789
address:
line1: 100 Technology Parkway
city: Palo Alto
state: CA
postalCode: '94304'
country: US
embeddedWalletEmailUpdate:
summary: Embedded Wallet email update request (both steps)
value:
customerType: INDIVIDUAL
email: john.smith@example.com
embeddedWalletPhoneUpdate:
summary: Embedded Wallet SMS auth phone update request (both steps)
value:
customerType: INDIVIDUAL
phoneNumber: '+14155559876'
combinedContactUpdateRejected:
summary: Combined email and phone update request (rejected)
value:
customerType: INDIVIDUAL
email: john.smith@example.com
phoneNumber: '+14155559876'
responses:
'200':
description: Customer updated successfully. For Embedded Wallet email or SMS auth phone updates, this is returned only on the signed retry after the customer contact field and all tied matching OTP credentials have been updated.
content:
application/json:
schema:
$ref: '#/components/schemas/CustomerOneOf'
'202':
description: Challenge issued for an Embedded Wallet email or SMS auth phone update. The response contains `payloadToSign` plus a `requestId`. Build an API-key stamp over `payloadToSign` with the session API keypair from a verified authentication credential on one of the customer's tied Embedded Wallets, then retry the same request with `Grid-Wallet-Signature` and `Request-Id`.
content:
application/json:
schema:
$ref: '#/components/schemas/SignedRequestChallenge'
examples:
embeddedWalletEmailUpdate:
summary: Embedded Wallet customer email update challenge
value:
payloadToSign: '{"organizationId":"org_2m9F...","parameters":{"userEmail":"john.smith@example.com","userId":"user_2m9F..."},"timestampMs":"1775681700000","type":"ACTIVITY_TYPE_UPDATE_USER_EMAIL"}'
requestId: Request:019542f5-b3e7-1d02-0000-000000000010
expiresAt: '2026-04-08T15:35:00Z'
embeddedWalletPhoneUpdate:
summary: Embedded Wallet customer SMS auth phone update challenge
value:
payloadToSign: '{"organizationId":"org_2m9F...","parameters":{"userId":"user_2m9F...","userPhoneNumber":"+14155559876"},"timestampMs":"1775681700000","type":"ACTIVITY_TYPE_UPDATE_USER_PHONE_NUMBER"}'
requestId: Request:019542f5-b3e7-1d02-0000-000000000011
expiresAt: '2026-04-08T15:35:00Z'
'400':
description: Bad request
content:
application/json:
schema:
$ref: '#/components/schemas/Error400'
'401':
description: Unauthorized. Also returned for Embedded Wallet email or SMS auth phone update retries when the provided `Grid-Wallet-Signature` is missing, malformed, or does not match the pending customer update challenge, when the `Request-Id` does not match an unexpired pending challenge, or when the retry body does not match the update fields bound into `payloadToSign` on the initial call.
content:
application/json:
schema:
$ref: '#/components/schemas/Error401'
'404':
description: Customer not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error404'
'409':
description: Conflict. Returned when the supplied email address is already associated with an `EMAIL_OTP` credential, or the supplied phone number is already associated with an `SMS_OTP` credential, on this or another internal account, or when the tied Embedded Wallet OTP credential set changed between the initial `202` challenge and the signed retry.
content:
application/json:
schema:
$ref: '#/components/schemas/Error409'
'424':
description: Failed dependency. Returned when Grid cannot update one or more tied Embedded Wallet OTP credentials. The customer contact field is not changed unless all tied credentials are updated successfu
# --- truncated at 32 KB (876 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/lightspark/refs/heads/main/openapi/lightspark-grid-openapi-original.yml