> ## Documentation Index
> Fetch the complete documentation index at: https://ramps-docs-sync-20260627.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Issue your first card and simulate a transaction end to end

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](/payouts-and-b2b/quickstart) up to "Get the Customer's
  Internal Account".

```bash theme={null}
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.

```bash theme={null}
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

```bash theme={null}
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: "PROCESSING"` 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](/cards/platform-tools/sandbox-testing)
for the full table. When activation completes, a
`CARD.STATE_CHANGE` webhook fires with `state: "ACTIVE"`:

```json theme={null}
{
  "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",
    "processorRef": "card_b81c2a4f",
    "issuerRef": "lead_card_7a1b9c3d",
    "createdAt": "2026-05-08T14:10:00Z",
    "updatedAt": "2026-05-08T14:11:00Z"
  }
}
```

<Note>
  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.
</Note>

## 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.

```bash theme={null}
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.00 on a $12.50 hold). Grid handles the over-auth by issuing a
post-hoc pull for the difference.

```bash theme={null}
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 transaction webhook fires with the updated parent: the transaction
moves to `SETTLED`, `pullSummary.count` becomes `2`, and
`settlementSummary.totalAmount` is `1500`.

The webhook payload carries the full parent `CardTransaction` with
child pull, clearing, and refund events rolled up into the
`pullSummary`, `settlementSummary`, and `refundSummary` aggregates —
see [Reconciliation](/cards/transactions/reconciliation) for the full
event model.

<Check>
  You've issued a card, watched it activate, and driven an over-auth
  transaction through pull and clearing.
</Check>
