Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
find_apisBrowse and filter every API in the catalog.
get_api_artifactsOne API's artifacts, grouped by type.
get_openapiThe primary OpenAPI for this API.
find_similar_apisAPIs that look like this one.
apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
resolveTurn a domain, URL or GitHub org into the provider it belongs to.
find_cohortsEvery scored population of providers in the catalog.
All 92 tools →
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/lightspark-customers-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we
store it to create your key and to recognise you if you sign in with another
provider. See our Privacy Policy and
Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: Grid Customers 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: Customers
description: Customer management endpoints for creating and updating customer information
paths:
/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 successfully.
content:
application/json:
schema:
$ref: '#/components/schemas/Error424'
'500':
description: Internal service error
content:
application/json:
schema:
$ref: '#/components/schemas/Error500'
delete:
summary: Delete customer by ID
description: Delete a customer by their system-generated ID
operationId: deleteCustomerById
tags:
- Customers
security:
- BasicAuth: []
responses:
'200':
description: Customer deleted successfully
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'
'410':
description: Customer deleted already
content:
application/json:
schema:
$ref: '#/components/schemas/Error410'
'500':
description: Internal service error
content:
application/json:
schema:
$ref: '#/components/schemas/Error500'
/customers/bulk/csv:
post:
summary: Upload customers via CSV file
description: 'Upload a CSV file containing customer information for bulk creation. The CSV file should follow
a specific format with required and optional columns based on customer type.
### CSV Format
The CSV file should have the following columns:
Required columns for all customers:
- umaAddress: The customer''s UMA address (e.g., $john.doe@uma.domain.com)
- platformCustomerId: Your platform''s unique identifier for the customer
- customerType: Either "INDIVIDUAL" or "BUSINESS"
Required columns for individual customers:
- fullName: Individual''s full name
- birthDate: Date of birth in YYYY-MM-DD format
- addressLine1: Street address line 1
- city: City
- state: State/Province/Region
- postalCode: Postal/ZIP code
- country: Country code (ISO 3166-1 alpha-2)
Required columns for business customers:
- businessLegalName: Legal name of the business
- addressLine1: Street address line 1
- city: City
- state: State/Province/Region
- postalCode: Postal/ZIP code
- country: Country code (ISO 3166-1 alpha-2)
Optional columns for all customers:
- addressLine2: Street address line 2
- platformAccountId: Your platform''s identifier for the bank account
- description: Optional description for the customer
Optional columns for individual customers:
- email: Customer''s email address
Optional columns for business customers:
- businessRegistrationNumber: Business registration number
- businessTaxId: Tax identification number
### Example CSV
```csv
umaAddress,platformCustomerId,customerType,fullName,birthDate,addressLine1,city,state,postalCode,country,platformAccountId,businessLegalName
john.doe@uma.domain.com,customer123,INDIVIDUAL,John Doe,1990-01-15,123 Main St,San Francisco,CA,94105,US
acme@uma.domain.com,biz456,BUSINESS,,,400 Commerce Way,Austin,TX,78701,US
```
The upload process is asynchronous and will return a job ID that can be used to track progress.
You can monitor the job status using the `/customers/bulk/jobs/{jobId}` endpoint.
'
operationId: uploadCustomersCsv
tags:
- Customers
security:
- BasicAuth: []
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
required:
- file
properties:
file:
type: string
format: binary
description: CSV file containing customer information
responses:
'202':
description: CSV upload accepted for processing
content:
application/json:
schema:
$ref: '#/components/schemas/BulkCustomerImportJobAccepted'
'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/bulk/jobs/{jobId}:
get:
summary: Get bulk import job status
description: 'Retrieve the current status and results of a bulk customer import job. This endpoint can be used
to track the progress of both CSV uploads.
The response includes:
- Overall job status
- Progress statistics
- Detailed error information for failed entries
- Completion timestamp when finished
'
operationId: getBulkCustomerImportJob
tags:
- Customers
security:
- BasicAuth: []
parameters:
- name: jobId
in: path
description: ID of the bulk import job to retrieve
required: true
schema:
type: string
responses:
'200':
description: Job status retrieved successfully
content:
application/json:
schema:
$ref: '#/components/schemas/BulkCustomerImportJob'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/Error401'
'404':
description: Job not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error404'
'500':
description: Internal service error
content:
application/json:
schema:
$ref: '#/components/schemas/Error500'
components:
schemas:
BulkCustomerImportJob:
type: object
required:
- id
- status
- progress
properties:
id:
type: string
description: Unique identifier for the bulk import job
example: Job:019542f5-b3e7-1d02-0000-000000000006
status:
type: string
enum:
- PENDING
- PROCESSING
- COMPLETED
- FAILED
description: Current status of the job
example: PROCESSING
progress:
type: object
required:
- total
- processed
- successful
- failed
properties:
total:
type: integer
description: Total number of customers to process
example: 5000
processed:
type: integer
description: Number of customers processed so far
example: 2500
successful:
type: integer
description: Number of customers successfully created
example: 2450
failed:
type: integer
description: Number of customers that failed to create
example: 50
errors:
type: array
description: Detailed error information for failed entries
items:
$ref: '#/components/schemas/BulkCustomerImportErrorEntry'
completedAt:
type: string
format: date-time
description: Timestamp when the job completed (only present for COMPLETED or FAILED status)
example: '2025-08-15T14:32:00Z'
EntityType:
type: string
enum:
- SOLE_PROPRIETORSHIP
- PARTNERSHIP
- LLC
- CORPORATION
- S_CORPORATION
- NON_PROFIT
- OTHER
description: Legal entity type of the business
example: LLC
BulkCustomerImportErrorEntry:
allOf:
- $ref: '#/components/schemas/GridError'
- type: object
description: Error information for a failed bulk import entry
required:
- correlationId
properties:
correlationId:
type: string
description: Platform customer ID or row number for the failed entry
example: biz456
SignedRequestChallenge:
title: Signed Request Challenge
type: object
required:
- payloadToSign
- requestId
- expiresAt
description: Common base for two-step signed-retry challenge responses on Embedded Wallet endpoints (credential registration or revocation, session refresh or revocation, wallet export, customer email updates, and similar). Holds the signing fields shared across every challenge shape; each variant composes this base via `allOf` and adds its own resource `id` (and `type`, when applicable) with variant-specific description and example.
properties:
payloadToSign:
type: string
description: Canonical payload for the retry authorization stamp. Build an API-key stamp over this exact value with the session API keypair, then send the full base64url-encoded stamp in `Grid-Wallet-Signature` on the retry that completes the original request.
example: '{"organizationId":"org_2m9F...","parameters":{"userId":"user_2m9F..."},"timestampMs":"1775681700000","type":"ACTIVITY_TYPE_EXAMPLE"}'
requestId:
type: string
description: Grid-issued `Request:<uuid>` identifier for this pending request. Echo this value exactly in the `Request-Id` header on the signed retry so the server can correlate the retry with the issued challenge.
example: Request:7c4a8d09-ca37-4e3e-9e0d-8c2b3e9a1f21
expiresAt:
type: string
format: date-time
description: Timestamp after which this challenge is no longer valid. The signed retry must be submitted before this time.
example: '2026-04-08T15:35:00Z'
Error400:
type: object
required:
- message
- status
- code
properties:
status:
type: integer
enum:
- 400
description: HTTP status code
code:
type: string
description: '| Error Code | Description |
|------------|-------------|
| INVALID_INPUT | Invalid input provided |
| MISSING_MANDATORY_USER_INFO | Required customer information is missing |
| INVITATION_ALREADY_CLAIMED | Invitation has already been claimed |
| INVITATIONS_NOT_CONFIGURED | Invitations are not configured |
| INVALID_UMA_ADDRESS | UMA address format is invalid |
| INVITATION_CANCELLED | Invitation has been cancelled |
| QUOTE_REQUEST_FAILED | An issue occurred during the quote process; this is retryable |
| INVALID_PAYREQ_RESPONSE | Counterparty Payreq response was invalid |
| INVALID_RECEIVER | Receiver is invalid |
| PARSE_PAYREQ_RESPONSE_ERROR | Error parsing receiver PayReq response |
| CERT_CHAIN_INVALID | Counterparty certificate chain is invalid |
| CERT_CHAIN_EXPIRED | Counterparty certificate chain has expired |
| INVALID_PUBKEY_FORMAT | Counterparty Public key format is invalid |
| MISSING_REQUIRED_UMA_PARAMETERS | Counterparty required UMA parameters are missing |
| SENDER_NOT_ACCEPTED | Sender is not accepted |
| AMOUNT_OUT_OF_RANGE | Amount is out of range |
| INVALID_CURRENCY | Currency is invalid |
| INVALID_TIMESTAMP | Timestamp is invalid |
| INVALID_NONCE | Nonce is invalid |
| INVALID_REQUEST_FORMAT | Request format is invalid |
| INVALID_BANK_ACCOUNT | Bank account is invalid |
| SELF_PAYMENT | Self payment not allowed |
| LOOKUP_REQUEST_FAILED | Lookup request failed |
| PARSE_LNURLP_RESPONSE_ERROR | Error parsing LNURLP response |
| INVALID_AMOUNT | Amount is invalid |
| WEBHOOK_ENDPOINT_NOT_SET | Webhook endpoint is not set |
| WEBHOOK_DELIVERY_ERROR | Webhook delivery error |
| LOW_QUALITY | Document quality too low to process |
| DATA_MISMATCH | Document details don''t match provided information |
| EXPIRED | Document has expired |
| SUSPECTED_FRAUD | Document suspected of being forged or edited |
| UNSUITABLE_DOCUMENT | Document type is not accepted or not supported |
| INCOMPLETE | Document is missing pages or sides |
| EMAIL_OTP_CREDENTIAL_ALREADY_EXISTS | An EMAIL_OTP credential is already registered on the target internal account; only one email OTP credential is supported per internal account at this time |
| SMS_OTP_CREDENTIAL_ALREADY_EXISTS | An SMS_OTP credential is already registered on the target internal account; only one SMS OTP credential is supported per internal account at this time |
| PASSKEY_CREDENTIAL_ALREADY_EXISTS | A PASSKEY credential with the same WebAuthn credentialId is already registered on the target internal account |
| STABLECOIN_PROVIDER_ACCOUNT_INVALID | The stablecoin provider account link is not usable |
| STABLECOIN_
# --- truncated at 32 KB (75 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/lightspark/refs/heads/main/openapi/lightspark-customers-api-openapi.yml