Sandbox

Simulate funding an internal account

Changed on

Simulate receiving funds into an internal account in the sandbox environment. This is useful for testing scenarios where you need to add funds to a customer's or platform's internal account without going through a real bank transfer or following payment instructions. This endpoint is only for the sandbox environment and will fail for production platforms/keys.

Funding a rule-based account

Funding a RULE_BASED account triggers its sweep, exactly as a settled deposit does in production: the balance is swept to the rule's destination and the account is left at zero. A balance outside the corridor band moves to the account holder's own account in the same currency instead, and the transaction fails with failureReason: SWEEP_AMOUNT_OUT_OF_RANGE — fund a rule-based account with a very small amount to rehearse that path. Either way the rule-based account is left at zero; it never holds a balance. The sweep's transaction reports a placeholder ACH depositor as its REALTIME_FUNDING source and the funded account as its ruleBasedAccountId, matching what a production deposit reports. To simulate the information a depositor attaches to a payment, pass remittanceInformation. It appears on the swept transaction's source (see remittanceInformation in the request body for which field). description cannot be set when funding a rule-based account: the swept transaction's description comes from the account's sweep rule, exactly as it does for a production deposit. Sending it returns 400 INVALID_INPUT.

Funding other account types

description sets the memo on the incoming transaction for the credit. With remittanceInformation set, the credit is reported as a REALTIME_FUNDING ACH deposit from a placeholder sandbox depositor, matching what a production bank deposit reports. The request is validated before any funds are credited, so a request rejected with 400 leaves the balance unchanged. Sandbox simulates the API contract and the routing decision, not the banking rails. The quote, the corridor bounds, the destination checks and the webhook are all real; the settlement legs behind them are not, so timings and failure modes that originate at a partner bank cannot be reproduced here.

post/sandbox/internal-accounts/{accountId}/fund

Request

  • Base URL
    https://api.lightspark.com/grid/2025-10-13
  • URL
    https://api.lightspark.com/grid/2025-10-13/sandbox/internal-accounts/{accountId}/fund
  • Auth
    HTTP basic

Path parameters

accountIdstring required

The ID of the internal account to fund

Request body

amountinteger required

Amount to add in the smallest unit of the account's currency (e.g., cents for USD/EUR, satoshis for BTC)

remittanceInformationstring

Simulates the free-form payment information a depositor's bank sends with the funds. Depending on the payment rail, a real sender attaches it as the ACH Addenda record, the FedNow or RTP remittanceInformation field, or the wire OBI (Originator to Beneficiary Information). Only printable ASCII characters are allowed. It is reported on the resulting transaction: the incoming transaction for the credit, or the swept transaction for a RULE_BASED account. When it is set, the credit's source is a REALTIME_FUNDING ACH deposit from a placeholder sandbox depositor. A production ACH deposit reports this text as source.railDetails.addenda. Sandbox credits do not include railDetails yet, so the value appears only in the deprecated source.remittanceInformation.

descriptionstring

Optional description/memo for the simulated credit, reported as the description of the incoming transaction. Defaults to a generated description when omitted. Not supported for RULE_BASED accounts: the swept transaction's description comes from the account's sweep rule, so sending it returns 400 INVALID_INPUT.

Example request

{
  "amount": 100000,
  "remittanceInformation": "INV-2026-0042",
  "description": "Test deposit for invoice reconciliation"
}

Response

Internal account funded successfully

idstring required

The ID of the internal account

customerIdstring

The ID of the customer associated with the internal account. If this field is empty, the internal account belongs to the platform.

type'INTERNAL_FIAT' | 'INTERNAL_CRYPTO' | 'EMBEDDED_WALLET' | 'RULE_BASED' | 'BULK_SETTLEMENT' required

Classification of an internal account.

  • INTERNAL_FIAT: A Grid-managed fiat holding account (for example, the USD holding account used as the source for Payouts flows).
  • INTERNAL_CRYPTO: A Grid-managed crypto holding account denominated in a stablecoin such as USDC.
  • EMBEDDED_WALLET: A self-custodial Embedded Wallet provisioned for the customer. Outbound transfers require a session signature produced by the customer's device — see the Embedded Wallets guide.
  • RULE_BASED: An additional account number for an existing account holder, with a routing rule attached, so incoming payments can be attributed to a specific payer and swept automatically. Created with POST /internal-accounts.
  • BULK_SETTLEMENT: An account for receiving bulk payments (for example, a single settlement from a payment processor) that the platform then pays out to its customers. Only a platform can hold one, and funds in it can move only to the platform's customers.
