Plans & Tier Switching

Voicebip workspaces run on one of three tiered plans or in PAYG mode. You can switch tiers in the middle of a billing period — the platform refunds your unused base, charges the new tier’s prorated base, and carries unused quota forward.

TierMonthly baseVoiceSMSWhatsApp Conversations
StarterFreePer-minute ratePer-message ratePer-conv rate
BuilderPer pricing dashboardIncluded minutesIncluded messagesIncluded conversations
ScalePer pricing dashboardHigher includesHigher includesHigher includes
PAYGNoneAlways per-minuteAlways per-messageAlways per-conv

Live rates are admin-managed; the /v1/workspace/subscription endpoint returns whatever your workspace is currently subscribed to.

Get Your Active Subscription

$curl "https://api.voicebip.com/v1/workspace/subscription" \
> -H "Authorization: Bearer pk_live_your_key"

Response — 200 OK

1{
2 "id": "sub_abc123",
3 "workspace_id": "ws_abc123",
4 "plan": "builder",
5 "status": "active",
6 "period_start": "2026-05-01T00:00:00Z",
7 "period_end": "2026-06-01T00:00:00Z",
8 "created_at": "2026-05-01T00:00:00Z",
9 "updated_at": "2026-05-01T00:00:00Z"
10}
StatusMeaning
200Active subscription returned
404No active subscription — workspace is PAYG
503Subscription store unavailable (operational alert)

Switch Tiers

$curl -X PATCH "https://api.voicebip.com/v1/workspace/subscription" \
> -H "Authorization: Bearer pk_live_your_key" \
> -H "Content-Type: application/json" \
> -d '{ "plan": "builder" }'

Response — 200 OK

1{
2 "subscription": {
3 "id": "sub_abc123",
4 "workspace_id": "ws_abc123",
5 "plan": "builder",
6 "status": "active",
7 "period_start": "2026-05-01T00:00:00Z",
8 "period_end": "2026-06-01T00:00:00Z",
9 "last_tier_switch_at": "2026-05-15T14:32:01Z",
10 "created_at": "2026-05-01T00:00:00Z",
11 "updated_at": "2026-05-15T14:32:01Z"
12 },
13 "proration": {
14 "refund_minor": 8064,
15 "charge_minor": 24193,
16 "net_minor": 16129,
17 "proration_ratio": 0.5484,
18 "days_remaining": 17,
19 "period_days": 31,
20 "currency": "NGN",
21 "description": "17 days remaining, upgraded starter → builder"
22 },
23 "quota_after": {
24 "voice_minutes_remaining": 1120,
25 "sms_remaining": 4300,
26 "whatsapp_remaining": 540,
27 "numbers_included": 3
28 }
29}

Proration Math

Net charge = (new tier base × days remaining ÷ period days) − (old tier base × days remaining ÷ period days).

A net_minor > 0 means a debit was taken from your balance; net_minor < 0 means a credit was issued. Both are recorded in the recurring_charges ledger and visible on the usage dashboard.

Quota Carryover

Unused voice minutes, SMS, and WhatsApp conversations from the old tier are preserved when you switch. The new tier’s included quotas are prorated by days_remaining / period_days — not granted in full — so oscillating between tiers within one period cannot farm free quota. At the next anniversary the new tier’s full monthly quota seeds.

Errors

Statuserror_codeCause
400NO_OPAlready on the requested plan — no transition needed.
400TIER_SWITCH_UNSUPPORTEDWorkspace is PAYG. Subscribe first via the dashboard.
400INVALID_PLANPlan name is not one of starter, builder, scale.
402INSUFFICIENT_BALANCEThe net charge would exceed your balance. Top up via Paystack first.
404NO_ACTIVE_SUBSCRIPTIONNothing to switch — workspace has no live subscription.
404WORKSPACE_NOT_FOUNDThe workspace could not be resolved.
429TIER_SWITCH_TOO_FREQUENTYou changed tiers within the last 24 hours. The cooldown prevents abuse of proration math.
503STORE_UNAVAILABLESubscription store temporarily unreachable. Retry.

Idempotency

Tier-switch PATCHes are idempotent. If your client retries the same PATCH after a network timeout, the platform either:

  • Returns NO_OP if the first attempt completed successfully, or
  • Replays the first attempt’s response (same proration payload) if the retry races the original.

You will not be double-billed. The underlying guarantee is a unique index on (workspace_id, charge_type, period_start, proration_note) in the recurring_charges ledger — a duplicate insert raises a constraint violation that the handler silently absorbs, preventing double-debits on retried requests.

Cooldown

After a successful tier change, the next PATCH is rejected with 429 TIER_SWITCH_TOO_FREQUENT for 24 hours. This is enforced server-side via subscriptions.last_tier_switch_at. The 24-hour window starts at the moment the transition committed, not at the moment of the next request.

If you need to switch tiers more often than once a day — e.g. during a controlled migration window — contact support and we can clear the cooldown manually.

What Tier-Switching Does Not Do

  • It does not change your API keys, agents, or numbers.
  • It does not change your data residency or NDPR posture.
  • It does not cancel a subscription. To stop being billed at a tier, switch to starter and the next anniversary will not auto-charge. Hard cancellation is not self-serve today — contact support.
  • It does not affect in-flight calls or messages — they bill at the rate active when the usage event was published.

Webhook Events

Tier switches do not emit a developer-facing webhook today. The internal billing.charged and billing.pricing.updated subjects fire but are not delivered. To detect a tier change in your application, poll GET /v1/workspace/subscription or watch the dashboard’s audit feed.