Customers
Customers are the core entity in PimaBill. Every subscription, invoice, and payment is associated with a customer. This guide covers all customer operations in detail.
Customer Object
A customer record contains the following fields:
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier (e.g., cust_x1y2z3) |
externalId | string | Your application's user ID for cross-referencing |
email | string | Customer's email address (unique per tenant) |
name | string | Customer's full name |
country | string | ISO 3166-1 alpha-2 country code |
currency | string | Preferred currency (ISO 4217) |
status | string | Customer status: active or inactive |
metadata | object | Custom key-value pairs for your application data |
totalSpent | number | Lifetime total amount paid |
activeSubscriptions | number | Count of active subscriptions |
createdAt | string | ISO 8601 creation timestamp |
updatedAt | string | ISO 8601 last update timestamp |
Creating Customers
Create a customer with at minimum an email address and name.
curl -X POST http://localhost:4000/api/customers \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk_live_a1b2c3d4..." \
-d '{
"externalId": "usr_98765",
"email": "sarah@kampaltech.ug",
"name": "Nakato Sarah",
"country": "UG",
"currency": "UGX",
"metadata": {
"userId": "usr_98765",
"accountType": "business"
}
}'
import { PimaBillClient } from 'pimabill';
const client = new PimaBillClient({ token: 'sk_live_a1b2c3d4...' });
const customer = await client.customers.create({
externalId: 'usr_98765',
email: 'sarah@kampaltech.ug',
name: 'Nakato Sarah',
country: 'UG',
currency: 'UGX',
metadata: {
userId: 'usr_98765',
accountType: 'business'
}
});
console.log('Customer created:', customer.id);
from pimabill import PimaBillClient
client = PimaBillClient(token="sk_live_a1b2c3d4...")
customer = client.customers.create(
external_id="usr_98765",
email="sarah@kampaltech.ug",
name="Nakato Sarah",
country="UG",
currency="UGX",
metadata={
"user_id": "usr_98765",
"account_type": "business"
}
)
print(f"Customer created: {customer.id}")
409 Conflict error.Updating Customers
Update any customer field. Only the fields you provide will be updated; omitted fields remain unchanged.
curl -X PATCH http://localhost:4000/api/customers/cust_x1y2z3 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk_live_a1b2c3d4..." \
-d '{
"name": "Nakato Sarah Williams",
"metadata": {
"userId": "usr_98765",
"accountType": "enterprise",
"upgradeDate": "2025-03-01"
}
}'
const updated = await client.customers.update('cust_x1y2z3', {
name: 'Nakato Sarah Williams',
metadata: {
userId: 'usr_98765',
accountType: 'enterprise',
upgradeDate: '2025-03-01'
}
});
console.log('Updated:', updated.name);
updated = client.customers.update(
"cust_x1y2z3",
name="Nakato Sarah Williams",
metadata={
"user_id": "usr_98765",
"account_type": "enterprise",
"upgrade_date": "2025-03-01"
}
)
print(f"Updated: {updated.name}")
metadata field is replaced entirely on update. If you want to add a new key while preserving existing ones, include all existing metadata keys in the update request.Listing and Filtering Customers
Retrieve customers with pagination, search, and sorting.
Find a customer by your own ID
GET /api/customers?externalId=usr_98765 returns the customer created with that externalId (an empty data list if there is none). IDs differ between live and the sandbox, but your externalId is the same in both, so use this rather than storing PimaBill IDs.
Basic Listing
curl -X GET "http://localhost:4000/api/customers?page=1&limit=20" \
-H "Authorization: Bearer sk_live_a1b2c3d4..."
const customers = await client.customers.list({
page: 1,
limit: 20
});
console.log(`Showing ${customers.data.length} of ${customers.meta.total} customers`);
customers = client.customers.list(page=1, limit=20)
print(f"Showing {len(customers.data)} of {customers.meta.total} customers")
Search by Name or Email
curl -X GET "http://localhost:4000/api/customers?search=sarah&page=1&limit=20" \
-H "Authorization: Bearer sk_live_a1b2c3d4..."
const results = await client.customers.list({
search: 'sarah',
page: 1,
limit: 20
});
for (const customer of results.data) {
console.log(`${customer.name} - ${customer.email}`);
}
results = client.customers.list(search="sarah", page=1, limit=20)
for customer in results.data:
print(f"{customer.name} - {customer.email}")
Getting Customer Details
curl -X GET http://localhost:4000/api/customers/cust_x1y2z3 \
-H "Authorization: Bearer sk_live_a1b2c3d4..."
const customer = await client.customers.get('cust_x1y2z3');
console.log(JSON.stringify(customer, null, 2));
customer = client.customers.get("cust_x1y2z3")
print(customer)
Deleting Customers
Delete a customer and all their associated data. This action is irreversible.
curl -X DELETE http://localhost:4000/api/customers/cust_x1y2z3 \
-H "Authorization: Bearer sk_live_a1b2c3d4..."
await client.customers.delete('cust_x1y2z3');
console.log('Customer deleted');
client.customers.delete("cust_x1y2z3")
print("Customer deleted")
Best Practices
- Use metadata for application data -- Store your application's user IDs, account types, and other relevant data in the metadata field. This makes it easy to correlate PimaBill customers with your application records.
- Store customer IDs -- Save the PimaBill customer ID (
cust_...) in your application's user record for easy lookups. - Validate email uniqueness -- The API enforces email uniqueness per tenant. Handle
409 Conflicterrors gracefully in your integration. - Set country and currency -- Always provide the customer's country and preferred currency for accurate billing and payment routing.