status'PENDING' | 'ACTIVE' | 'CLOSED' | 'FROZEN' | 'FAILED' required

Status of a Grid internal account. The status determines whether the account can send or receive payments.

  • PENDING: The account is under review and is being provisioned. The account cannot send or receive payments until provisioning completes.
  • ACTIVE: The account is ready to send and receive payments.
  • CLOSED: The account cannot send or receive payments. A customer can initiate the closing of an internal account, after which the account transitions to this status.
  • FROZEN: The account cannot send or receive payments. Grid may freeze an account in response to compliance or fraud signals; payments are blocked while the account remains frozen.
  • FAILED: The account could not be provisioned. Grid was unable to create the underlying account, so it cannot send or receive payments and requires remediation.
onBehalfOfCustomerIdstring

The customer whose payments this platform-owned account receives. Only set by regulated financial institutions. Omitted for accounts that name no such customer, which includes every account owned by a customer.

labelstring

The platform-supplied label recorded when the account was created. Null for accounts that carry none.

privateEnabledboolean

Whether wallet privacy is enabled for the Embedded Wallet. Only present for EMBEDDED_WALLET internal accounts.

createdAtstring date-time required

Timestamp when the internal account was created

updatedAtstring date-time required

Timestamp when the internal account was last updated

Example response

{
  "id": "InternalAccount:12dcbd6-dced-4ec4-b756-3c3a9ea3d123",
  "customerId": "Customer:019542f5-b3e7-1d02-0000-000000000001",
  "status": "ACTIVE",
  "balance": {
    "amount": 12550,
    "currency": {
      "code": "USD",
      "name": "United States Dollar",
      "symbol": "$",
      "decimals": 2
    }
  },
  "totalBalance": {
    "amount": 12550,
    "currency": {
      "code": "USD",
      "name": "United States Dollar",
      "symbol": "$",
      "decimals": 2
    }
  },
  "fundingPaymentInstructions": [
    {
      "instructionsNotes": "Please ensure the reference code is included in the payment memo/description field",
      "isPlatformAccount": true,
      "accountOrWalletInfo": {
        "accountType": "USD_ACCOUNT",
        "accountNumber": "1234567890",
        "routingNumber": "021000021",
        "bankName": "Chase Bank",
        "intermediaryBankName": "JPMorgan Chase Bank",
        "intermediaryRoutingNumber": "021000021",
        "fiToFiInformation": "/BNF/Invoice 4471",
        "bankAccountType": "CHECKING"
      }
    }
  ],
  "onBehalfOfCustomerId": "Customer:019542f5-b3e7-1d02-0000-000000000002",
  "label": "invoice-4417",
  "sweepRule": {
    "destination": {
      "accountId": "ExternalAccount:a12dcbd6-dced-4ec4-b756-3c3a9ea3d123",
      "paymentRail": "ACH"
    },
    "minimumAmount": {
      "amount": 12550,
      "currency": {
        "code": "USD",
        "name": "United States Dollar",
        "symbol": "$",
        "decimals": 2
      }
    },
    "maximumAmount": {
      "amount": 12550,
      "currency": {
        "code": "USD",
        "name": "United States Dollar",
        "symbol": "$",
        "decimals": 2
      }
    },
    "description": "Rent sweep",
    "remittanceInformation": "Unit 4B March",
    "platformFeeOverride": {
      "platformFixedFee": {
        "amount": 50,
        "currency": "USD"
      },
      "platformVariableFeeBps": 30
    }
  },
  "privateEnabled": true,
  "cardCapabilities": {
    "supportsVelocityLimits": true,
    "supportsPanReveal": true,
    "supportsDigitalWalletTokenization": true
  },
  "createdAt": "2025-10-03T12:30:00Z",
  "updatedAt": "2025-10-03T12:30:00Z"
}

Changes

    • info

      added the optional property / to the response with the status

    • info

      added the optional property / to the response with the status

    • info

      added the optional property / to the response with the status

    • info

      added the optional property / to the response with the status

    • info

      added the optional property / to the response with the status

    • warning

      added the new CORRIDOR_UNDER_MAINTENANCE enum value to the response property for the response status