From ff7f9d5779ca234493b178881b14028b9753c9a7 Mon Sep 17 00:00:00 2001 From: Jeremy Klein Date: Mon, 25 May 2026 01:32:25 -0700 Subject: [PATCH 1/5] docs(accounts/auth/cards): sync examples with schema Account IDs and headers: - accountId / Internal account uses InternalAccount: prefix (was EmbeddedWallet:) - requestId values and Request-Id headers use Request: prefix - /auth/credentials register response no longer falsely claims a challenge is returned (it returns AuthMethod only - call /challenge separately) - Removed email field from EMAIL_OTP credential create body (not in schema) External / internal account types and fields: - USD_ACCOUNT, EUR_ACCOUNT, BRL_ACCOUNT, MXN_ACCOUNT, INR_ACCOUNT (no US_ACCOUNT / IBAN / IBAN_ACCOUNT / PIX / CLABE / UPI aliases) - ExternalAccountStatus: PENDING | ACTIVE | UNDER_REVIEW | INACTIVE (no REJECTED / FAILED / DISABLED) - Field renames: bankAccountType (was accountCategory), swiftCode (was swiftBic), beneficiaryType (was counterPartyType) - Spark wallet creation: removed unsupported top-level beneficiary block - Removed fabricated GET /customers/internal-accounts/{id} endpoint example Platform config: - supportedCurrencies entries require requiredCounterpartyFields - Sandbox webhook test endpoint is /sandbox/webhooks/test (not /webhooks/test) Cards: - CARDHOLDER_KYC_NOT_APPROVED and FUNDING_SOURCE_INELIGIBLE are 400 (not 409) Co-Authored-By: Claude Opus 4.7 --- .../platform-tools/sandbox-testing.mdx | 4 +-- .../core-concepts/account-model.mdx | 22 ++++++------ mintlify/ramps/accounts/external-accounts.mdx | 19 ++++------ .../conversion-flows/self-custody-wallets.mdx | 15 -------- mintlify/snippets/cards/cardholder-setup.mdx | 4 +-- mintlify/snippets/cards/funding-sources.mdx | 4 +-- .../cards/implementation-overview.mdx | 2 +- mintlify/snippets/cards/issuing-cards.mdx | 4 +-- mintlify/snippets/external-accounts.mdx | 23 ++++++------ .../global-accounts/authentication.mdx | 29 +++++++-------- .../global-accounts/exporting-wallet.mdx | 6 ++-- .../global-accounts/managing-sessions.mdx | 4 +-- .../snippets/global-accounts/walkthrough.mdx | 6 ++-- mintlify/snippets/internal-accounts.mdx | 36 ++++++++++--------- .../platform-config-currency-api-webhooks.mdx | 2 +- .../platform-configuration-non-uma.mdx | 10 ++++-- 16 files changed, 87 insertions(+), 103 deletions(-) diff --git a/mintlify/payouts-and-b2b/platform-tools/sandbox-testing.mdx b/mintlify/payouts-and-b2b/platform-tools/sandbox-testing.mdx index b860fd5e..2170b9d2 100644 --- a/mintlify/payouts-and-b2b/platform-tools/sandbox-testing.mdx +++ b/mintlify/payouts-and-b2b/platform-tools/sandbox-testing.mdx @@ -121,7 +121,7 @@ POST /customers/external-accounts "customerId": "Customer:123", "currency": "EUR", "accountInfo": { - "accountType": "IBAN_ACCOUNT", + "accountType": "EUR_ACCOUNT", "iban": "DE89370400440532013003", "beneficiary": { "beneficiaryType": "INDIVIDUAL", @@ -183,7 +183,7 @@ All webhook events fire normally in sandbox. To test your webhook endpoint: You can also manually trigger a test webhook: ```bash -POST /webhooks/test +POST /sandbox/webhooks/test { "url": "https://your-app.com/webhooks" diff --git a/mintlify/platform-overview/core-concepts/account-model.mdx b/mintlify/platform-overview/core-concepts/account-model.mdx index 35df3735..e1089349 100644 --- a/mintlify/platform-overview/core-concepts/account-model.mdx +++ b/mintlify/platform-overview/core-concepts/account-model.mdx @@ -31,11 +31,11 @@ Grid uses two types of accounts: **internal accounts** (Grid-managed balances) a ```json { - "accountType": "US_ACCOUNT", + "accountType": "USD_ACCOUNT", "currency": "USD", "accountNumber": "1234567890", "routingNumber": "110000000", - "accountCategory": "CHECKING", + "bankAccountType": "CHECKING", "beneficiary": { "beneficiaryType": "INDIVIDUAL", "fullName": "Alice Johnson", @@ -54,10 +54,10 @@ Grid uses two types of accounts: **internal accounts** (Grid-managed balances) a ```json { - "accountType": "IBAN", + "accountType": "EUR_ACCOUNT", "currency": "EUR", "iban": "DE89370400440532013000", - "swiftBic": "DEUTDEFF", + "swiftCode": "DEUTDEFF", "bankName": "Deutsche Bank", "beneficiary": { "beneficiaryType": "INDIVIDUAL", @@ -70,7 +70,7 @@ Grid uses two types of accounts: **internal accounts** (Grid-managed balances) a ```json { - "accountType": "PIX", + "accountType": "BRL_ACCOUNT", "currency": "BRL", "pixKey": "user@example.com", "pixKeyType": "EMAIL", @@ -87,7 +87,7 @@ Grid uses two types of accounts: **internal accounts** (Grid-managed balances) a ```json { - "accountType": "CLABE", + "accountType": "MXN_ACCOUNT", "clabeNumber": "012345678901234567", "bankName": "BBVA Mexico", "beneficiary": { @@ -101,7 +101,7 @@ Grid uses two types of accounts: **internal accounts** (Grid-managed balances) a ```json { - "accountType": "UPI", + "accountType": "INR_ACCOUNT", "currency": "INR", "vpa": "user@paytm", "beneficiary": { @@ -164,10 +164,10 @@ curl -X POST https://api.lightspark.com/grid/2025-10-13/customers/external-accou "customerId": "Customer:019542f5-b3e7-1d02-0000-000000000001", "currency": "USD", "accountInfo": { - "accountType": "US_ACCOUNT", + "accountType": "USD_ACCOUNT", "accountNumber": "9876543210", "routingNumber": "110000000", - "accountCategory": "CHECKING", + "bankAccountType": "CHECKING", "beneficiary": { "beneficiaryType": "INDIVIDUAL", "fullName": "Alice Johnson", @@ -192,7 +192,7 @@ curl -X POST https://api.lightspark.com/grid/2025-10-13/customers/external-accou "currency": "USD", "status": "PENDING", "accountInfo": { - "accountType": "US_ACCOUNT", + "accountType": "USD_ACCOUNT", "accountNumber": "****3210", "routingNumber": "110000000" } @@ -210,7 +210,7 @@ PENDING → ACTIVE - **PENDING**: Created, undergoing verification/screening - **ACTIVE**: Verified, ready for transactions - **INACTIVE**: Disabled (can be reactivated) -- **REJECTED**: Failed verification +- **UNDER_REVIEW**: Additional review required You'll receive `INTERNAL_ACCOUNT.BALANCE_UPDATED` webhooks as balance changes, and `INTERNAL_ACCOUNT.STATUS_UPDATED` webhooks when account status changes (e.g., ACTIVE to FROZEN). diff --git a/mintlify/ramps/accounts/external-accounts.mdx b/mintlify/ramps/accounts/external-accounts.mdx index 575ed8cd..287d4f67 100644 --- a/mintlify/ramps/accounts/external-accounts.mdx +++ b/mintlify/ramps/accounts/external-accounts.mdx @@ -130,10 +130,10 @@ curl -X POST 'https://api.lightspark.com/grid/2025-10-13/customers/external-acco "currency": "USD", "platformAccountId": "user_bank_usd_001", "accountInfo": { - "accountType": "US_ACCOUNT", + "accountType": "USD_ACCOUNT", "accountNumber": "123456789", "routingNumber": "021000021", - "accountCategory": "CHECKING", + "bankAccountType": "CHECKING", "bankName": "Chase Bank", "beneficiary": { "beneficiaryType": "INDIVIDUAL", @@ -168,23 +168,16 @@ curl -X GET 'https://api.lightspark.com/grid/2025-10-13/customers/external-accou -H 'Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET' ``` -### Filter by account type - -```bash -curl -X GET 'https://api.lightspark.com/grid/2025-10-13/customers/external-accounts?customerId=Customer:019542f5-b3e7-1d02-0000-000000000001&accountType=SPARK_WALLET' \ - -H 'Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET' -``` - ## Account status and verification External accounts move through verification states: | Status | Description | Can Use for Conversions | | ---------- | ------------------------ | ----------------------- | -| `PENDING` | Verification in progress | ❌ | -| `ACTIVE` | Verified and ready | ✅ | -| `FAILED` | Verification failed | ❌ | -| `DISABLED` | Manually disabled | ❌ | +| `PENDING` | Verification in progress | ❌ | +| `ACTIVE` | Verified and ready | ✅ | +| `UNDER_REVIEW` | Additional review required | ❌ | +| `INACTIVE` | Manually disabled | ❌ | Spark wallet accounts are immediately `ACTIVE`. Bank accounts may require diff --git a/mintlify/ramps/conversion-flows/self-custody-wallets.mdx b/mintlify/ramps/conversion-flows/self-custody-wallets.mdx index 0f2cecf7..89567f5f 100644 --- a/mintlify/ramps/conversion-flows/self-custody-wallets.mdx +++ b/mintlify/ramps/conversion-flows/self-custody-wallets.mdx @@ -72,11 +72,6 @@ curl -X POST 'https://api.lightspark.com/grid/2025-10-13/customers/external-acco -d '{ "customerId": "Customer:019542f5-b3e7-1d02-0000-000000000001", "currency": "BTC", - "beneficiary": { - "counterPartyType": "INDIVIDUAL", - "fullName": "John Doe", - "email": "john@example.com" - }, "accountInfo": { "accountType": "SPARK_WALLET", "address": "spark1pgssyuuuhnrrdjswal5c3s3rafw9w3y5dd4cjy3duxlf7hjzkp0rqx6dj6mrhu" @@ -96,11 +91,6 @@ const externalAccount = await fetch( body: JSON.stringify({ customerId: "Customer:019542f5-b3e7-1d02-0000-000000000001", currency: "BTC", - beneficiary: { - counterPartyType: "INDIVIDUAL", - fullName: "John Doe", - email: "john@example.com", - }, accountInfo: { accountType: "SPARK_WALLET", address: sparkAddress, @@ -129,11 +119,6 @@ response = requests.post( json={ 'customerId': 'Customer:019542f5-b3e7-1d02-0000-000000000001', 'currency': 'BTC', - 'beneficiary': { - 'counterPartyType': 'INDIVIDUAL', - 'fullName': 'John Doe', - 'email': 'john@example.com' - }, 'accountInfo': { 'accountType': 'SPARK_WALLET', 'address': spark_address diff --git a/mintlify/snippets/cards/cardholder-setup.mdx b/mintlify/snippets/cards/cardholder-setup.mdx index 723bc065..3c989152 100644 --- a/mintlify/snippets/cards/cardholder-setup.mdx +++ b/mintlify/snippets/cards/cardholder-setup.mdx @@ -4,7 +4,7 @@ covers the requirements and the order they must be satisfied in. ## KYC must be APPROVED -`POST /cards` is rejected with `409 CARDHOLDER_KYC_NOT_APPROVED` if the +`POST /cards` is rejected with `400 CARDHOLDER_KYC_NOT_APPROVED` if the cardholder's `kycStatus` is anything other than `APPROVED`. There is no "issue and verify later" path. @@ -26,7 +26,7 @@ time. The account must: - Belong to the cardholder (no cross-customer funding in v1). - Be denominated in a card-eligible currency. In v1 this is USDB; the - request is rejected with `409 FUNDING_SOURCE_INELIGIBLE` otherwise. + request is rejected with `400 FUNDING_SOURCE_INELIGIBLE` otherwise. If the cardholder doesn't have an internal account yet, internal accounts are created automatically when the customer is created based diff --git a/mintlify/snippets/cards/funding-sources.mdx b/mintlify/snippets/cards/funding-sources.mdx index d41550bf..1653289e 100644 --- a/mintlify/snippets/cards/funding-sources.mdx +++ b/mintlify/snippets/cards/funding-sources.mdx @@ -29,7 +29,7 @@ Each source must: one currency. If any source fails these checks, the request is rejected with -`409 FUNDING_SOURCE_INELIGIBLE`. +`400 FUNDING_SOURCE_INELIGIBLE`. ## Replacing the binding @@ -62,7 +62,7 @@ post-change `Card` resource. | Status | Code | What it means | |--------|------|---------------| -| 409 | `FUNDING_SOURCE_INELIGIBLE` | A supplied account doesn't belong to the cardholder or isn't denominated in the card's currency. | +| 400 | `FUNDING_SOURCE_INELIGIBLE` | A supplied account doesn't belong to the cardholder or isn't denominated in the card's currency. | | 409 | `CARD_NOT_MUTABLE` | The card is `CLOSED`. | | 400 | `INVALID_INPUT` | The `fundingSources` array is empty (a card must have at least one source). | diff --git a/mintlify/snippets/cards/implementation-overview.mdx b/mintlify/snippets/cards/implementation-overview.mdx index 7151d0d8..c8db5cf3 100644 --- a/mintlify/snippets/cards/implementation-overview.mdx +++ b/mintlify/snippets/cards/implementation-overview.mdx @@ -27,7 +27,7 @@ Grid. You'll only need to: A card can only be issued to a `Customer` with `kycStatus: APPROVED`. This is the same gate you use for Grid's other features. If the cardholder hasn't completed KYC, `POST /cards` returns -`409 CARDHOLDER_KYC_NOT_APPROVED` — see +`400 CARDHOLDER_KYC_NOT_APPROVED` — see [Cardholder setup](/cards/onboarding/cardholder-setup) for how to drive KYC to completion before issuing. diff --git a/mintlify/snippets/cards/issuing-cards.mdx b/mintlify/snippets/cards/issuing-cards.mdx index 156fce9f..eb1c141b 100644 --- a/mintlify/snippets/cards/issuing-cards.mdx +++ b/mintlify/snippets/cards/issuing-cards.mdx @@ -71,8 +71,8 @@ cross your servers. | Status | Code | What it means | |--------|------|---------------| -| 409 | `CARDHOLDER_KYC_NOT_APPROVED` | Cardholder is not `kycStatus: APPROVED`. Drive KYC to completion before retrying. | -| 409 | `FUNDING_SOURCE_INELIGIBLE` | The supplied internal account doesn't belong to the cardholder or isn't denominated in a card-eligible currency. | +| 400 | `CARDHOLDER_KYC_NOT_APPROVED` | Cardholder is not `kycStatus: APPROVED`. Drive KYC to completion before retrying. | +| 400 | `FUNDING_SOURCE_INELIGIBLE` | The supplied internal account doesn't belong to the cardholder or isn't denominated in a card-eligible currency. | | 400 | `INVALID_INPUT` | Validation failure on the request body. | ## Changing funding sources later diff --git a/mintlify/snippets/external-accounts.mdx b/mintlify/snippets/external-accounts.mdx index 4e9fb957..5a36eda0 100644 --- a/mintlify/snippets/external-accounts.mdx +++ b/mintlify/snippets/external-accounts.mdx @@ -54,10 +54,10 @@ curl -X POST 'https://api.lightspark.com/grid/2025-10-13/customers/external-acco "currency": "USD", "platformAccountId": "user_123_primary_bank", "accountInfo": { - "accountType": "US_ACCOUNT", + "accountType": "USD_ACCOUNT", "accountNumber": "123456789", "routingNumber": "021000021", - "accountCategory": "CHECKING", + "bankAccountType": "CHECKING", "bankName": "Chase Bank", "beneficiary": { "beneficiaryType": "INDIVIDUAL", @@ -92,7 +92,7 @@ curl -X POST 'https://api.lightspark.com/grid/2025-10-13/customers/external-acco "currency": "MXN", "platformAccountId": "mx_beneficiary_001", "accountInfo": { - "accountType": "CLABE", + "accountType": "MXN_ACCOUNT", "clabeNumber": "123456789012345678", "bankName": "BBVA Mexico", "beneficiary": { @@ -125,10 +125,11 @@ curl -X POST 'https://api.lightspark.com/grid/2025-10-13/customers/external-acco "currency": "BRL", "platformAccountId": "br_pix_001", "accountInfo": { - "accountType": "PIX", + "accountType": "BRL_ACCOUNT", "pixKey": "user@email.com", "pixKeyType": "EMAIL", "bankName": "Nubank", + "taxId": "12345678900", "beneficiary": { "beneficiaryType": "INDIVIDUAL", "fullName": "João Silva", @@ -304,9 +305,9 @@ curl -X POST 'https://api.lightspark.com/grid/2025-10-13/customers/external-acco "currency": "EUR", "platformAccountId": "eu_iban_001", "accountInfo": { - "accountType": "IBAN", + "accountType": "EUR_ACCOUNT", "iban": "DE89370400440532013000", - "swiftBic": "DEUTDEFF", + "swiftCode": "DEUTDEFF", "bankName": "Deutsche Bank", "beneficiary": { "beneficiaryType": "INDIVIDUAL", @@ -409,7 +410,7 @@ curl -X POST 'https://api.lightspark.com/grid/2025-10-13/customers/external-acco "currency": "INR", "platformAccountId": "in_upi_001", "accountInfo": { - "accountType": "UPI", + "accountType": "INR_ACCOUNT", "vpa": "user@okbank", "beneficiary": { "beneficiaryType": "INDIVIDUAL", @@ -821,10 +822,10 @@ curl -X POST 'https://api.lightspark.com/grid/2025-10-13/customers/external-acco "currency": "USD", "platformAccountId": "user_123_primary_bank", "accountInfo": { - "accountType": "US_ACCOUNT", + "accountType": "USD_ACCOUNT", "accountNumber": "123456789", "routingNumber": "021000021", - "accountCategory": "CHECKING", + "bankAccountType": "CHECKING", "bankName": "Chase Bank", "beneficiary": { "beneficiaryType": "INDIVIDUAL", @@ -853,10 +854,10 @@ For business accounts, include business information: "platformAccountId": "acme_corp_account", "customerId": "Customer:019542f5-b3e7-1d02-0000-000000000001", "accountInfo": { - "accountType": "US_ACCOUNT", + "accountType": "USD_ACCOUNT", "accountNumber": "987654321", "routingNumber": "021000021", - "accountCategory": "CHECKING", + "bankAccountType": "CHECKING", "bankName": "Chase Bank", "beneficiary": { "beneficiaryType": "BUSINESS", diff --git a/mintlify/snippets/global-accounts/authentication.mdx b/mintlify/snippets/global-accounts/authentication.mdx index 15748d32..e4a0d6db 100644 --- a/mintlify/snippets/global-accounts/authentication.mdx +++ b/mintlify/snippets/global-accounts/authentication.mdx @@ -392,7 +392,7 @@ curl -X POST "$GRID_BASE_URL/auth/credentials" \ -H "Content-Type: application/json" \ -d '{ "type": "OAUTH", - "accountId": "EmbeddedWallet:019542f5-b3e7-1d02-0000-000000000002", + "accountId": "InternalAccount:019542f5-b3e7-1d02-0000-000000000002", "oidcToken": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImFiYzEyMyIsInR5cCI6IkpXVCJ9..." }' ``` @@ -448,8 +448,7 @@ curl -X POST "$GRID_BASE_URL/auth/credentials" \ -H "Content-Type: application/json" \ -d '{ "type": "EMAIL_OTP", - "accountId": "EmbeddedWallet:019542f5-b3e7-1d02-0000-000000000002", - "email": "jane@example.com" + "accountId": "InternalAccount:019542f5-b3e7-1d02-0000-000000000002" }' ``` @@ -458,7 +457,7 @@ curl -X POST "$GRID_BASE_URL/auth/credentials" \ ```json { "id": "AuthMethod:019542f5-b3e7-1d02-0000-000000000004", - "accountId": "EmbeddedWallet:019542f5-b3e7-1d02-0000-000000000002", + "accountId": "InternalAccount:019542f5-b3e7-1d02-0000-000000000002", "type": "EMAIL_OTP", "nickname": "jane@example.com", "createdAt": "2026-04-19T12:00:00Z", @@ -507,7 +506,7 @@ Every Global Account starts with a single credential — the one used in the ```bash curl -X POST "$GRID_BASE_URL/internal-accounts/InternalAccount:019542f5-b3e7-1d02-0000-000000000002/export" \ - -u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET" + -u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET" \ -H "Content-Type: application/json" \ -d '{ "clientPublicKey": "04f45f2a22c908b9ce09a7150e514afd24627c401c38a4afc164e1ea783adaaa31d4245acfb88c2ebd42b47628d63ecabf345484f0a9f665b63c54c897d5578be2" @@ -37,7 +37,7 @@ sequenceDiagram ```json { "payloadToSign": "Y2hhbGxlbmdlLXBheWxvYWQtdG8tc2lnbg==", - "requestId": "c3f8a614-47e2-4a19-9f5d-2b0a91d47e08", + "requestId": "Request:c3f8a614-47e2-4a19-9f5d-2b0a91d47e08", "expiresAt": "2026-04-19T12:10:00Z" } ``` @@ -51,7 +51,7 @@ sequenceDiagram -u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET" \ -H "Content-Type: application/json" \ -H "Grid-Wallet-Signature: MEUCIQDx7k2N0aK4p8f3vR9J6yT5wL1mB0sXnG2hQ4vJ8zYkCgIgZ4rP9dT7eWfU3oM6KjR1qSpNvBwL0tXyA2iG8fH5dE=" \ - -H "Request-Id: c3f8a614-47e2-4a19-9f5d-2b0a91d47e08" \ + -H "Request-Id: Request:c3f8a614-47e2-4a19-9f5d-2b0a91d47e08" \ -d '{ "clientPublicKey": "04f45f2a22c908b9ce09a7150e514afd24627c401c38a4afc164e1ea783adaaa31d4245acfb88c2ebd42b47628d63ecabf345484f0a9f665b63c54c897d5578be2" }' diff --git a/mintlify/snippets/global-accounts/managing-sessions.mdx b/mintlify/snippets/global-accounts/managing-sessions.mdx index 4966b698..8974f70d 100644 --- a/mintlify/snippets/global-accounts/managing-sessions.mdx +++ b/mintlify/snippets/global-accounts/managing-sessions.mdx @@ -53,7 +53,7 @@ Session revocation uses the same @@ -262,7 +262,7 @@ The customer has an outstanding quote with a `payloadToSign`. Now we need a sess "createdAt": "2026-04-19T12:00:01Z", "updatedAt": "2026-04-19T12:05:00Z", "challenge": "VjZ6o8KfE9V3q3LkR2nH5eZ6dM8yA1xW", - "requestId": "7c4a8d09-ca37-4e3e-9e0d-8c2b3e9a1f21", + "requestId": "Request:7c4a8d09-ca37-4e3e-9e0d-8c2b3e9a1f21", "expiresAt": "2026-04-19T12:10:00Z" } ``` @@ -295,7 +295,7 @@ The customer has an outstanding quote with a `payloadToSign`. Now we need a sess curl -X POST "$GRID_BASE_URL/auth/credentials/AuthMethod:019542f5-b3e7-1d02-0000-000000000001/verify" \ -u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET" \ -H "Content-Type: application/json" \ - -H "Request-Id: 7c4a8d09-ca37-4e3e-9e0d-8c2b3e9a1f21" \ + -H "Request-Id: Request:7c4a8d09-ca37-4e3e-9e0d-8c2b3e9a1f21" \ -d '{ "type": "PASSKEY", "assertion": { diff --git a/mintlify/snippets/internal-accounts.mdx b/mintlify/snippets/internal-accounts.mdx index 48cfe9e5..56e9c03e 100644 --- a/mintlify/snippets/internal-accounts.mdx +++ b/mintlify/snippets/internal-accounts.mdx @@ -63,7 +63,7 @@ curl -X GET 'https://api.lightspark.com/grid/2025-10-13/customers/internal-accou "instructionsNotes": "Include the reference code in your ACH transfer memo", "accountOrWalletInfo": { "reference": "FUND-ABC123", - "accountType": "US_ACCOUNT", + "accountType": "USD_ACCOUNT", "accountNumber": "9876543210", "routingNumber": "021000021", "accountHolderName": "Lightspark Payments FBO John Doe", @@ -123,7 +123,7 @@ Each internal account includes `fundingPaymentInstructions` that tell your custo { "instructionsNotes": "Include the reference code in your ACH transfer memo", "accountOrWalletInfo": { - "accountType": "US_ACCOUNT", + "accountType": "USD_ACCOUNT", "reference": "FUND-ABC123", "accountNumber": "9876543210", "routingNumber": "021000021", @@ -241,28 +241,32 @@ The internal account balance reflects all deposits and withdrawals. The balance ### Example balance check ```bash Fetch the balance of an internal account -curl -X GET 'https://api.lightspark.com/grid/2025-10-13/customers/internal-accounts/InternalAccount:e85dcbd6-dced-4ec4-b756-3c3a9ea3d965' \ +curl -X GET 'https://api.lightspark.com/grid/2025-10-13/customers/internal-accounts?customerId=Customer:019542f5-b3e7-1d02-0000-000000000001¤cy=USD' \ -u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET" ``` ```json { - "data": { - "id": "InternalAccount:e85dcbd6-dced-4ec4-b756-3c3a9ea3d965", - "customerId": "Customer:019542f5-b3e7-1d02-0000-000000000001", - "type": "INTERNAL_FIAT", - "status": "ACTIVE", - "balance": { - "amount": 50000, - "currency": { - "code": "USD", - "name": "United States Dollar", - "symbol": "$", - "decimals": 2 + "data": [ + { + "id": "InternalAccount:e85dcbd6-dced-4ec4-b756-3c3a9ea3d965", + "customerId": "Customer:019542f5-b3e7-1d02-0000-000000000001", + "type": "INTERNAL_FIAT", + "status": "ACTIVE", + "balance": { + "amount": 50000, + "currency": { + "code": "USD", + "name": "United States Dollar", + "symbol": "$", + "decimals": 2 + } } } - } + ], + "hasMore": false, + "totalCount": 1 } ``` diff --git a/mintlify/snippets/platform-config-currency-api-webhooks.mdx b/mintlify/snippets/platform-config-currency-api-webhooks.mdx index 1365a735..866fc2ee 100644 --- a/mintlify/snippets/platform-config-currency-api-webhooks.mdx +++ b/mintlify/snippets/platform-config-currency-api-webhooks.mdx @@ -39,7 +39,7 @@ You can trigger a test delivery from the API to validate your endpoint setup. Th Use the webhook test endpoint to send a synthetic event to your configured endpoint. ```bash -curl -sS -X POST "https://api.lightspark.com/grid/2025-10-13/webhooks/test" \ +curl -sS -X POST "https://api.lightspark.com/grid/2025-10-13/sandbox/webhooks/test" \ -u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET" ``` diff --git a/mintlify/snippets/platform-configuration-non-uma.mdx b/mintlify/snippets/platform-configuration-non-uma.mdx index f4d78c2c..29cb5804 100644 --- a/mintlify/snippets/platform-configuration-non-uma.mdx +++ b/mintlify/snippets/platform-configuration-non-uma.mdx @@ -20,7 +20,8 @@ curl -X GET 'https://api.lightspark.com/grid/2025-10-13/config' \ "currencyCode": "USD", "minAmount": 100, "maxAmount": 1000000, - "enabledTransactionTypes": ["OUTGOING", "INCOMING"] + "enabledTransactionTypes": ["OUTGOING", "INCOMING"], + "requiredCounterpartyFields": [] } ], "createdAt": "2023-06-15T12:30:45Z", @@ -49,6 +50,7 @@ curl -X PATCH 'https://api.lightspark.com/grid/2025-10-13/config' \ "minAmount": 100, "maxAmount": 1000000, "enabledTransactionTypes": ["OUTGOING", "INCOMING"], + "requiredCounterpartyFields": [] } ] }' @@ -63,7 +65,8 @@ curl -X PATCH 'https://api.lightspark.com/grid/2025-10-13/config' \ "currencyCode": "USD", "minAmount": 100, "maxAmount": 1000000, - "enabledTransactionTypes": ["OUTGOING", "INCOMING"] + "enabledTransactionTypes": ["OUTGOING", "INCOMING"], + "requiredCounterpartyFields": [] } ], "createdAt": "2023-06-15T12:30:45Z", @@ -96,9 +99,10 @@ The `supportedCurrencies` array allows you to define settings for each currency - `minAmount`: (Integer, required) Minimum transaction amount in the smallest unit of the currency. - `maxAmount`: (Integer, required) Maximum transaction amount in the smallest unit of the currency. - `enabledTransactionTypes`: (Array, optional) Specifies which transaction types are allowed (e.g., `["OUTGOING", "INCOMING"]`). +- `requiredCounterpartyFields`: (Array, required) Counterparty PII fields required for transactions in this currency. For non-UMA platforms with no PII requirements, send an empty array (`[]`). -For payouts payments, you do not need UMA-specific fields like `providerRequiredCustomerFields` or `providerRequiredCounterpartyCustomerFields`. The configuration is simpler and focuses on basic currency requirements. +For payouts payments, you do not need UMA-specific fields like `providerRequiredCustomerFields` or `providerRequiredCounterpartyCustomerFields`. `requiredCounterpartyFields` itself is structurally required — send `[]` when you don't need to collect counterparty PII. ## Verify Configuration From 7bb31ffaec44f4e29edcb4bb85ac15ae38e31f61 Mon Sep 17 00:00:00 2001 From: Jeremy Klein Date: Mon, 25 May 2026 02:46:11 -0700 Subject: [PATCH 2/5] explain EMAIL_OTP nickname source (Greptile review) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The EMAIL_OTP create body intentionally omits an email field — Grid sends the OTP to the address on the customer profile that owns the internal account, and returns that address as the AuthMethod's nickname. Note added next to the example so readers don't go looking for a missing field. Co-Authored-By: Claude Opus 4.7 --- mintlify/snippets/global-accounts/authentication.mdx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mintlify/snippets/global-accounts/authentication.mdx b/mintlify/snippets/global-accounts/authentication.mdx index e4a0d6db..91d0b936 100644 --- a/mintlify/snippets/global-accounts/authentication.mdx +++ b/mintlify/snippets/global-accounts/authentication.mdx @@ -452,6 +452,10 @@ curl -X POST "$GRID_BASE_URL/auth/credentials" \ }' ``` + +The request body carries only `type` and `accountId` — there is no `email` field. Grid sends the OTP to the email address on the customer profile that owns this internal account (the `email` field from `POST /customers`). That same address is returned as `nickname` on the response. + + **Response (201):** ```json From 4c6ae9708791b0bec51aa6068c74e01208e60a81 Mon Sep 17 00:00:00 2001 From: Jeremy Klein Date: Mon, 25 May 2026 04:32:39 -0700 Subject: [PATCH 3/5] sync IBAN funding-instructions example (Greptile review) internal-accounts.mdx EUR funding-instructions accordion still used the old aliases: accountType IBAN -> EUR_ACCOUNT and swiftBic -> swiftCode, matching the renames already applied elsewhere in the PR. Co-Authored-By: Claude Opus 4.7 --- mintlify/snippets/internal-accounts.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mintlify/snippets/internal-accounts.mdx b/mintlify/snippets/internal-accounts.mdx index 56e9c03e..83e7537c 100644 --- a/mintlify/snippets/internal-accounts.mdx +++ b/mintlify/snippets/internal-accounts.mdx @@ -147,10 +147,10 @@ Each internal account includes `fundingPaymentInstructions` that tell your custo { "instructionsNotes": "Include reference in SEPA transfer description", "accountOrWalletInfo": { - "accountType": "IBAN", + "accountType": "EUR_ACCOUNT", "reference": "FUND-EUR789", "iban": "DE89370400440532013000", - "swiftBic": "DEUTDEFF", + "swiftCode": "DEUTDEFF", "accountHolderName": "Lightspark Payments FBO Maria Garcia", "bankName": "Banco de México" } From d2c45216898595853875ba94455d71f51912ffaa Mon Sep 17 00:00:00 2001 From: Jeremy Klein Date: Mon, 25 May 2026 05:48:18 -0700 Subject: [PATCH 4/5] sync EMAIL_OTP mermaid diagram with schema (Greptile review) The Email OTP sequence diagram still showed an email field in the Grid request, contradicting the curl example, Note, and schema. Removed the field and clarified that the OTP is delivered to the customer profile address. Co-Authored-By: Claude Opus 4.7 --- mintlify/snippets/global-accounts/authentication.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mintlify/snippets/global-accounts/authentication.mdx b/mintlify/snippets/global-accounts/authentication.mdx index 91d0b936..0a93b0b0 100644 --- a/mintlify/snippets/global-accounts/authentication.mdx +++ b/mintlify/snippets/global-accounts/authentication.mdx @@ -429,9 +429,9 @@ sequenceDiagram participant G as Grid participant E as Email - C->>IB: POST /my-backend/otp/register { email } - IB->>G: POST /auth/credentials { type: EMAIL_OTP, email, accountId } - G->>E: deliver OTP email + C->>IB: POST /my-backend/otp/register + IB->>G: POST /auth/credentials { type: EMAIL_OTP, accountId } + G->>E: deliver OTP email (to customer profile address) G-->>IB: 201 AuthMethod IB-->>C: { credentialId } E-->>C: OTP code From aedb2b5b70b84e43d43347b1add2391c56c1a9c1 Mon Sep 17 00:00:00 2001 From: Jeremy Klein Date: Mon, 25 May 2026 06:10:35 -0700 Subject: [PATCH 5/5] fix stale 'address you pass' sentence (Greptile review) Co-Authored-By: Claude Opus 4.7 --- mintlify/snippets/global-accounts/authentication.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mintlify/snippets/global-accounts/authentication.mdx b/mintlify/snippets/global-accounts/authentication.mdx index 0a93b0b0..e46e5ced 100644 --- a/mintlify/snippets/global-accounts/authentication.mdx +++ b/mintlify/snippets/global-accounts/authentication.mdx @@ -420,7 +420,7 @@ The lowest-friction credential type — works on any device with email access an ### Email OTP registration -Creating the credential triggers an OTP email to the address you pass. The user reads the code off the email and submits it through your UI. +Creating the credential triggers an OTP email to the email address on the customer profile that owns this internal account. The user reads the code off the email and submits it through your UI. ```mermaid sequenceDiagram