From 42e56ebead1258dfefa6654571ca384ba5bf52cc Mon Sep 17 00:00:00 2001 From: Jeremy Klein Date: Mon, 26 Jan 2026 16:40:46 -0800 Subject: [PATCH 1/3] Add Grid API Claude skill Claude skill for Grid API operations and documentation: - SKILL.md: Main skill file with triggers and CLI command reference - references/endpoints.md: API endpoint reference extracted from OpenAPI - references/account-types.md: Country-to-account-type mapping for international payments - references/workflows.md: Common payment workflow guides The skill enables Claude to: - Execute API operations using the CLI tool - Answer questions about the Grid API by reading docs - Guide users through interactive payment workflows --- .claude/skills/grid-api/SKILL.md | 298 ++++++++++++++++++ .../grid-api/references/account-types.md | 183 +++++++++++ .../skills/grid-api/references/endpoints.md | 187 +++++++++++ .../skills/grid-api/references/workflows.md | 270 ++++++++++++++++ 4 files changed, 938 insertions(+) create mode 100644 .claude/skills/grid-api/SKILL.md create mode 100644 .claude/skills/grid-api/references/account-types.md create mode 100644 .claude/skills/grid-api/references/endpoints.md create mode 100644 .claude/skills/grid-api/references/workflows.md diff --git a/.claude/skills/grid-api/SKILL.md b/.claude/skills/grid-api/SKILL.md new file mode 100644 index 0000000..d23fdde --- /dev/null +++ b/.claude/skills/grid-api/SKILL.md @@ -0,0 +1,298 @@ +--- +name: grid-api +description: > + This skill should be used when the user asks to "send a payment", "check balance", + "list transactions", "create a quote", "manage customers", "create external account", + "what currencies does Grid support", "how do I use the Grid API", "send money to [country]", + "pay [UMA address]", "send to CLABE", "send to PIX", "send to IBAN", "send to UPI", + "fund sandbox account", "test a payment", "on-ramp", "off-ramp", "convert crypto to fiat", + "convert fiat to crypto", "look up UMA", "real-time quote", "JIT funding", or any payment + operations using the Grid API CLI. +allowed-tools: + - Bash + - Read + - Grep + - Glob +--- + +# Grid API Skill + +You are a Grid API assistant that helps users manage global payments. You can: + +1. **Execute API Operations** - Use the CLI tool at `cli/dist/index.js` to interact with the Grid API +2. **Answer Documentation Questions** - Read the OpenAPI spec and Mintlify docs in this repo +3. **Guide Payment Workflows** - Help users send payments to bank accounts, UMA addresses, and crypto wallets + +## Supporting References + +For detailed information, read these reference files in the `references/` directory: + +- **`references/account-types.md`** - Country-specific external account requirements (CLABE, PIX, IBAN, UPI, etc.) with field requirements and CLI examples. Read this when creating external accounts for international payments. +- **`references/endpoints.md`** - Complete API endpoint reference with methods, paths, and response codes. Read this when answering questions about specific API capabilities. +- **`references/workflows.md`** - Step-by-step payment workflow guides for common scenarios (UMA payments, international transfers, on-ramp, off-ramp). Read this when guiding users through multi-step payment flows. + +## Key Concepts + +### Entities +- **Platform**: The top-level entity (the API user's business) +- **Customer**: End users of the platform who send/receive payments +- **Internal Account**: Grid-managed account for holding funds (can be platform-owned or customer-owned) +- **External Account**: Bank account or crypto wallet outside Grid (destination for payouts) +- **UMA Address**: Universal Money Address (e.g., `$user@domain.com`) for receiving payments + +### Account Types +- **Platform internal accounts**: For pooled funds, rewards distribution, treasury +- **Customer internal accounts**: Per-currency holding accounts created automatically for each customer +- **External accounts**: Traditional bank accounts (CLABE, IBAN, UPI, etc.) or crypto wallets + +### Account Status Lifecycle +`PENDING` → `ACTIVE` → `UNDER_REVIEW` → `INACTIVE` + +### Currency & Amounts +- All amounts are in the **smallest currency unit** (cents for USD, satoshis for BTC) +- Use the `currency.decimals` field to convert for display (USD=2, BTC=8, etc.) +- Example: `10000` with `decimals: 2` = $100.00 + +## Configuration + +The CLI requires credentials configured via environment variables: +- `GRID_API_TOKEN_ID` - API token ID +- `GRID_API_CLIENT_SECRET` - API client secret +- `GRID_BASE_URL` - Base URL (defaults to `https://api.lightspark.com/grid/2025-10-13`) + +## CLI Commands + +Run all CLI commands from the repo root using: `node cli/dist/index.js ` + +### Platform Configuration +```bash +node cli/dist/index.js config get # Get platform config (currencies, limits) +node cli/dist/index.js config update --webhook-endpoint +``` + +### Customer Management +```bash +node cli/dist/index.js customers list [--limit N] +node cli/dist/index.js customers get +node cli/dist/index.js customers create --platform-id --type INDIVIDUAL --full-name "Name" +node cli/dist/index.js customers kyc-link --customer-id --redirect-url +``` + +### Account Management +```bash +# Internal accounts (Grid-managed, for holding funds) +node cli/dist/index.js accounts internal list [--customer-id ] # Customer internal accounts +node cli/dist/index.js accounts internal list --platform # Platform internal accounts + +# External accounts (bank accounts, crypto wallets - destinations for payouts) +node cli/dist/index.js accounts external list [--customer-id ] + +# Create external accounts by country/type: +# Mexico (CLABE) +node cli/dist/index.js accounts external create --customer-id --currency MXN --account-type CLABE --clabe <18-digit-number> --beneficiary-type BUSINESS --beneficiary-name "Company Name" + +# India (UPI) +node cli/dist/index.js accounts external create --customer-id --currency INR --account-type UPI --upi-id "name@bank" --beneficiary-type INDIVIDUAL --beneficiary-name "Name" --beneficiary-birth-date YYYY-MM-DD --beneficiary-nationality IN + +# Nigeria (NGN) +node cli/dist/index.js accounts external create --customer-id --currency NGN --account-type NGN_ACCOUNT --account-number <10-digit> --bank-name "Bank Name" --purpose GOODS_OR_SERVICES --beneficiary-type INDIVIDUAL --beneficiary-name "Name" --beneficiary-birth-date YYYY-MM-DD --beneficiary-nationality NG +``` + +### Quotes (Cross-Currency Transfers) +```bash +# Account-funded: Use when funds are already in an internal account +node cli/dist/index.js quotes create --source-account --dest-uma
--amount 10000 --lock-side SENDING + +# Real-time/JIT funded: Use when user will provide funds at execution time via instant payment +# Returns paymentInstructions for funding. Only use with instant settlement methods. +# Destination can be internal account, external account, or UMA address +node cli/dist/index.js quotes create --source-customer --source-currency --dest-account --dest-currency --amount 10000 --lock-side RECEIVING + +node cli/dist/index.js quotes execute +node cli/dist/index.js quotes list [--status PENDING] +node cli/dist/index.js quotes get +``` + +### Same-Currency Transfers +```bash +node cli/dist/index.js transfers in --source --dest --amount 10000 +node cli/dist/index.js transfers out --source --dest --amount 10000 +``` + +### Transactions +```bash +node cli/dist/index.js transactions list [--status PENDING] +node cli/dist/index.js transactions get +node cli/dist/index.js transactions approve +node cli/dist/index.js transactions reject [--reason "reason"] +``` + +### Receiver Lookup +```bash +node cli/dist/index.js receiver lookup-uma # Get UMA payment capabilities +node cli/dist/index.js receiver lookup-account # Get account payment capabilities +``` + +### Sandbox Testing +```bash +node cli/dist/index.js sandbox fund --amount 100000 # Fund account in sandbox +node cli/dist/index.js sandbox send --quote-id --currency # Simulate sending funds to a real-time quote +node cli/dist/index.js sandbox receive --uma-address --amount 1000 --currency USD +``` + +## Payment Flow Patterns + +Grid supports three main payment patterns: + +### 1. Prefunded (Account-Funded) +Funds are already in an internal account. Quote executes immediately from existing balance. +``` +Internal Account (USD) → Quote → External Account/UMA (EUR) +``` +Use `--source-account` with an internal account ID. + +### 2. Just-in-Time (Real-Time Funded) +Funds will be provided at execution time. Quote returns `paymentInstructions` with multiple funding options. Grid auto-executes when deposit is received. +``` +Customer sends crypto/fiat → Grid detects deposit → Auto-executes at locked rate +``` +Use `--source-customer` + `--source-currency`. Only works with instant settlement methods. + +### 3. Same-Currency Transfers +Direct transfers between accounts without currency conversion. No quote needed. +``` +External Account (USD) → Internal Account (USD) [transfer-in] +Internal Account (USD) → External Account (USD) [transfer-out] +``` + +## Interactive Payment Workflows + +When a user wants to send a payment, guide them through these steps: + +### Sending to a UMA Address + +1. Look up the receiver: `node cli/dist/index.js receiver lookup-uma $user@domain.com` +2. Show supported currencies and any required payer data +3. Create a quote: `node cli/dist/index.js quotes create --source-account --dest-uma
--amount --lock-side SENDING` +4. Show exchange rate and fees from the quote response +5. Ask for confirmation before executing +6. Execute: `node cli/dist/index.js quotes execute ` + +### Sending to a Bank Account (International) + +1. Determine the destination country and use the appropriate account type: + - **Mexico**: CLABE (18 digits) + - **Brazil**: PIX (CPF 11 digits, CNPJ 14 digits, Email, Phone, or EVP 32 chars) + - **India**: UPI (VPA format: `user@bankhandle`) + - **Nigeria**: NGN_ACCOUNT (10-digit account + bank name + purpose) + - **Europe**: IBAN + SWIFT BIC + - **US**: Routing number (9 digits) + Account number + - **Crypto**: Spark wallet (`spark1...`), Solana/Base/Polygon/Tron addresses + +2. Collect required information: + - Account details specific to the type + - Beneficiary info (requirements vary by destination - check API response for errors) + +3. Create external account using the CLI (see Account Management section for examples) + +4. Create quote showing exchange rate and fees + +5. Get confirmation and execute (or for JIT, show payment instructions) + +### Real-Time / Just-in-Time Funded Transfers + +Use this flow when the user asks for a "realtime quote" or "just in time" funded transfer. The quote response includes `paymentInstructions` for how to fund the transfer. + +**Key concept:** Real-time funding is about instant settlement, not currency type. Use this when funds will be provided at execution time via any instant payment method: +- **Crypto:** BTC (Lightning, Spark), USDC (Solana, Base, Polygon), USDT (Tron) +- **Fiat:** RTP, SEPA Instant, and other instant payment rails + +**Important:** Only use real-time funding with instant settlement methods. Do not use with slow methods like ACH since quotes expire quickly. + +1. Create a quote with `--source-customer` and `--source-currency`. Destination can be an internal account, external account, or UMA address: + ```bash + node cli/dist/index.js quotes create \ + --source-customer \ + --source-currency BTC \ + --dest-account \ + --dest-currency USD \ + --amount 100000 \ + --lock-side RECEIVING + ``` + +2. The response includes `paymentInstructions` with **multiple funding options simultaneously**: + - For BTC: Lightning invoice AND Spark wallet address + - For USDC: Solana wallet AND Base wallet AND Polygon wallet + - For fiat: RTP details or SEPA Instant details + + The user can choose any one of these options to fund the quote. + +3. Show the user ALL payment options and the exchange rate. Let them choose their preferred method. + +4. **Auto-execution**: Once the user sends funds to ANY of the provided addresses, Grid automatically: + - Detects the deposit (monitors blockchain/payment rails) + - Executes the transfer at the locked exchange rate + - Credits the destination account + - Sends webhooks: `ACCOUNT_STATUS` on deposit, `OUTGOING_PAYMENT` on completion + +5. **No manual execution needed** - Do NOT call `quotes execute` for JIT quotes. The transfer executes automatically when funds are received. + +6. **Quote expiration**: Quotes expire in 1-5 minutes. If expired, create a new quote. Do not use slow settlement methods (ACH) with JIT funding. + +## Documentation Resources + +For questions about the Grid API: +- **OpenAPI Spec**: `openapi/` directory for endpoint details and request/response schemas +- **Mintlify Docs**: `mintlify/` directory for guides, concepts, and workflow explanations + - `mintlify/snippets/` - Reusable content on accounts, transfers, KYC, etc. + - `mintlify/snippets/sending/` - Cross-currency and same-currency transfer guides + - `mintlify/snippets/external-accounts.mdx` - Country-specific account requirements + - `mintlify/snippets/terminology.mdx` - Entity definitions and relationships +- **External Account Schemas**: `openapi/components/schemas/external_accounts/` for field requirements per account type + +## Best Practices + +1. **Check platform config first**: Run `config get` to see supported currencies and required fields +2. **Use smallest currency units**: All amounts are in cents/satoshis - use `decimals` field for display +3. **Handle quote expiration**: Quotes expire in 1-5 minutes; be prepared to create new quotes +4. **Choose the right flow**: Use prefunded for immediate execution, JIT for crypto/instant rails +5. **Validate before creating**: Check country-specific requirements to avoid validation errors + +## Error Handling + +All CLI commands output JSON with this structure: +```json +{ + "success": true, + "data": { ... } +} +``` + +Or on error: +```json +{ + "success": false, + "error": { + "code": "ERROR_CODE", + "message": "Human readable message" + } +} +``` + +### Common Error Codes + +**Quote/Transfer Errors:** +- `QUOTE_EXPIRED` - Quote timed out; create a new quote +- `INSUFFICIENT_BALANCE` - Check internal account balance before transfer +- `INVALID_BANK_ACCOUNT` - Validate field formats per country requirements +- `QUOTE_EXECUTION_FAILED` - Transient error; retry with exponential backoff + +**Incoming Payment Errors:** +- `PAYMENT_APPROVAL_TIMED_OUT` - Webhook approval not received within 5 seconds +- `PAYMENT_APPROVAL_WEBHOOK_ERROR` - Webhook returned error + +**Validation Errors:** +- `INVALID_INPUT` - Check required fields; the `reason` field has details +- `MISSING_MANDATORY_USER_INFO` - Customer or sender info missing required fields + +Always check the `success` field and report errors clearly to the user. diff --git a/.claude/skills/grid-api/references/account-types.md b/.claude/skills/grid-api/references/account-types.md new file mode 100644 index 0000000..2539f7c --- /dev/null +++ b/.claude/skills/grid-api/references/account-types.md @@ -0,0 +1,183 @@ +# External Account Types by Country/Region + +This reference maps countries/regions to their required account types and fields for sending payments via the Grid API. + +## Account Type Summary + +| Country/Region | Account Type | Currency | Primary Identifier | +|----------------|--------------|----------|-------------------| +| Mexico | CLABE | MXN | 18-digit CLABE number | +| Brazil | PIX | BRL | PIX key (CPF/CNPJ/email/phone/random) | +| Europe (SEPA) | IBAN | EUR | IBAN number | +| United States | US_ACCOUNT | USD | Account + Routing number | +| India | UPI | INR | UPI ID (user@bank) | +| Nigeria | NGN_ACCOUNT | NGN | Account number + Bank code | + +## Crypto/Wallet Types + +| Type | Currency | Primary Identifier | +|------|----------|-------------------| +| SPARK_WALLET | BTC | Spark wallet address | +| LIGHTNING | BTC | Lightning invoice or address | +| SOLANA_WALLET | USDC | Solana wallet address | +| TRON_WALLET | USDT | Tron wallet address | +| POLYGON_WALLET | USDC | Polygon wallet address | +| BASE_WALLET | USDC | Base wallet address | + +## Detailed Field Requirements + +### Mexico (CLABE) + +```bash +node cli/dist/index.js accounts external create \ + --customer-id \ + --currency MXN \ + --account-type CLABE \ + --clabe <18-digit-clabe> \ + --beneficiary-type INDIVIDUAL \ + --beneficiary-name "Full Name" \ + --beneficiary-birth-date "1990-01-15" \ + --beneficiary-nationality MX +``` + +Required fields: +- `clabeNumber`: 18-digit CLABE number (validates with check digit) +- For individuals: `fullName`, `birthDate`, `nationality` +- For businesses: `legalName` + +### Brazil (PIX) + +```bash +node cli/dist/index.js accounts external create \ + --customer-id \ + --currency BRL \ + --account-type PIX \ + --pix-key "cpf:12345678901" \ + --beneficiary-type INDIVIDUAL \ + --beneficiary-name "Full Name" +``` + +PIX key formats: +- CPF: 11 digits (e.g., `12345678901`) +- CNPJ: 14 digits (e.g., `12345678901234`) +- Email: valid email address +- Phone: +55 followed by number +- Random: 32-character alphanumeric EVP key + +### Europe (IBAN) + +```bash +node cli/dist/index.js accounts external create \ + --customer-id \ + --currency EUR \ + --account-type IBAN \ + --iban "DE89370400440532013000" \ + --beneficiary-type INDIVIDUAL \ + --beneficiary-name "Full Name" \ + --beneficiary-address-line1 "123 Street" \ + --beneficiary-address-city "Berlin" \ + --beneficiary-address-country DE +``` + +IBAN format: Country code (2) + Check digits (2) + BBAN (up to 30) + +### United States (US_ACCOUNT) + +```bash +node cli/dist/index.js accounts external create \ + --customer-id \ + --currency USD \ + --account-type US_ACCOUNT \ + --routing-number "123456789" \ + --account-number "12345678901" \ + --account-category CHECKING \ + --beneficiary-type INDIVIDUAL \ + --beneficiary-name "Full Name" \ + --beneficiary-address-line1 "123 Main St" \ + --beneficiary-address-city "San Francisco" \ + --beneficiary-address-state CA \ + --beneficiary-address-postal "94105" \ + --beneficiary-address-country US +``` + +Required fields: +- `routingNumber`: 9-digit ABA routing number +- `accountNumber`: Bank account number +- `accountCategory`: CHECKING or SAVINGS + +### India (UPI) + +```bash +node cli/dist/index.js accounts external create \ + --customer-id \ + --currency INR \ + --account-type UPI \ + --upi-id "user@okbank" \ + --beneficiary-type INDIVIDUAL \ + --beneficiary-name "Full Name" +``` + +UPI ID format: `username@bankhandle` (e.g., `john@okaxis`, `jane@ybl`) + +### Nigeria (NGN_ACCOUNT) + +```bash +node cli/dist/index.js accounts external create \ + --customer-id \ + --currency NGN \ + --account-type NGN_ACCOUNT \ + --account-number "1234567890" \ + --bank-code "058" \ + --beneficiary-type INDIVIDUAL \ + --beneficiary-name "Full Name" +``` + +Common Nigerian bank codes: +- 058: GTBank +- 057: Zenith Bank +- 033: United Bank for Africa +- 044: Access Bank +- 011: First Bank of Nigeria + +### Crypto Wallets + +#### Spark Wallet (Bitcoin) +```bash +node cli/dist/index.js accounts external create \ + --customer-id \ + --currency BTC \ + --account-type SPARK_WALLET \ + --address "spark1..." +``` + +#### Solana Wallet (USDC) +```bash +node cli/dist/index.js accounts external create \ + --customer-id \ + --currency USDC \ + --account-type SOLANA_WALLET \ + --address "..." +``` + +## Beneficiary Information + +### For Individuals +- `fullName`: Full legal name +- `birthDate`: Date of birth (YYYY-MM-DD) +- `nationality`: 2-letter country code +- `address`: Optional but recommended + +### For Businesses +- `legalName`: Registered business name +- `registrationNumber`: Business registration number (optional) +- `taxId`: Tax identification number (optional) +- `address`: Business address + +## Sandbox Testing + +In sandbox mode, use these account number patterns to test scenarios: +- Numbers ending in **002**: Insufficient funds +- Numbers ending in **003**: Account closed/invalid +- Numbers ending in **004**: Transfer rejected +- Numbers ending in **005**: Timeout/delayed failure +- Any other number: Success diff --git a/.claude/skills/grid-api/references/endpoints.md b/.claude/skills/grid-api/references/endpoints.md new file mode 100644 index 0000000..eee1abe --- /dev/null +++ b/.claude/skills/grid-api/references/endpoints.md @@ -0,0 +1,187 @@ +# Grid API Endpoints Reference + +Quick reference for all Grid API endpoints. For full details, see `openapi/` directory. + +## Base URL + +Production: `https://api.lightspark.com/grid/2025-10-13` + +## Authentication + +HTTP Basic Auth: `Authorization: Basic base64(tokenId:clientSecret)` + +## Platform Configuration + +| Method | Endpoint | Description | +|--------|----------|-------------| +| GET | `/config` | Get platform configuration | +| PATCH | `/config` | Update platform configuration | + +## Customers + +| Method | Endpoint | Description | +|--------|----------|-------------| +| POST | `/customers` | Create a new customer | +| GET | `/customers` | List customers (paginated) | +| GET | `/customers/{customerId}` | Get customer details | +| PATCH | `/customers/{customerId}` | Update customer | +| DELETE | `/customers/{customerId}` | Delete customer | +| POST | `/customers/kyc-link` | Generate KYC link | +| POST | `/customers/bulk/csv` | Bulk upload customers | +| GET | `/customers/bulk/jobs/{jobId}` | Get bulk job status | + +## Internal Accounts + +| Method | Endpoint | Description | +|--------|----------|-------------| +| GET | `/customers/internal-accounts` | List customer internal accounts | +| GET | `/platform/internal-accounts` | List platform internal accounts | + +Internal accounts are auto-created when customers are created based on platform config. + +## External Accounts + +| Method | Endpoint | Description | +|--------|----------|-------------| +| POST | `/customers/external-accounts` | Create customer external account | +| GET | `/customers/external-accounts` | List customer external accounts | +| GET | `/platform/external-accounts` | List platform external accounts | + +## Same-Currency Transfers + +| Method | Endpoint | Description | +|--------|----------|-------------| +| POST | `/transfer-in` | Transfer from external to internal (same currency) | +| POST | `/transfer-out` | Transfer from internal to external (same currency) | + +## Cross-Currency Transfers (Quotes) + +| Method | Endpoint | Description | +|--------|----------|-------------| +| POST | `/quotes` | Create a transfer quote | +| GET | `/quotes` | List quotes (paginated) | +| GET | `/quotes/{quoteId}` | Get quote details | +| POST | `/quotes/{quoteId}/execute` | Execute a pending quote | + +### Quote Source Types +- `source.accountId`: Internal account ID +- `source.customerId` + `source.currency`: Customer-funded with payment instructions + +### Quote Destination Types +- `destination.accountId`: External account ID +- `destination.umaAddress` + `destination.currency`: UMA address +- `destination.externalAccountDetails`: Inline account creation + +## Receiver Lookup + +| Method | Endpoint | Description | +|--------|----------|-------------| +| GET | `/receiver/uma/{receiverUmaAddress}` | Look up UMA address capabilities | +| GET | `/receiver/external-account/{accountId}` | Look up external account capabilities | + +Returns: supported currencies, min/max amounts, required payer data fields. + +## Transactions + +| Method | Endpoint | Description | +|--------|----------|-------------| +| GET | `/transactions` | List transactions (paginated) | +| GET | `/transactions/{transactionId}` | Get transaction details | +| POST | `/transactions/{transactionId}/approve` | Approve incoming payment | +| POST | `/transactions/{transactionId}/reject` | Reject incoming payment | + +### Transaction Types +- `INCOMING`: Payment received +- `OUTGOING`: Payment sent + +### Transaction Statuses +- `PENDING`: Awaiting processing +- `PENDING_APPROVAL`: Needs approval (incoming) +- `PROCESSING`: In progress +- `COMPLETED`: Successfully completed +- `FAILED`: Failed +- `CANCELLED`: Cancelled + +## Webhooks + +| Method | Endpoint | Description | +|--------|----------|-------------| +| POST | `/webhooks/test` | Send test webhook | + +### Webhook Events +- `incoming-payment`: Payment received +- `outgoing-payment`: Payment status update +- `kyc-status`: KYC status change +- `account-status`: Account status change +- `bulk-upload`: Bulk job completion +- `invitation-claimed`: Invitation claimed + +## Invitations + +| Method | Endpoint | Description | +|--------|----------|-------------| +| POST | `/invitations` | Create invitation | +| GET | `/invitations` | List invitations | +| GET | `/invitations/{invitationCode}` | Get invitation | +| POST | `/invitations/{invitationCode}/claim` | Claim invitation | +| POST | `/invitations/{invitationCode}/cancel` | Cancel invitation | + +## Sandbox Testing + +| Method | Endpoint | Description | +|--------|----------|-------------| +| POST | `/sandbox/send` | Simulate sending payment | +| POST | `/sandbox/uma/receive` | Simulate receiving UMA payment | +| POST | `/sandbox/internal-accounts/{accountId}/fund` | Fund account in sandbox | + +### Sandbox Account Patterns +Use these account number endings for testing: +- `002`: Insufficient funds +- `003`: Account closed/invalid +- `004`: Transfer rejected +- `005`: Timeout (pending ~30s, then fails) +- Other: Success + +## API Tokens + +| Method | Endpoint | Description | +|--------|----------|-------------| +| POST | `/tokens` | Create API token | +| GET | `/tokens` | List API tokens | +| GET | `/tokens/{tokenId}` | Get token details | +| DELETE | `/tokens/{tokenId}` | Delete token | + +## UMA Providers + +| Method | Endpoint | Description | +|--------|----------|-------------| +| GET | `/uma-providers` | List UMA provider domains | + +## Plaid Integration + +| Method | Endpoint | Description | +|--------|----------|-------------| +| POST | `/plaid/link-tokens` | Create Plaid Link token | +| POST | `/plaid/callback/{plaid_link_token}` | Plaid Link callback | + +## Pagination + +List endpoints support cursor-based pagination: +- `limit`: Max results (default 20, max 100) +- `cursor`: Pagination cursor from previous response +- Response includes `hasMore`, `nextCursor`, `totalCount` + +## Common Response Codes + +| Code | Description | +|------|-------------| +| 200 | Success | +| 201 | Created | +| 400 | Bad request (invalid parameters) | +| 401 | Unauthorized (invalid credentials) | +| 404 | Not found | +| 409 | Conflict (duplicate) | +| 412 | Precondition failed (UMA version) | +| 424 | Counterparty issue | +| 500 | Internal server error | +| 501 | Not implemented | diff --git a/.claude/skills/grid-api/references/workflows.md b/.claude/skills/grid-api/references/workflows.md new file mode 100644 index 0000000..234c407 --- /dev/null +++ b/.claude/skills/grid-api/references/workflows.md @@ -0,0 +1,270 @@ +# Common Payment Workflows + +This reference describes common payment workflows using the Grid API CLI. + +## Workflow 1: Send Payment to UMA Address + +Use this when the user wants to send money to a UMA address like `$alice@example.com`. + +### Steps + +1. **Look up the receiver** +```bash +node cli/dist/index.js receiver lookup-uma "\$alice@example.com" +``` + +This returns: +- Supported currencies +- Min/max amounts per currency +- Required payer data fields + +2. **Check sender's balance** +```bash +node cli/dist/index.js accounts internal list --customer-id +``` + +Identify the internal account with sufficient balance. + +3. **Create a quote** +```bash +node cli/dist/index.js quotes create \ + --source-account InternalAccount:xxx \ + --dest-uma "\$alice@example.com" \ + --dest-currency USD \ + --amount 10000 \ + --lock-side SENDING \ + --description "Payment for services" +``` + +The response includes: +- `sendingAmount` and `sendingCurrency` +- `receivingAmount` and `receivingCurrency` +- `exchangeRate` +- `fees` array +- `expiresAt` (quote validity) + +4. **Show the user the exchange details and get confirmation** + +Example: "You're sending $100.00 USD. The recipient will receive €92.15 EUR (rate: 0.9215). Fee: $1.50. Confirm?" + +5. **Execute the quote** +```bash +node cli/dist/index.js quotes execute Quote:xxx +``` + +6. **Monitor the transaction** +```bash +node cli/dist/index.js transactions list --status PROCESSING +``` + +## Workflow 2: Send Payment to International Bank Account + +Use this when the user wants to send money to a bank account in another country. + +### Steps + +1. **Determine destination country and account type** + +Ask the user: "Which country is the bank account in?" + +Refer to `account-types.md` for: +- Required account type (CLABE, PIX, IBAN, etc.) +- Required fields + +2. **Collect account details interactively** + +For Mexico (CLABE): +- Ask for 18-digit CLABE number +- Ask for beneficiary name +- Ask for beneficiary birth date +- Ask for beneficiary nationality + +3. **Create the external account** +```bash +node cli/dist/index.js accounts external create \ + --customer-id Customer:xxx \ + --currency MXN \ + --account-type CLABE \ + --clabe 012345678901234567 \ + --beneficiary-type INDIVIDUAL \ + --beneficiary-name "Juan Garcia" \ + --beneficiary-birth-date "1985-03-15" \ + --beneficiary-nationality MX +``` + +4. **Look up the account to get payment capabilities** +```bash +node cli/dist/index.js receiver lookup-account ExternalAccount:xxx +``` + +5. **Create a quote** +```bash +node cli/dist/index.js quotes create \ + --source-account InternalAccount:xxx \ + --dest-account ExternalAccount:xxx \ + --dest-currency MXN \ + --amount 100000 \ + --lock-side RECEIVING +``` + +Note: `--lock-side RECEIVING` means the recipient gets exactly this amount. + +6. **Show exchange details and confirm** + +7. **Execute the quote** +```bash +node cli/dist/index.js quotes execute Quote:xxx +``` + +## Workflow 3: On-Ramp (Fiat to Crypto) + +Use this when a customer wants to convert fiat to cryptocurrency. + +### Steps + +1. **Ensure customer has completed KYC** +```bash +node cli/dist/index.js customers get Customer:xxx +``` + +Check `kycStatus` is `APPROVED`. + +2. **Customer deposits fiat to their internal account** + +Show customer the `paymentInstructions` from their internal account: +```bash +node cli/dist/index.js accounts internal list --customer-id Customer:xxx +``` + +3. **Create external account for crypto destination** +```bash +node cli/dist/index.js accounts external create \ + --customer-id Customer:xxx \ + --currency BTC \ + --account-type SPARK_WALLET \ + --address "spark1..." +``` + +4. **Create and execute quote for conversion** +```bash +node cli/dist/index.js quotes create \ + --source-account InternalAccount:xxx \ + --dest-account ExternalAccount:xxx \ + --dest-currency BTC \ + --amount 10000000 \ + --lock-side SENDING \ + --immediate +``` + +The `--immediate` flag executes the quote instantly. + +## Workflow 4: Off-Ramp (Crypto to Fiat) + +Use this when a customer wants to convert cryptocurrency to fiat. + +### Steps + +1. **Create fiat external account for payout** +```bash +node cli/dist/index.js accounts external create \ + --customer-id Customer:xxx \ + --currency USD \ + --account-type US_ACCOUNT \ + --routing-number "123456789" \ + --account-number "12345678901" \ + --account-category CHECKING \ + --beneficiary-type INDIVIDUAL \ + --beneficiary-name "John Doe" +``` + +2. **Customer sends crypto to their internal account** + +Provide the deposit address from their BTC internal account. + +3. **Create and execute quote for conversion** +```bash +node cli/dist/index.js quotes create \ + --source-account InternalAccount:xxx \ + --dest-account ExternalAccount:xxx \ + --dest-currency USD \ + --amount 50000 \ + --lock-side RECEIVING +``` + +## Workflow 5: Handle Incoming Payment + +Use this when your platform receives an incoming payment that needs approval. + +### Steps + +1. **List pending incoming transactions** +```bash +node cli/dist/index.js transactions list --type INCOMING --status PENDING_APPROVAL +``` + +2. **Review transaction details** +```bash +node cli/dist/index.js transactions get Transaction:xxx +``` + +3. **Approve or reject** +```bash +# Approve +node cli/dist/index.js transactions approve Transaction:xxx + +# Or reject +node cli/dist/index.js transactions reject Transaction:xxx --reason "Suspicious activity" +``` + +## Workflow 6: Bulk Customer Onboarding + +The API supports bulk customer creation via CSV upload. + +### Steps + +1. **Prepare CSV file** with columns: + - platformCustomerId + - customerType + - fullName (for individuals) + - birthDate + - address fields + +2. **Upload CSV** (this endpoint isn't in the CLI, use curl): +```bash +curl -X POST https://api.lightspark.com/grid/2025-10-13/customers/bulk/csv \ + -u "$GRID_API_TOKEN_ID:$GRID_API_CLIENT_SECRET" \ + -F "file=@customers.csv" +``` + +3. **Check job status** +```bash +node cli/dist/index.js customers bulk-status +``` + +## Error Recovery + +### Quote Expired + +If a quote expires before execution: +1. Create a new quote with the same parameters +2. Note: Exchange rates may have changed + +### Transaction Failed + +Check transaction status for failure reason: +```bash +node cli/dist/index.js transactions get Transaction:xxx +``` + +Common failure reasons: +- Insufficient funds +- Invalid account details +- Compliance rejection +- Bank rejection + +### Retry with Different Account + +If a bank account is rejected, try: +1. Verify account details are correct +2. Create a new external account with corrected details +3. Create new quote with the new account From f0a3f448a9d6c5b9656f12adbce309f68be79d5f Mon Sep 17 00:00:00 2001 From: Jeremy Klein Date: Tue, 27 Jan 2026 11:44:25 -0800 Subject: [PATCH 2/3] README --- README.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/README.md b/README.md index 2c9b1e7..288d194 100644 --- a/README.md +++ b/README.md @@ -891,6 +891,30 @@ npm run lint # Or: make lint ``` +## Claude Code Skill + +This repository includes a [Claude Code](https://claude.ai/code) skill for interacting with the Grid API. The skill enables Claude to execute API operations, answer documentation questions, and guide you through payment workflows. + +### Usage + +When using Claude Code in this repository, invoke the skill with `/grid-api` or ask questions like: + +- "Send a payment to Mexico" +- "Create a quote from USDC to INR" +- "What currencies does Grid support?" +- "Help me set up a UPI account" + +The skill uses the CLI at `cli/dist/index.js` to execute operations against the Grid API. + +### Configuration + +Set your API credentials as environment variables: + +```bash +export GRID_API_TOKEN_ID="your-token-id" +export GRID_API_CLIENT_SECRET="your-client-secret" +``` + ## Support For any questions or issues, please contact Grid support at . From 83fe5c4902e5c54c581ac3b75d313ed59417151b Mon Sep 17 00:00:00 2001 From: Jeremy Klein Date: Tue, 27 Jan 2026 11:53:49 -0800 Subject: [PATCH 3/3] Improve Grid API skill with common mistake prevention - Add "Common Mistakes to Avoid" section for external accounts and quotes - Fix Nigerian account example: use --bank-name (not --bank-code), add --purpose - Clarify individual beneficiary requirements (birth date, nationality required) - Add --dest-currency requirement note for quotes to external accounts - Add separate individual/business examples for CLABE accounts Co-Authored-By: Claude Opus 4.5 --- .claude/skills/grid-api/SKILL.md | 39 +++++++++-- .../grid-api/references/account-types.md | 65 +++++++++++++------ 2 files changed, 80 insertions(+), 24 deletions(-) diff --git a/.claude/skills/grid-api/SKILL.md b/.claude/skills/grid-api/SKILL.md index d23fdde..8751701 100644 --- a/.claude/skills/grid-api/SKILL.md +++ b/.claude/skills/grid-api/SKILL.md @@ -88,21 +88,31 @@ node cli/dist/index.js accounts internal list --platform # Platform node cli/dist/index.js accounts external list [--customer-id ] # Create external accounts by country/type: -# Mexico (CLABE) +# IMPORTANT: For INDIVIDUAL beneficiaries, ALWAYS include: +# --beneficiary-birth-date YYYY-MM-DD --beneficiary-nationality <2-letter-code> +# For BUSINESS beneficiaries, use --beneficiary-name with the legal business name + +# Mexico (CLABE) - Business example node cli/dist/index.js accounts external create --customer-id --currency MXN --account-type CLABE --clabe <18-digit-number> --beneficiary-type BUSINESS --beneficiary-name "Company Name" +# Mexico (CLABE) - Individual example +node cli/dist/index.js accounts external create --customer-id --currency MXN --account-type CLABE --clabe <18-digit-number> --beneficiary-type INDIVIDUAL --beneficiary-name "Full Name" --beneficiary-birth-date 1990-01-15 --beneficiary-nationality MX + # India (UPI) node cli/dist/index.js accounts external create --customer-id --currency INR --account-type UPI --upi-id "name@bank" --beneficiary-type INDIVIDUAL --beneficiary-name "Name" --beneficiary-birth-date YYYY-MM-DD --beneficiary-nationality IN -# Nigeria (NGN) -node cli/dist/index.js accounts external create --customer-id --currency NGN --account-type NGN_ACCOUNT --account-number <10-digit> --bank-name "Bank Name" --purpose GOODS_OR_SERVICES --beneficiary-type INDIVIDUAL --beneficiary-name "Name" --beneficiary-birth-date YYYY-MM-DD --beneficiary-nationality NG +# Nigeria (NGN) - REQUIRES: --bank-name (NOT --bank-code), --purpose +node cli/dist/index.js accounts external create --customer-id --currency NGN --account-type NGN_ACCOUNT --account-number <10-digit> --bank-name "GTBank" --purpose GOODS_OR_SERVICES --beneficiary-type INDIVIDUAL --beneficiary-name "Name" --beneficiary-birth-date YYYY-MM-DD --beneficiary-nationality NG ``` ### Quotes (Cross-Currency Transfers) ```bash -# Account-funded: Use when funds are already in an internal account +# Account-funded to UMA: Use when funds are already in an internal account node cli/dist/index.js quotes create --source-account --dest-uma
--amount 10000 --lock-side SENDING +# Account-funded to external account: IMPORTANT - always include --dest-currency +node cli/dist/index.js quotes create --source-account --dest-account --dest-currency --amount 10000 --lock-side SENDING + # Real-time/JIT funded: Use when user will provide funds at execution time via instant payment # Returns paymentInstructions for funding. Only use with instant settlement methods. # Destination can be internal account, external account, or UMA address @@ -113,6 +123,8 @@ node cli/dist/index.js quotes list [--status PENDING] node cli/dist/index.js quotes get ``` +**IMPORTANT**: When using `--dest-account`, you MUST also specify `--dest-currency`. This is required even though the external account already has a currency. + ### Same-Currency Transfers ```bash node cli/dist/index.js transfers in --source --dest --amount 10000 @@ -258,6 +270,25 @@ For questions about the Grid API: 4. **Choose the right flow**: Use prefunded for immediate execution, JIT for crypto/instant rails 5. **Validate before creating**: Check country-specific requirements to avoid validation errors +## Common Mistakes to Avoid + +### External Account Creation +1. **Missing individual beneficiary fields**: For `--beneficiary-type INDIVIDUAL`, you MUST include: + - `--beneficiary-birth-date YYYY-MM-DD` + - `--beneficiary-nationality <2-letter-code>` + +2. **Wrong option names**: + - Use `--bank-name` (NOT `--bank-code`) for Nigerian accounts + - Use `--purpose` for Nigerian accounts (required) + +3. **Missing country-specific fields**: + - Nigeria (NGN_ACCOUNT): Requires `--purpose` (e.g., `GOODS_OR_SERVICES`) + - Brazil (PIX): Requires `--pix-key` and `--pix-key-type` + - Europe (IBAN): Requires `--swift-bic` + +### Quote Creation +1. **Missing destination currency**: When using `--dest-account`, you MUST also include `--dest-currency `. This is required even though the external account already has a currency associated with it. + ## Error Handling All CLI commands output JSON with this structure: diff --git a/.claude/skills/grid-api/references/account-types.md b/.claude/skills/grid-api/references/account-types.md index 2539f7c..e70b484 100644 --- a/.claude/skills/grid-api/references/account-types.md +++ b/.claude/skills/grid-api/references/account-types.md @@ -28,6 +28,7 @@ This reference maps countries/regions to their required account types and fields ### Mexico (CLABE) +**Individual beneficiary:** ```bash node cli/dist/index.js accounts external create \ --customer-id \ @@ -40,9 +41,20 @@ node cli/dist/index.js accounts external create \ --beneficiary-nationality MX ``` +**Business beneficiary:** +```bash +node cli/dist/index.js accounts external create \ + --customer-id \ + --currency MXN \ + --account-type CLABE \ + --clabe <18-digit-clabe> \ + --beneficiary-type BUSINESS \ + --beneficiary-name "Company Legal Name" +``` + Required fields: - `clabeNumber`: 18-digit CLABE number (validates with check digit) -- For individuals: `fullName`, `birthDate`, `nationality` +- For individuals: `fullName`, `birthDate`, `nationality` (ALL THREE REQUIRED) - For businesses: `legalName` ### Brazil (PIX) @@ -127,17 +139,29 @@ node cli/dist/index.js accounts external create \ --currency NGN \ --account-type NGN_ACCOUNT \ --account-number "1234567890" \ - --bank-code "058" \ + --bank-name "GTBank" \ + --purpose GOODS_OR_SERVICES \ --beneficiary-type INDIVIDUAL \ - --beneficiary-name "Full Name" + --beneficiary-name "Full Name" \ + --beneficiary-birth-date "1990-05-15" \ + --beneficiary-nationality NG ``` -Common Nigerian bank codes: -- 058: GTBank -- 057: Zenith Bank -- 033: United Bank for Africa -- 044: Access Bank -- 011: First Bank of Nigeria +Required fields: +- `accountNumber`: 10-digit account number +- `bankName`: Bank name (e.g., "GTBank", "Zenith Bank", "Access Bank") +- `purposeOfPayment`: Purpose code (e.g., `GOODS_OR_SERVICES`) +- For individuals: `fullName`, `birthDate`, `nationality` +- For businesses: `legalName` + +**IMPORTANT**: Use `--bank-name` (NOT `--bank-code`). Use the bank's display name. + +Common Nigerian banks: +- GTBank +- Zenith Bank +- United Bank for Africa +- Access Bank +- First Bank of Nigeria ### Crypto Wallets @@ -161,17 +185,18 @@ node cli/dist/index.js accounts external create \ ## Beneficiary Information -### For Individuals -- `fullName`: Full legal name -- `birthDate`: Date of birth (YYYY-MM-DD) -- `nationality`: 2-letter country code -- `address`: Optional but recommended - -### For Businesses -- `legalName`: Registered business name -- `registrationNumber`: Business registration number (optional) -- `taxId`: Tax identification number (optional) -- `address`: Business address +**CRITICAL**: All external accounts require beneficiary information. The required fields depend on the beneficiary type. + +### For Individuals (--beneficiary-type INDIVIDUAL) +**All three fields are REQUIRED:** +- `--beneficiary-name`: Full legal name +- `--beneficiary-birth-date`: Date of birth (YYYY-MM-DD format) +- `--beneficiary-nationality`: 2-letter ISO country code (e.g., NG, MX, IN, US) +- `--beneficiary-address-*`: Optional but recommended + +### For Businesses (--beneficiary-type BUSINESS) +- `--beneficiary-name`: Registered business/legal name (REQUIRED) +- `--beneficiary-address-*`: Business address (optional) ## Sandbox Testing