Plan groups and plans
A plan group is a logical container. You might have one group called “Monthly Plans” and another called “Annual Plans”, or one called “Core” and another called “Enterprise”. A plan belongs to a group and has:- A name (e.g., “Pro”)
- An amount in kobo (e.g., 500000 for ₦5,000)
- A billing interval (
monthoryear) - An optional trial period in days
- A required
lookup_key— a stable handle (e.g.pro_monthly) you reference instead of the UUID
Create a plan group and plan
First, create the group:Response
Trial periods
Settrial_period_days on a plan. New subscribers start in trialing state and aren’t charged until the trial ends. When the trial expires, the subscription transitions to active and the first invoice is created.
If a subscriber cancels during trial, they’re never charged. The subscription.canceled webhook fires.
Amounts are in kobo
All
amount_minor values are in kobo — 1/100th of a Naira. Never pass decimal values.| Naira price | amount_minor |
|---|---|
| ₦500/month | 50000 |
| ₦2,000/month | 200000 |
| ₦5,000/month | 500000 |
| ₦12,000/month | 1200000 |
| ₦120,000/year | 12000000 |
Lookup keys
Every plan requires alookup_key (lowercase letters, numbers, underscores — unique per tenant) so your app references a plan by a stable role instead of an environment-specific UUID:
GET /v1/plans, find the plan whose lookup_key is pro_monthly, and use its id — no hardcoded ids, and the mapping survives re-provisioning, renames, and price changes. (Reusing a key returns 409.)
Changing prices, archiving & deleting plans
To change a price: create a new plan (new price, newlookup_key e.g. pro_monthly_v2), archive the old one, then either grandfather existing subscribers or migrate them with a plan change.
Deleting is archive-by-default. DELETE /v1/plans/{id}:
- If the plan has subscribers → it’s archived (
active: false): existing subscribers keep billing, history is preserved, and it stops accepting new sign-ups. Response:{ archived: true, deleted: false }. - If the plan was never subscribed → it’s hard-deleted. Response:
{ archived: false, deleted: true }.
List all plans
?include_archived=true to include archived plans.