Skip to main content

Documentation Index

Fetch the complete documentation index at: https://ramps-docs-sync-payments-examples.mintlify.app/llms.txt

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

Customers must complete identity verification before processing conversions. The required information varies based on your platform’s regulatory status.
Regulated platforms have lighter KYC requirements since they handle compliance verification internally.
The KYC/KYB flow allows you to onboard customers through direct API calls.Regulated financial institutions can:
  • Direct API Onboarding: Create customers directly via API calls with minimal verification
  • Internal KYC/KYB: Handle identity verification through your own compliance systems
  • Reduced Documentation: Only provide essential customer information required by your payment counterparty or service provider.
  • Faster Onboarding: Streamlined process for known, verified customers

Creating Customers via Direct API

For regulated platforms, you can create customers directly through the API without requiring external KYC verification:To register a new customer in the system, use the POST /customers endpoint:
curl -X POST "https://api.lightspark.com/grid/2025-10-13/customers" \
  -H "Authorization: Basic $GRID_CLIENT_ID:$GRID_CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "platformCustomerId": "customer_12345",
    "customerType": "INDIVIDUAL",
    "fullName": "Jane Doe",
    "birthDate": "1992-03-25",
    "nationality": "US",
    "address": {
      "line1": "123 Pine Street",
      "city": "Seattle",
      "state": "WA",
      "postalCode": "98101",
      "country": "US"
    }
  }'
The examples below show a more comprehensive set of data. Not all fields are strictly required by the API for customer creation itself, but become necessary based on currency and UMA provider requirements if using UMA.
{
  "platformCustomerId": "9f84e0c2a72c4fa",
  "customerType": "INDIVIDUAL",
  "fullName": "John Sender",
  "birthDate": "1985-06-15",
  "address": {
    "line1": "Paseo de la Reforma 222",
    "line2": "Piso 15",
    "city": "Ciudad de México",
    "state": "Ciudad de México",
    "postalCode": "06600",
    "country": "MX"
  }
}
Unregulated platforms rely on Grid to run KYC for individuals and KYB for businesses. You can onboard customers either through the hosted KYC/KYB link flow below, or by submitting customer data directly through the API. Both paths produce the same kycStatus transitions and emit the same KYC_STATUS webhooks.
Either path works for unregulated platforms:
  • Hosted flow: Redirect customers to a Grid-hosted link (or embed the provider SDK) for identity verification. Best when you want Grid to handle the entire collection UX.
  • Direct API onboarding: Collect customer information in your own UI and submit it via the API. For INDIVIDUAL customers (KYC), personal information goes through POST /customers. For BUSINESS customers (KYB), you also register beneficial owners via POST /beneficial-owners. Submit for review with POST /verifications.
The hosted KYC flow provides a secure, hosted interface where customers can complete their identity verification and onboarding process.The flow is two steps: create the customer with the information you have, then generate a hosted KYC link for that customer. The customer’s kycStatus stays PENDING until they complete the hosted flow.

1. Create the customer

Create the customer with POST /customers, supplying at least customerType and any fields you already have. See Configuring Customers for the full list of optional pre-fill fields.
curl -X POST "https://api.lightspark.com/grid/2025-10-13/customers" \
  -u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "customerType": "INDIVIDUAL",
    "platformCustomerId": "9f84e0c2a72c4fa",
    "region": "US",
    "currencies": ["USD", "USDC"],
    "email": "jane.doe@example.com",
    "fullName": "Jane Doe"
  }'
Persist the returned id (the Grid customer ID) — you’ll need it for the next step.
curl -X POST "https://api.lightspark.com/grid/2025-10-13/customers/Customer:019542f5-b3e7-1d02-0000-000000000001/kyc-link" \
  -u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "redirectUri": "https://yourapp.com/onboarding-complete"
  }'
