Billing API

Check usage, list available tiers, and manage the active plan. Only relevant when DEPLOYMENT_MODE=saas. In self-hosted mode, endpoints still respond but return "saas": false.

Billing status

http
GET /api/billing/status Authorization: Bearer {msp-token} Host: atechsolutions.org # Response (SaaS mode, Growth plan at 41% usage): {{ "saas": true, "tier": "growth", "tier_name": "Growth", "tier_price_cad": 129, "asset_limit": 1000, "total_assets": 412, "usage_pct": 41.2, "usage_status": "ok", # ok | warning | exceeded "trial_days_left": null, "trial_expired": false, "next_tier": {{ "key": "scale", "name": "Scale", "asset_limit": 5000, "price_cad": 349 }}, "billing_email": "billing@yourmsp.com" }}
http
# Response (self-hosted mode): {{ "saas": false, "tier": "selfhosted", "asset_limit": null, "total_assets": 847 }}
usage_status valueConditionUI behaviour
okUnder 80% of limitGreen usage bar in sidebar
warning80% or more of limitAmber usage bar; warning banner on dashboard
exceededAt or over 100% of limitRed usage bar; 402 errors on any asset creation

List tiers

http
GET /api/billing/tiers Authorization: Bearer {msp-token} # Returns all billable tiers (trial through enterprise): [ {{"key": "trial", "name": "Free Trial", "asset_limit": 250, "price_cad": 0}}, {{"key": "starter", "name": "Starter", "asset_limit": 250, "price_cad": 49}}, {{"key": "growth", "name": "Growth", "asset_limit": 1000, "price_cad": 129}}, {{"key": "scale", "name": "Scale", "asset_limit": 5000, "price_cad": 349}}, {{"key": "enterprise", "name": "Enterprise", "asset_limit": null, "price_cad": null}} ]

Update tier

http
PUT /api/billing/tier Authorization: Bearer {msp-token} Content-Type: application/json {{ "tier": "growth", "billing_email": "billing@yourmsp.com", "notes": "Stripe customer: cus_abc123" }} # Returns: {{"ok": true, "tier": "growth"}}

This endpoint requires tenants.manage permission. It is intended to be called by you (the MSP operator) after a customer pays — either manually or via a Stripe webhook. Tether does not include built-in payment processing.

Stripe webhook integration

To automate tier changes after payment, create a Stripe webhook that calls this endpoint on checkout.session.completed events. Include your MSP admin Bearer token in the webhook handler.

Trial expiry behaviour

New SaaS installations start on a 30-day trial. When the trial expires:

Last updated: May 2026