Customers API
Complete guide to managing customers via the API
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 /api/customers
Response
{
"customers": [
{
"id": "cust_stable_123",
"email": "customer@example.com",
"name": "John Doe",
"userId": "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
}
]
}
Get Customer by ID
Get a specific customer by their ID.
GET /api/customers/{id}
Parameters
Parameter | Type | Description |
---|---|---|
id | string | Customer ID |
Response
{
"customer": {
"id": "cust_stable_123",
"email": "customer@example.com",
"name": "John Doe",
"userId": "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 /api/customers
Request Body
{
"email": "newcustomer@example.com",
"name": "Jane Smith",
"userId": "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 | |
userId | 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",
"userId": "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 /api/customers/{id}
Parameters
Parameter | Type | Description |
---|---|---|
id | string | Customer ID |
Request Body
{
"email": "updated@example.com",
"name": "Updated Name",
"userId": "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 |
userId | 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",
"userId": "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 /api/customers/{id}
Parameters
Parameter | Type | Description |
---|---|---|
id | string | Customer ID |
Response
{
"success": true
}
Examples
Creating a Customer
curl -X POST /api/customers \
-H "Content-Type: application/json" \
-d '{
"email": "customer@example.com",
"name": "John Doe",
"userId": "user_123",
"billingAddressLine1": "123 Main St",
"billingCity": "New York",
"billingPostalCode": "10001",
"billingCountry": "US"
}'
Updating Customer Information
curl -X POST /api/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 /api/customers \
-H "Content-Type: application/json"
Getting a Specific Customer
curl -X GET /api/customers/cust_stable_123 \
-H "Content-Type: application/json"
Deleting a Customer
curl -X DELETE /api/customers/cust_stable_123 \
-H "Content-Type: application/json"
Updating Customer with Duplicate Email (Not Recommended)
curl -X POST /api/customers/cust_stable_123 \
-H "Content-Type: application/json" \
-d '{
"email": "duplicate@example.com",
"dangerouslyAllowSameEmailForDifferentCustomers": true
}'
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"
}
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"
}
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
userId
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