Response:
{
  "kycUrl": "https://kyc.lightspark.com/onboard/abc123def456",
  "expiresAt": "2027-01-15T14:32:00Z",
  "provider": "SUMSUB",
  "token": "_act-sbx-jwt-eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
The response always includes kycUrl for the hosted flow. For providers that support direct SDK integration (currently SUMSUB), a token is also returned — you can pass this to the provider’s web SDK to embed verification in your own UI instead of redirecting. Both paths update the customer’s kycStatus identically.

Complete KYC Process

1

Create the customer

Call POST /customers with customerType and any pre-fill fields you have. The returned id is the customer’s Grid ID; their kycStatus is PENDING until verification completes.
2

Generate the KYC link

Call POST /customers/{customerId}/kyc-link. Each call returns a fresh single-use kycUrl and expiresAt; previously-issued links remain single-use but aren’t invalidated.
The redirectUri you pass is embedded in the generated kycUrl and is used to automatically return the customer to your application after they complete verification.
3

Send the customer through verification

Redirect the customer to kycUrl, or — if you want to embed the flow directly — initialize the provider’s SDK with the returned token.
The hosted URL is single-use and expires at expiresAt. If a customer needs to retry, call the endpoint again to generate a new link.
4

Track the decision

Reaching your redirectUri only means the customer finished the hosted flow — not that they were approved. Wait for the final decision in one of two ways:
  • Webhook (recommended): Subscribe to KYC_STATUS to be notified when the customer reaches a terminal status (APPROVED, REJECTED, EXPIRED, or CANCELED).
  • Polling: Call GET /customers/{customerId} and inspect kycStatus.
5

Handle completion

On APPROVED, the customer is ready to transact — proceed with account setup and unlock funding. On REJECTED or EXPIRED, surface the appropriate next step (for example, regenerate the link or request manual review).

Direct API Onboarding

Prefer to collect identity information in your own UI and submit it to Grid yourself? Use the API directly instead of redirecting to a hosted link. The customer’s kycStatus transitions the same way and you receive the same KYC_STATUS webhooks.The shape of the flow depends on the customer type:
  • KYC (INDIVIDUAL customers) — supply the customer’s personal information through the customer endpoint. No beneficial owners are involved.
  • KYB (BUSINESS customers) — create the business customer, then register its beneficial owners, directors, and officers individually.
1

Create the customer with personal information

Call POST /customers with customerType: INDIVIDUAL and the personal information collected from the customer (legal name, date of birth, address, nationality, etc.). The returned id is the customer’s Grid ID; kycStatus starts at PENDING.
curl -X POST "https://api.lightspark.com/grid/2025-10-13/customers" \
  -u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "customerType": "INDIVIDUAL",
    "platformCustomerId": "9f84e0c2a72c4fa",
    "fullName": "Jane Doe",
    "birthDate": "1985-06-15",
    "nationality": "US",
    "email": "jane.doe@example.com",
    "address": {
      "line1": "123 Pine Street",
      "city": "Seattle",
      "state": "WA",
      "postalCode": "98101",
      "country": "US"
    }
  }'
2

Upload supporting documents (if requested)

Some jurisdictions or currencies require an ID document or proof of address. Upload them with POST /documents using multipart/form-data, referencing the customer by customerId.
curl -X POST "https://api.lightspark.com/grid/2025-10-13/documents" \
  -u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET" \
  -F "customerId=Customer:019542f5-b3e7-1d02-0000-000000000001" \
  -F "documentType=PASSPORT" \
  -F "file=@./passport.jpg"
3

Submit for verification

Call POST /verifications to submit the customer for review. The response includes a verificationStatus. If anything is missing, verificationStatus is RESOLVE_ERRORS and the errors array describes exactly what to collect before retrying.
curl -X POST "https://api.lightspark.com/grid/2025-10-13/verifications" \
  -u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "customerId": "Customer:019542f5-b3e7-1d02-0000-000000000001"
  }'
Submitted successfully:
{
  "id": "Verification:019542f5-b3e7-1d02-0000-000000000002",
  "customerId": "Customer:019542f5-b3e7-1d02-0000-000000000001",
  "verificationStatus": "IN_PROGRESS",
  "errors": [],
  "createdAt": "2025-10-03T12:00:00Z"
}
Blocked by missing data:
{
  "id": "Verification:019542f5-b3e7-1d02-0000-000000000001",
  "customerId": "Customer:019542f5-b3e7-1d02-0000-000000000001",
  "verificationStatus": "RESOLVE_ERRORS",
  "errors": [
    {
      "resourceId": "Customer:019542f5-b3e7-1d02-0000-000000000001",
      "type": "MISSING_PROOF_OF_ADDRESS_DOCUMENT",
      "acceptedDocumentTypes": ["PROOF_OF_ADDRESS"],
      "reason": "Proof of address document is required"
    }
  ],
  "createdAt": "2025-10-03T12:00:00Z"
}
4

Track the decision

Track terminal kycStatus transitions via the KYC_STATUS webhook (recommended) or by polling GET /customers/{customerId}. On APPROVED, unlock funding and money movement.

Monitor verification status

