Grid API

The Grid API enables modern financial institutions to easily send and receive global payments. It covers customers and KYC/KYB verification, internal and external accounts, same-currency transfers, cross-currency quotes and execution, UMA lookups and payments, transactions, card issuing, stablecoin provider accounts, embedded wallet authentication, agent provisioning and agent-scoped operations, and a sandbox with published magic test values.

OpenAPI Specification

lightspark-grid-openapi-original.yml Raw ↑
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