Customers API
The Customers API allows you to create, manage, and track customers for your application. Customers represent the individuals or organizations that subscribe to your plans and use your services.
Overview
Customers are the core entities in your subscription system. Each customer can have:
- Contact Information: Email, name, and other identifying details
- Multiple Subscriptions: Customers can have multiple active subscriptions
- Billing Details: Address and tax information for invoicing
- Soft Deletion: Customers are soft-deleted to preserve historical data
Authentication
All API requests require authentication via merchant credentials.
Endpoints
Get All Customers
Get all customers for the authenticated merchant.
GET https://api.getlumen.dev/v1/customers?includePaymentData={includePaymentData}
Query Parameters
Parameter | Type | Description |
---|---|---|
includePaymentData | boolean | When true , include payment aggregates per customer |
Response (basic)
{
"customers": [
{
"id": "cust_stable_123",
"email": "customer@example.com",
"name": "John Doe",
"externalCustomerId": "user_ext_123",
"billingAddressLine1": "123 Main St",
"billingAddressLine2": "Apt 4B",
"billingCity": "New York",
"billingPostalCode": "10001",
"billingCountry": "US",
"taxId": "12-3456789",
"merchantId": "merchant_123",
"createdAt": "2024-01-01T00:00:00Z",
"updatedAt": "2024-01-01T00:00:00Z",
"deletedAt": null
}
]
}
Response (when includePaymentData=true)
{
"customers": [
{
"id": "cust_stable_123",
"email": "customer@example.com",
"name": "John Doe",
"externalCustomerId": "user_ext_123",
"customerOrganizationId": "org_abc",
"orgRole": "primary",
"totalPaymentsCents": 125000,
"paymentCount": 3,
"currency": "USD",
"createdAt": "2024-01-01T00:00:00Z",
"updatedAt": "2024-01-01T00:00:00Z"
}
]
}
Get Customer by ID
Get a specific customer by their ID.
GET https://api.getlumen.dev/v1/customers/{id}
Parameters
Parameter | Type | Description |
---|---|---|
id | string | Customer ID |
Response
{
"customer": {
"id": "cust_stable_123",
"email": "customer@example.com",
"name": "John Doe",
"externalCustomerId": "user_ext_123",
"billingAddressLine1": "123 Main St",
"billingAddressLine2": "Apt 4B",
"billingCity": "New York",
"billingPostalCode": "10001",
"billingCountry": "US",
"taxId": "12-3456789",
"merchantId": "merchant_123",
"createdAt": "2024-01-01T00:00:00Z",
"updatedAt": "2024-01-01T00:00:00Z",
"deletedAt": null
}
}
Create Customer
Create a new customer for the authenticated merchant.
POST https://api.getlumen.dev/v1/customers
Request Body
{
"email": "newcustomer@example.com",
"name": "Jane Smith",
"externalCustomerId": "user_ext_456",
"billingAddressLine1": "456 Oak Ave",
"billingAddressLine2": "Suite 200",
"billingCity": "San Francisco",
"billingPostalCode": "94102",
"billingCountry": "US",
"taxId": "98-7654321"
}
Request Fields
Field | Type | Required | Description |
---|---|---|---|
email | string | ✓ | Customer email address (must be unique) |
name | string | Customer full name | |
externalCustomerId | string | External user ID for integration | |
billingAddressLine1 | string | Primary billing address | |
billingAddressLine2 | string | Secondary billing address | |
billingCity | string | Billing city | |
billingPostalCode | string | Billing postal code | |
billingCountry | string | Billing country code | |
taxId | string | Tax identification number |
Response
{
"customer": {
"id": "cust_stable_456",
"email": "newcustomer@example.com",
"name": "Jane Smith",
"externalCustomerId": "user_ext_456",
"billingAddressLine1": "456 Oak Ave",
"billingAddressLine2": "Suite 200",
"billingCity": "San Francisco",
"billingPostalCode": "94102",
"billingCountry": "US",
"taxId": "98-7654321",
"merchantId": "merchant_123",
"createdAt": "2024-01-01T00:00:00Z",
"updatedAt": "2024-01-01T00:00:00Z",
"deletedAt": null
}
}
Update Customer
Update an existing customer's information.
POST https://api.getlumen.dev/v1/customers/{id}
Parameters
Parameter | Type | Description |
---|---|---|
id | string | Customer ID |
Request Body
{
"email": "updated@example.com",
"name": "Updated Name",
"externalCustomerId": "user_ext_updated",
"billingAddressLine1": "789 Pine St",
"billingAddressLine2": "Floor 3",
"billingCity": "Seattle",
"billingPostalCode": "98101",
"billingCountry": "US",
"taxId": "11-2233445"
}
Request Fields
All fields are optional and only provided fields will be updated:
Field | Type | Description |
---|---|---|
email | string | Customer email address |
name | string | Customer full name |
externalCustomerId | string | External user ID |
billingAddressLine1 | string | Primary billing address |
billingAddressLine2 | string | Secondary billing address |
billingCity | string | Billing city |
billingPostalCode | string | Billing postal code |
billingCountry | string | Billing country code |
taxId | string | Tax identification number |
dangerouslyAllowSameEmailForDifferentCustomers | boolean | Allow duplicate emails (not recommended) |
Response
{
"customer": {
"id": "cust_stable_123",
"email": "updated@example.com",
"name": "Updated Name",
"externalCustomerId": "user_ext_updated",
"billingAddressLine1": "789 Pine St",
"billingAddressLine2": "Floor 3",
"billingCity": "Seattle",
"billingPostalCode": "98101",
"billingCountry": "US",
"taxId": "11-2233445",
"merchantId": "merchant_123",
"createdAt": "2024-01-01T00:00:00Z",
"updatedAt": "2024-01-15T10:30:00Z",
"deletedAt": null
}
}
Delete Customer
Soft delete a customer (preserves historical data while marking as deleted).
DELETE https://api.getlumen.dev/v1/customers/{id}
Parameters
Parameter | Type | Description |
---|---|---|
id | string | Customer ID |
Response
{
"success": true
}
Examples
Creating a Customer
curl -X POST https://api.getlumen.dev/v1/customers \
-H "Content-Type: application/json" \
-d '{
"email": "customer@example.com",
"name": "John Doe",
"externalCustomerId": "user_123",
"billingAddressLine1": "123 Main St",
"billingCity": "New York",
"billingPostalCode": "10001",
"billingCountry": "US"
}'
Updating Customer Information
curl -X POST https://api.getlumen.dev/v1/customers/cust_stable_123 \
-H "Content-Type: application/json" \
-d '{
"email": "newemail@example.com",
"name": "John Smith",
"billingAddressLine1": "456 Oak Ave"
}'
Getting All Customers
curl -X GET "https://api.getlumen.dev/v1/customers?includePaymentData=true" \
-H "Content-Type: application/json"
Getting a Specific Customer
curl -X GET https://api.getlumen.dev/v1/customers/cust_stable_123 \
-H "Content-Type: application/json"
Deleting a Customer
curl -X DELETE https://api.getlumen.dev/v1/customers/cust_stable_123 \
-H "Content-Type: application/json"
Updating Customer with Duplicate Email (Not Recommended)
curl -X POST https://api.getlumen.dev/v1/customers/cust_stable_123 \
-H "Content-Type: application/json" \
-d '{
"email": "duplicate@example.com",
"dangerouslyAllowSameEmailForDifferentCustomers": true
}'
Customer Portal Endpoints
These endpoints support building a customer-facing billing portal and require secret key or session authentication.
Get Customer Portal Overview
Aggregate view of a customer's subscription, payment methods, invoices, and recent payments.
GET https://api.getlumen.dev/v1/customers/portal/overview?externalCustomerId={externalCustomerId}
Query Parameters
Parameter | Type | Description |
---|---|---|
externalCustomerId | string | External customer ID |
Response
{
"portal": {
"customer": { "id": "cust_123", "name": "Jane", "email": "jane@example.com" },
"subscription": {
"id": "sub_123",
"stableSubscriptionId": "ss_123",
"status": "active",
"planId": "plan_123",
"gracePeriodEndsAt": null,
"paymentMethodId": "pm_123"
},
"paymentMethods": [
{
"id": "pm_123",
"provider": "stripe",
"paymentType": "card",
"status": "active",
"cardBrand": "visa",
"cardLastFour": "4242",
"cardExpiryMonth": 12,
"cardExpiryYear": 2030,
"linkedToSubscription": true
}
],
"invoices": [
{
"id": "inv_123",
"number": "INV-0001",
"status": "paid",
"totalAmountCents": 5000,
"currency": "USD",
"issueDate": "2024-01-01T00:00:00Z",
"paidDate": "2024-01-02T00:00:00Z",
"pdfUrl": "https://...",
"paymentStatus": "succeeded"
}
],
"payments": [
{
"id": "pay_123",
"amountCents": 5000,
"currency": "USD",
"status": "succeeded",
"createdAt": "2024-01-02T00:00:00Z",
"errorMessage": null,
"invoiceId": "inv_123"
}
]
}
}
Create Setup Intent / Payment Link
Creates a Stripe Setup Intent or Dodo payment link to add a payment method.
POST https://api.getlumen.dev/v1/customers/portal/create-setup-intent
Request Body
{
"externalCustomerId": "user_ext_123"
}
Response (Stripe)
{
"provider": "stripe",
"stripe": {
"clientSecret": "seti_..._secret_...",
"intentId": "seti_...",
"publishableKey": "pk_live_..."
}
}
Response (Dodo)
{
"provider": "dodo",
"dodo": {
"paymentLink": "https://pay.dodo..."
}
}
Set Subscription Payment Method
Link an existing payment method to the customer's active subscription.
POST https://api.getlumen.dev/v1/customers/portal/set-subscription-payment-method
Request Body
{
"externalCustomerId": "user_ext_123",
"paymentMethodId": "pm_123"
}
Response
{ "success": true }
Remove Payment Method
Soft delete a payment method from the customer.
DELETE https://api.getlumen.dev/v1/customers/portal/payment-methods/{id}
Parameters
Parameter | Type | Description |
---|---|---|
id | string | Payment Method ID |
Response
{ "success": true }
Check Subscription Status
Check if a user (by external ID) has an active subscription and return summary data.
GET https://api.getlumen.dev/v1/customers/subscription-status?externalCustomerId={externalCustomerId}
Response
{
"hasActiveSubscription": true,
"customer": { "id": "cust_123", "name": "Jane", "email": "jane@example.com" },
"subscription": {
"id": "sub_123",
"planId": "plan_123",
"planName": "Pro",
"planDescription": "Pro plan",
"priceId": "price_123",
"currency": "USD",
"pricingData": { "components": [] },
"startTimestamp": "2024-01-01T00:00:00Z"
}
}
Get Organization Customers
Get the organization and all customers (primary + seat members) for a primary customer.
GET https://api.getlumen.dev/v1/customers/{id}/organization-customers
Parameters
Parameter | Type | Description |
---|---|---|
id | string | Customer ID |
Response
{
"organization": {
"id": "org_abc",
"name": "Acme, Inc."
},
"customers": [
{ "id": "cust_primary", "orgRole": "primary" },
{ "id": "cust_member_1", "orgRole": "member" }
]
}
Error Responses
All endpoints may return these error responses:
400 Bad Request
{
"error": "Email is required"
}
404 Not Found
{
"error": "Customer not found or access denied"
}
{
"error": "Payment method not found"
}
409 Conflict
{
"error": "A customer with this email already exists"
}
{
"error": "Another customer with this email already exists. Use dangerouslyAllowSameEmailForDifferentCustomers to allow."
}
500 Internal Server Error
{
"error": "Failed to create customer"
}
{
"error": "Failed to update customer"
}
{
"error": "Failed to delete customer"
}
{
"error": "Active subscription required to add mandate for Dodo"
}
Important Notes
Email Uniqueness
- By default, customer emails must be unique within a merchant
- The system performs case-insensitive email comparison
- Use
dangerouslyAllowSameEmailForDifferentCustomers: true
to bypass this validation (not recommended for production)
Soft Deletion
- Customers are soft-deleted by setting the
deletedAt
timestamp - Soft-deleted customers are excluded from all queries by default
- This preserves historical data while removing customers from active operations
- Once deleted, customers cannot be restored through the API
Customer ID Format
- All customer IDs use the prefix
cust_
followed by a unique identifier - Customer IDs are validated to ensure they match the expected format
- IDs are stable and remain constant throughout the customer's lifecycle
Data Validation
- Email addresses are validated for format and uniqueness
- All request data is validated against the customer schema
- Invalid data will return appropriate error messages with details
Integration Considerations
- Use the
externalCustomerId
field to link customers to your external user system - Billing address information is optional but recommended for invoicing
- Tax ID field can be used for tax compliance and reporting
- All timestamps are in ISO 8601 format with UTC timezone
Merchant Isolation
- All operations are automatically scoped to the authenticated merchant
- Customers from other merchants are not accessible
- This ensures complete data isolation between different merchants