After a customer completes the KYC/KYB verification process, you’ll receive webhook notifications about their KYC status. These notifications are sent to your configured webhook endpoint.
For regulated platforms, customers are created with APPROVED KYC status by default.
Webhook Payload (sent to your endpoint):
{
  "id": "Webhook:019542f5-b3e7-1d02-0000-000000000020",
  "type": "CUSTOMER.KYC_APPROVED",
  "timestamp": "2025-07-21T17:32:28Z",
  "data": {
    "id": "Customer:019542f5-b3e7-1d02-0000-000000000001",
    "platformCustomerId": "9f84e0c2a72c4fa",
    "customerType": "INDIVIDUAL",
    "umaAddress": "$john.doe@uma.domain.com",
    "kycStatus": "APPROVED",
    "fullName": "John Michael Doe",
    "birthDate": "1990-01-15",
    "nationality": "US",
    "address": {
      "line1": "123 Main Street",
      "line2": "Apt 4B",
      "city": "San Francisco",
      "state": "CA",
      "postalCode": "94105",
      "country": "US"
    },
    "createdAt": "2025-07-21T17:32:28Z",
    "updatedAt": "2025-07-21T17:32:28Z",
    "isDeleted": false
  }
}
Webhook Headers:
  • Content-Type: application/json
  • X-Grid-Signature: {"v": "1", "s": "base64_signature..."}
id
string
required
Unique identifier for this webhook delivery. Use this for idempotency to prevent processing duplicate webhooks.
type
string
required
Status-specific event type. KYC webhooks use CUSTOMER.* types:
  • CUSTOMER.KYC_APPROVED: Customer verification completed successfully
  • CUSTOMER.KYC_REJECTED: Customer verification was rejected
  • CUSTOMER.KYC_SUBMITTED: KYC verification was initially submitted
  • CUSTOMER.KYC_MANUALLY_APPROVED: Customer was manually approved by platform
  • CUSTOMER.KYC_MANUALLY_REJECTED: Customer was manually rejected by platform
data
object
required
The full customer resource object, same as the corresponding GET /customers/{id} endpoint would return. Includes all customer fields such as id, kycStatus, fullName, birthDate, nationality, address, etc.
Intermediate states like PENDING_REVIEW do not trigger webhook notifications. Only final resolution states will send webhook notifications.
// Example webhook handler for KYC status updates
// Note: Only final states trigger webhook notifications
app.post('/webhooks/kyc-status', async (req, res) => {
  const { type, data } = req.body;

  switch (type) {
    case 'CUSTOMER.KYC_APPROVED':
      // Activate customer account
      await activateCustomer(data.id);
      await sendWelcomeEmail(data.id);
      break;

    case 'CUSTOMER.KYC_REJECTED':
      // Notify support and customer
      await notifySupport(data.id, 'KYC_REJECTED');
      await sendRejectionEmail(data.id);
      break;

    case 'CUSTOMER.KYC_MANUALLY_APPROVED':
      // Handle manual approval
      await activateCustomer(data.id);
      await sendWelcomeEmail(data.id);
      break;

    case 'CUSTOMER.KYC_MANUALLY_REJECTED':
      // Handle manual rejection
      await notifySupport(data.id, 'KYC_MANUALLY_REJECTED');
      await sendRejectionEmail(data.id);
      break;

    default:
      // Log unexpected types
      console.log(`Unexpected webhook type ${type} for customer ${data.id}`);
  }

  res.status(200).send('OK');
});
Only customers with APPROVED status can create quotes and process conversions.

Customer types

For personal conversions and consumer wallets.Required fields: fullName, email, birthDate, address
curl -X POST 'https://api.lightspark.com/grid/2025-10-13/customers' \
  -u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET" \
  -H 'Content-Type: application/json' \
  -d '{
    "platformCustomerId": "user_12345",
    "customerType": "INDIVIDUAL",
    "fullName": "Alice Johnson",
    "email": "alice@example.com",
    "birthDate": "1990-01-15",
    "address": {...}
  }'
For corporate conversions and business accounts.Required fields: businessName, email, taxId, address
curl -X POST 'https://api.lightspark.com/grid/2025-10-13/customers' \
  -u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET" \
  -H 'Content-Type: application/json' \
  -d '{
    "platformCustomerId": "biz_67890",
    "customerType": "BUSINESS",
    "businessName": "Acme Corporation",
    "email": "finance@acme.com",
    "taxId": "12-3456789",
    "address": {...}
  }'

Next steps