Lightspark Exchange Rates API

Endpoints for retrieving cached foreign exchange rates. Rates are cached for approximately 5 minutes and include platform-specific fees.

OpenAPI Specification

lightspark-exchange-rates-api-openapi.yml Raw ↑
openapi: 3.1.0
info:
  title: Grid Agent Management Exchange Rates 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: Exchange Rates
  description: Endpoints for retrieving cached foreign exchange rates. Rates are cached for approximately 5 minutes and include platform-specific fees.
paths:
  /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'
components:
  schemas:
    ExchangeRateListResponse:
      type: object
      required:
      - data
      properties:
        data:
          type: array
          description: List of exchange rates matching the filter criteria
          items:
            $ref: '#/components/schemas/ExchangeRate'
    Currency:
      type: object
      properties:
        code:
          type: string
          description: Three-letter currency code (ISO 4217) for fiat currencies. Some cryptocurrencies may use their own ticker symbols (e.g. "BTC" for Bitcoin, "USDC" for USDC, etc.)
          example: USD
        name:
          type: string
          description: Full name of the currency
          example: United States Dollar
        symbol:
          type: string
          description: Symbol of the currency
          example: $
        decimals:
          type: integer
          description: Number of decimal places for the currency
          minimum: 0
          example: 2
    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_PROVIDER_ACCOUNT_REVOKED | The stablecoin provider account link has been revoked |

            | STABLECOIN_PROVIDER_ACCOUNT_SELECTION_REQUIRED | Multiple active provider account links exist; pass `stablecoinProviderAccountId` to select one |

            '
          enum:
          - INVALID_INPUT
          - MISSING_MANDATORY_USER_INFO
          - INVITATION_ALREADY_CLAIMED
          - INVITATIONS_NOT_CONFIGURED
          - INVALID_UMA_ADDRESS
          - INVITATION_CANCELLED
          - QUOTE_REQUEST_FAILED
          - INVALID_PAYREQ_RESPONSE
          - INVALID_RECEIVER
          - PARSE_PAYREQ_RESPONSE_ERROR
          - CERT_CHAIN_INVALID
          - CERT_CHAIN_EXPIRED
          - INVALID_PUBKEY_FORMAT
          - MISSING_REQUIRED_UMA_PARAMETERS
          - SENDER_NOT_ACCEPTED
          - AMOUNT_OUT_OF_RANGE
          - INVALID_CURRENCY
          - INVALID_TIMESTAMP
          - INVALID_NONCE
          - INVALID_REQUEST_FORMAT
          - INVALID_BANK_ACCOUNT
          - SELF_PAYMENT
          - LOOKUP_REQUEST_FAILED
          - PARSE_LNURLP_RESPONSE_ERROR
          - INVALID_AMOUNT
          - WEBHOOK_ENDPOINT_NOT_SET
          - WEBHOOK_DELIVERY_ERROR
          - LOW_QUALITY
          - DATA_MISMATCH
          - EXPIRED
          - SUSPECTED_FRAUD
          - UNSUITABLE_DOCUMENT
          - INCOMPLETE
          - EMAIL_OTP_CREDENTIAL_ALREADY_EXISTS
          - SMS_OTP_CREDENTIAL_ALREADY_EXISTS
          - PASSKEY_CREDENTIAL_ALREADY_EXISTS
          - STABLECOIN_PROVIDER_ACCOUNT_INVALID
          - STABLECOIN_PROVIDER_ACCOUNT_REVOKED
          - STABLECOIN_PROVIDER_ACCOUNT_SELECTION_REQUIRED
        message:
          type: string
          description: Error message
        details:
          type: object
          description: Additional error details
          additionalProperties: true
    ExchangeRateFees:
      type: object
      description: Fees associated with an exchange rate
      properties:
        fixed:
          type: integer
          format: int64
          description: Fixed fee in the smallest unit of the sending currency (e.g., cents for USD)
          minimum: 0
          example: 100
        total:
          type: integer
          format: int64
          description: Total fees in the smallest unit of the sending currency (e.g., cents for USD). This value may change depending on the sending amount used; if no sending amount is specified, it falls back to the default.
          minimum: 0
          example: 100
    PaymentRail:
      type: string
      enum:
      - ACH
      - ACH_COLOMBIA
      - BANK_TRANSFER
      - BRE_B
      - CIPS
      - FAST
      - FASTER_PAYMENTS
      - FEDNOW
      - INSTAPAY
      - MOBILE_MONEY
      - NEFT
      - PAYNOW
      - PESONET
      - PIX
      - RTGS
      - RTP
      - SEPA
      - SEPA_INSTANT
      - SPEI
      - SWIFT
      - UNIONPAY
      - UPI
      - WIRE
      description: The payment rail used for the transfer. Payment rails represent the underlying payment network or system used to move funds between accounts.
      example: ACH
    Error500:
      type: object
      required:
      - message
      - status
      - code
      properties:
        status:
          type: integer
          enum:
          - 500
          description: HTTP status code
        code:
          type: string
          description: '| Error Code | Description |

            |------------|-------------|

            | GRID_SWITCH_ERROR | Grid switch error |

            | INTERNAL_ERROR | Internal server or UMA error |

            '
          enum:
          - GRID_SWITCH_ERROR
          - INTERNAL_ERROR
        message:
          type: string
          description: Error message
        details:
          type: object
          description: Additional error details
          additionalProperties: true
    ExchangeRate:
      type: object
      description: Exchange rate information for a currency corridor
      required:
      - sourceCurrency
      - destinationCurrency
      - destinationPaymentRail
      - minSendingAmount
      - maxSendingAmount
      - sendingAmount
      - receivingAmount
      - exchangeRate
      - fees
      - updatedAt
      properties:
        sourceCurrency:
          $ref: '#/components/schemas/Currency'
        sendingAmount:
          type: integer
          format: int64
          description: The sending amount in the smallest unit of the source currency (e.g., cents for USD). Echoed back from the request if provided.
          minimum: 0
          example: 10000
        minSendingAmount:
          type: integer
          format: int64
          description: The minimum supported sending amount in the smallest unit of the source currency.
          minimum: 0
          example: 100
        maxSendingAmount:
          type: integer
          format: int64
          description: The maximum supported sending amount in the smallest unit of the source currency.
          minimum: 0
          example: 10000000
        destinationCurrency:
          $ref: '#/components/schemas/Currency'
        destinationPaymentRail:
          allOf:
          - $ref: '#/components/schemas/PaymentRail'
          - description: The payment rail used for the destination (e.g., UPI, SEPA_INSTANT, MOBILE_MONEY, FASTER_PAYMENTS)
            example: UPI
        receivingAmount:
          type: integer
          format: int64
          description: The receiving amount in the smallest unit of the destination currency
          minimum: 0
          example: 1650000
        exchangeRate:
          type: number
          description: Number of sending currency units per receiving currency unit.
          exclusiveMinimum: 0
          example: 0.012121
        fees:
          $ref: '#/components/schemas/ExchangeRateFees'
        updatedAt:
          type: string
          format: date-time
          description: Timestamp when this exchange rate was last refreshed
          example: '2025-02-05T12:00:00Z'
    Error401:
      type: object
      required:
      - message
      - status
      - code
      properties:
        status:
          type: integer
          enum:
          - 401
          description: HTTP status code
        code:
          type: string
          description: '| Error Code | Description |

            |------------|-------------|

            | UNAUTHORIZED | Issue with API credentials |

            | INVALID_SIGNATURE | Signature header is invalid |

            | WALLET_SIGNATURE_MISSING | The `Grid-Wallet-Signature` header is required for this Embedded Wallet action but was not supplied |

            | WALLET_SIGNATURE_MALFORMED | The `Grid-Wallet-Signature` header could not be parsed (bad encoding, structure, or fields) |

            | WALLET_SIGNATURE_BODY_MISMATCH | The `Grid-Wallet-Signature` was computed over a different request body than the one received |

            | WALLET_SIGNATURE_INVALID | The `Grid-Wallet-Signature` failed cryptographic verification against the registered credential |

            | REQUEST_ID_MISSING | The `Request-Id` header is required on the signed retry but was not supplied (paired with `Grid-Wallet-Signature`) |

            '
          enum:
          - UNAUTHORIZED
          - INVALID_SIGNATURE
          - WALLET_SIGNATURE_MISSING
          - WALLET_SIGNATURE_MALFORMED
          - WALLET_SIGNATURE_BODY_MISMATCH
          - WALLET_SIGNATURE_INVALID
          - REQUEST_ID_MISSING
        message:
          type: string
          description: Error message
        details:
          type: object
          description: Additional error details
          additionalProperties: true
  securitySchemes:
    BasicAuth:
      type: http
      scheme: basic
      description: API token authentication using format `<api token id>:<api client secret>`
    AgentAuth:
      type: http
      scheme: bearer
      description: 'Bearer token authentication for agent-scoped endpoints. The token is the `accessToken` returned when redeeming a device code via `POST /agents/device-codes/{code}/redeem`. Agent credentials are user-scoped: all requests are automatically bound to the agent''s associated customer and subject to the agent''s policy.'
    WebhookSignature:
      type: apiKey
      in: header
      name: X-Grid-Signature
      description: 'Secp256r1 (P-256) asymmetric signature of the webhook payload, which can be used to verify that the webhook was sent by Grid.

        To verify the signature:

        1. Get the Grid public key provided to you during integration

        2. Decode the base64 signature from the header

        3. Create a SHA-256 hash of the request body

        4. Verify the signature using the public key and the hash


        If the signature verification succeeds, the webhook is authentic. If not, it should be rejected.

        '