Skip to main content

Documentation Index

Fetch the complete documentation index at: https://ramps-moonrise-limestone.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

This quickstart walks you from an empty Sandbox to a card transaction you can see in your dashboard. We’ll:
  1. Confirm the cardholder is KYC-approved.
  2. Fund their internal account.
  3. Issue a virtual card against that account.
  4. Simulate an inbound authorization, then a clearing.
  5. List the resulting CardTransaction.

Prerequisites

  • Sandbox API credentials.
  • A Customer with kycStatus: APPROVED and at least one InternalAccount. If you don’t have one yet, follow the Payouts quickstart up to “Get the Customer’s Internal Account”.
export GRID_BASE_URL="https://api.lightspark.com/grid/2025-10-13"
export GRID_CLIENT_ID="YOUR_SANDBOX_CLIENT_ID"
export GRID_CLIENT_SECRET="YOUR_SANDBOX_CLIENT_SECRET"

Fund the cardholder’s internal account

Cards decline at auth time if the bound funding source can’t cover the transaction. Top up the cardholder’s internal account first.
curl -X POST "$GRID_BASE_URL/sandbox/internal-accounts/InternalAccount:019542f5-b3e7-1d02-0000-000000000002/fund" \
  -u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{ "amount": 50000 }'

Issue the card

curl -X POST "$GRID_BASE_URL/cards" \
  -u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "cardholderId": "Customer:019542f5-b3e7-1d02-0000-000000000001",
    "platformCardId": "card-emp-aary-001",
    "form": "VIRTUAL",
    "fundingSources": [
      "InternalAccount:019542f5-b3e7-1d02-0000-000000000002"
    ]
  }'
The card comes back in state: "PENDING_ISSUE" while the issuer provisions it. In Sandbox, activation is near-instant for any platformCardId whose last three characters aren’t a magic suffix — see the Sandbox testing guide for the full table. When activation completes, a CARD.STATE_CHANGE webhook fires with state: "ACTIVE":
{
  "id": "Webhook:019542f5-b3e7-1d02-0000-000000000020",
  "type": "CARD.STATE_CHANGE",
  "timestamp": "2026-05-08T14:11:00Z",
  "data": {
    "id": "Card:019542f5-b3e7-1d02-0000-000000000010",
    "cardholderId": "Customer:019542f5-b3e7-1d02-0000-000000000001",
    "state": "ACTIVE",
    "brand": "VISA",
    "form": "VIRTUAL",
    "last4": "4242",
    "expMonth": 12,
    "expYear": 2029,
    "panEmbedUrl": "https://embed.lithic.com/iframe/...?t=...",
    "fundingSources": [
      "InternalAccount:019542f5-b3e7-1d02-0000-000000000002"
    ],
    "currency": "USD",
    "createdAt": "2026-05-08T14:10:00Z",
    "updatedAt": "2026-05-08T14:11:00Z"
  }
}
Render panEmbedUrl in an iframe in your client to display the full PAN, CVV, and expiry to the cardholder. The full card credentials never cross your servers.

Simulate an authorization

Sandbox exposes simulate endpoints that drive the same internal paths the card issuer would call in production. The decisioning outcome is controlled by the last three characters of merchant.descriptor — any non-magic suffix is approved.
curl -X POST "$GRID_BASE_URL/sandbox/cards/Card:019542f5-b3e7-1d02-0000-000000000010/simulate/authorization" \
  -u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 1250,
    "currency": { "code": "USD" },
    "merchant": {
      "descriptor": "BLUE BOTTLE COFFEE SF",
      "mcc": "5814",
      "country": "US"
    }
  }'
The response is the resulting CardTransaction in status: "AUTHORIZED" with a single pull on the funding source.

Simulate the clearing

The merchant adds a tip and clears for more than the original auth (15.00ona15.00 on a 12.50 hold). Grid handles the over-auth by issuing a post-hoc pull for the difference.
curl -X POST "$GRID_BASE_URL/sandbox/cards/Card:019542f5-b3e7-1d02-0000-000000000010/simulate/clearing" \
  -u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "cardTransactionId": "CardTransaction:019542f5-b3e7-1d02-0000-000000000100",
    "amount": 1500
  }'
A CARD_TRANSACTION.UPDATED webhook fires with the updated parent: the transaction moves to SETTLED, pullSummary.count becomes 2, and settlementSummary.totalAmount is 1500.

List card transactions

curl -X GET "$GRID_BASE_URL/cards/Card:019542f5-b3e7-1d02-0000-000000000010/transactions?limit=10" \
  -u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET"
Each row is the parent CardTransaction with child pull, clearing, and refund events rolled up into the pullSummary, settlementSummary, and refundSummary aggregates. See Listing transactions for filtering, and Reconciliation for the full event model.
You’ve issued a card, watched it activate, driven an over-auth transaction through pull and clearing, and listed the reconciled result.