Skip to main content

Billing and Usage

Mandaitor exposes tenant-scoped billing and usage endpoints so dashboard surfaces can show consumption, invoices, payment readiness, and subscription state without duplicating billing logic in the frontend. These endpoints are implemented in the backend and are now included in the API reference.

Usage Metering

Tenant usage is retrieved with GET /tenants/{id}/usage. The endpoint is intended for dashboard cards, quota indicators, and operational review screens that need to show API consumption over the current billing period.

Mandaitor tenant Usage dashboard showing total billing units, average daily usage, active days, the top endpoint, a daily usage chart, an endpoint breakdown, and per-API-key consumption
The tenant Usage view turns the GET /tenants/{id}/usage response into billing-unit totals, a daily consumption trend, and per-endpoint and per-API-key breakdowns for the selected billing period.
EndpointPurposeTypical consumer
GET /tenants/{id}/usageReturns tenant usage data and quota context.Dashboard usage cards and tenant operations screens.
GET /tenants/{id}/billingReturns billing status and invoice history.Billing settings and finance review views.
const usage = await client.get(`/tenants/${tenantId}/usage`);
console.log(usage.current_period);
console.log(usage.quota_limit);

Billing Status and Invoice History

GET /tenants/{id}/billing returns the tenant's Stripe-linked billing state and invoice history. The dashboard should use this endpoint as the source of truth for whether a tenant has a Stripe customer, whether a subscription exists, and which invoices are visible to tenant operators.

Field groupDescription
Customer linkageIndicates whether the tenant is mapped to a billing customer.
Subscription statusDescribes the active plan and current subscription state when present.
Invoice historyLists invoices available for review in the dashboard.

Collecting a Payment Method

Use POST /tenants/{id}/billing/setup-intent to create a Stripe SetupIntent for card collection. The backend owns SetupIntent creation so that Stripe secrets remain server-side and the frontend only receives the client-side material needed to complete collection.

const setup = await client.post(`/tenants/${tenantId}/billing/setup-intent`, {
return_url: "https://dashboard.mandaitor.io/settings/billing",
});

The dashboard should only render Stripe collection UI after receiving a successful setup-intent response. It should not create Stripe customers directly from the browser.

Creating or Updating a Subscription

Use POST /tenants/{id}/billing/subscription to create or update the tenant subscription for a pricing plan. The endpoint centralizes tenant-to-price mapping and subscription lifecycle changes.

const subscription = await client.post(`/tenants/${tenantId}/billing/subscription`, {
price_id: "price_metered_plan",
});

Subscription changes should be represented in the dashboard as asynchronous billing operations. If the payment provider requires additional user action, the dashboard should render the returned status rather than assuming immediate activation.

Admin Stripe Customer Synchronization

Platform administrators can backfill Stripe customer records for active tenants with POST /admin/billing/sync-customers. The endpoint scans active tenants, creates missing Stripe customers, and optionally creates a metered subscription when the backend is configured with a metered price.

EndpointRequired authorityPurpose
POST /admin/billing/sync-customersCognito JWT with mandaitor-admins membershipBackfills tenant customer records and optional metered subscriptions.

This operation is intended for controlled admin workflows and migrations. It should not be exposed in tenant self-service screens.