Manage the subscription
Let an app or agent run the store's whole Nembol subscription (subscribe, upgrade, downgrade, switch to annual, update the card, cancel and renew) while the person always confirms on the payment provider's page.
The billing endpoints cover the whole subscription lifecycle, with one rule: the API prepares, the person confirms, the payment provider executes. No money moves through the API. Every action that involves a payment returns a link to the provider's own page (Stripe Checkout, the Stripe customer portal or PayPal) where the person sees the exact amount and confirms.
Your key needs billing:read to read and billing:manage to create links.
These endpoints keep working when the store is no longer on an API plan.
That's how a downgraded or lapsed store comes back.
1. Read what's possible
curl https://api.nembol.com/rest/v1/billing \
-H "Authorization: Bearer $NEMBOL_API_KEY"{
"object": "billing",
"billing_source": "stripe",
"managed_elsewhere": null,
"plan": { "key": "enterprise", "name": "Enterprise", "interval": "month" },
"status": "active",
"current_period_end": "2026-11-08T07:41:43.000Z",
"cancel_at_period_end": false,
"payment_method": { "brand": "visa", "last4": "4242" },
"usage": { "products": 350, "max_accounts_on_one_channel": 3, "team_members": 0 },
"plans": [
{
"key": "pro",
"name": "Pro",
"limits": { "products": 2000, "accounts_per_channel": 2, "team_members": 0 },
"prices": {
"month": { "amount": 49, "currency": "usd", "selectable": false,
"reason": "The store has 3 accounts on one channel; Pro allows 2 per channel." },
"year": { "amount": 441, "currency": "usd", "selectable": false, "reason": "…" }
}
}
// … basic, enterprise, enterprise_plus
],
"invoices": [ { "amount": "79.00", "status": "paid", "url": "https://invoice.stripe.com/…", "created_at": "…" } ],
"actions": { "change_plan": true, "update_payment_method": true, "cancel": true, "manage": true }
}plans[].prices.*.selectable tells you which plan changes are accepted
right now, and reason tells you why not. Show it to the person; it's
written for them.
2. Change the plan
Subscribing, reactivating, upgrading, downgrading and switching between monthly and annual are all the same call:
curl -X POST https://api.nembol.com/rest/v1/billing/plan_change_link \
-H "Authorization: Bearer $NEMBOL_API_KEY" \
-H "Content-Type: application/json" \
-d '{"plan": "enterprise_plus", "interval": "year",
"return_url": "https://app.example.com/billing/done"}'{
"object": "billing_link",
"action": "change_plan",
"provider": "stripe",
"plan": "enterprise_plus",
"interval": "year",
"url": "https://billing.stripe.com/p/session/…"
}Which page opens depends on the store:
| Store | Page |
|---|---|
| Trial, canceled, or no card yet | Stripe Checkout: enter a card and subscribe |
| Active Stripe subscription | Stripe confirmation page with the prorated amount |
| Billed through PayPal | PayPal approval page |
| Billed through Shopify, Wix or WooCommerce.com | Not available here: billing_managed_elsewhere |
Nothing changes until the person confirms. Afterwards, GET /billing
shows the new plan.
Limits are the same as in the dashboard
A plan change is refused, before any link is created, when the store's usage doesn't fit the target plan:
{
"error": {
"type": "invalid_request_error",
"code": "plan_limits_exceeded",
"message": "The store has 3 accounts on one channel; Pro allows 2 per channel. Reduce usage first, or pick a larger plan.",
"param": "plan"
}
}The checks are products, connected accounts per channel and team members.
To downgrade, reduce usage first (for example, disconnect a channel
account with POST /channel_accounts/{id}/disconnect), then ask again.
3. Card, cancellation, renewal
| Goal | Call | What the person does |
|---|---|---|
| Add or replace the card | POST /billing/payment_method_link | Updates the card on Stripe (or the automatic payment on PayPal) |
| Cancel | POST /billing/cancel_link | Confirms on Stripe and may give a reason. Access continues until current_period_end |
| Undo a cancellation, see invoices | POST /billing/manage_link | Clicks Don't cancel subscription in the Stripe portal |
| Restart the free trial | POST /billing/restart_trial | Nothing. It's free and immediate when eligible |
A trial has nothing to cancel: cancel_link answers nothing_to_cancel.
A new trial is available only to canceled stores that never restarted one
and never paid, or whose last paid period ended more than 3 months ago
(trial_not_available otherwise).
Return URLs
return_url is optional (the default is the Nembol dashboard). When you
pass one, it must start with a URL registered for the store. It's the same
allowlist used by channel connects (POST /redirect_urls, or Settings → Developers → Redirect URLs).
Good practice for agents
- Create a link right before handing it to the person, and don't store it: links are short-lived.
- Always say what will happen before sending the link ("this switches you to Enterprise+ yearly, $1,161/year; Stripe will show the prorated amount").
- Check
GET /billingafter the person returns instead of assuming the change happened. They may have closed the page.
Last updated on October 15, 2026
Need help?
Email us and a human replies, usually within one business day.