customer()
Create, resolve, and configure a customer
customer()
Use owo.customer() to create or resolve a customer by email or ID. The response includes the customer's current billing configuration, and the same namespace exposes helpers for customer-specific billing controls.
For the dedicated guide covering customer-level billing overrides, precedence, and recommended usage, see Customer Config.
Signature
const customer = await owo.customer({
id?: string, // Optional: Your customer ID
email: string, // Required: Customer email
name?: string, // Optional: Display name
metadata?: Record<string, unknown>, // Optional: Custom data
});
await owo.customer.setFeatureConfig({
customer: string,
feature: string,
overage?: "block" | "charge" | null,
maxOverageUnits?: number | null,
});
await owo.customer.setOverageLimit({
customer: string,
maxOverageAmount: number | null,
onLimitReached?: "block" | "notify",
});Parameters
owo.customer(params)
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | - | Your internal customer ID |
email | string | ✅ | Customer email address |
name | string | - | Customer display name |
metadata | object | - | Custom key-value data |
owo.customer.setFeatureConfig(params)
| Parameter | Type | Required | Description |
|---|---|---|---|
customer | string | ✅ | Customer ID or identifier |
feature | string | ✅ | Feature slug or ID |
overage | "block" | "charge" | null | - | Override overage behavior for this feature |
maxOverageUnits | number | null | - | Override the hard overage cap for this feature |
Provide at least one of overage or maxOverageUnits. Pass null to clear an existing override.
owo.customer.setOverageLimit(params)
| Parameter | Type | Required | Description |
|---|---|---|---|
customer | string | ✅ | Customer ID or identifier |
maxOverageAmount | number | null | ✅ | Customer-wide spend cap in minor units |
onLimitReached | "block" | "notify" | - | Behavior when the spend cap is reached. Defaults to block |
Pass null for maxOverageAmount to remove the spend cap.
Returns
All three methods return the customer plus the current customer billing config.
interface CustomerResult {
id: string;
email: string;
name?: string;
metadata?: Record<string, unknown>;
billing: {
overageLimit: {
maxOverageAmount: number | null;
onLimitReached: "block" | "notify";
createdAt: number;
updatedAt: number;
} | null;
featureConfigs: Array<{
feature: {
id: string;
slug: string | null;
name: string;
};
overage: "block" | "charge" | null;
maxOverageUnits: number | null;
createdAt: number;
updatedAt: number;
}>;
};
createdAt: number;
updatedAt: number;
}Examples
Create or Resolve a Customer
import { Owostack } from "owostack";
const owo = new Owostack({ secretKey: process.env.OWOSTACK_API_KEY });
// Create an org customer
const org = await owo.customer({
email: "billing@acme.com",
name: "Acme Corporation",
metadata: { industry: "SaaS" },
});
console.log(org.id);
console.log(org.billing.overageLimit); // null by default
console.log(org.billing.featureConfigs); // []Resolve an Existing Customer
// Resolve existing customer by email
const existing = await owo.customer({
email: "billing@acme.com",
});
// Or by your internal ID
const byId = await owo.customer({
id: "org_acme",
email: "billing@acme.com",
});Set a Per-Feature Overage Policy
const updated = await owo.customer.setFeatureConfig({
customer: "cust_123",
feature: "api_calls",
overage: "block",
maxOverageUnits: 1000,
});
console.log(updated.billing.featureConfigs);Set a Customer-Wide Overage Spend Cap
const updated = await owo.customer.setOverageLimit({
customer: "cust_123",
maxOverageAmount: 500_000,
onLimitReached: "block",
});
console.log(updated.billing.overageLimit);Clear Customer Billing Overrides
await owo.customer.setFeatureConfig({
customer: "cust_123",
feature: "api_calls",
overage: null,
maxOverageUnits: null,
});
await owo.customer.setOverageLimit({
customer: "cust_123",
maxOverageAmount: null,
onLimitReached: "block",
});Using the Customer Object
The returned customer object has convenience methods:
const org = await owo.customer({ email: "org@acme.com" });
// Attach subscription
await org.attach({ product: "team" });
// Manage entities (seats)
await org.addEntity({
feature: "seats",
entity: "user_123",
name: "John Doe",
});
const { entities } = await org.listEntities({ feature: "seats" });Entity Management Methods
Customer objects provide these entity management methods:
customer.addEntity(params)
Add an entity (e.g., seat) to the customer.
await org.addEntity({
feature: "seats",
entity: "user_123",
name: "John Doe",
email: "john@acme.com",
metadata: { role: "admin" },
});Parameters:
feature(string, required): Feature slugentity(string, required): Your entity IDname(string, optional): Display nameemail(string, optional): Contact emailmetadata(object, optional): Custom data
customer.removeEntity(params)
Remove an entity and free up the slot.
await org.removeEntity({
feature: "seats",
entity: "user_123",
});customer.listEntities(params?)
List entities for this customer.
// List all entities
const { entities } = await org.listEntities();
// Filter by feature
const { entities: seats } = await org.listEntities({ feature: "seats" });Best Practices
- Create early - Create the customer before attaching subscriptions or adding entities
- Use consistent IDs - Either always pass your own
idor always use email as identifier - Store metadata - Use metadata for customer segmentation and analytics
- Use spend caps as safety rails -
setOverageLimit()protects the whole customer across billable overage - Use feature config for exceptions -
setFeatureConfig()is best for one risky or contract-specific feature - Update on changes - Call
customer()when user data changes to keep billing records in sync
Related
- Customer Config - Customer-level billing overrides and spend caps
attach()- Subscribe customer to a plan- Overage - How plan overage and customer overrides interact
addEntity()- Add entities/seats (flat API)- Seat Pricing Guide - Complete seat-based billing walkthrough