Togul uses Stripe as its billing provider. Your subscription controls the limits applied to your organization: how many environments, flags, seats, and monthly evaluations you can use.
Plans
| Plan | Description |
|---|
free | Default plan for new organizations |
pro | Paid plan with higher limits, managed through Stripe |
enterprise | High-volume plan with custom limits |
Subscription schema
All billing endpoints return or operate on a SubscriptionSummary object.
| Field | Type | Description |
|---|
provider | string | Always stripe |
plan | string | free, pro, or enterprise |
status | string | See subscription status below |
seats | integer | Number of seats in the current plan |
limits | object | See subscription limits below |
provider_customer_id | string | null | Stripe customer ID |
provider_subscription_id | string | null | Stripe subscription ID |
current_period_start | datetime | null | Start of the current billing period |
current_period_end | datetime | null | End of the current billing period |
cancel_at_period_end | boolean | Whether the subscription cancels at the end of the current period |
Subscription limits
The limits object describes the resource caps enforced for the plan.
| Field | Type | Description |
|---|
environments | integer | Maximum number of environments |
flags | integer | Maximum number of flags |
seats | integer | Maximum number of organization members |
monthly_evaluations | int64 | Maximum flag evaluations per calendar month |
Subscription status
| Status | Description |
|---|
active | Subscription is current and all features are available |
trialing | In a trial period; full access applies |
past_due | Payment failed; access may be restricted |
canceled | Subscription has been canceled |
suspended | Account suspended; access is restricted |
Organizations with past_due or suspended status may have restricted access to API resources. Resolve the payment issue in the billing portal or contact support.
Get subscription
Returns the current subscription and entitlements for your organization.
GET /api/v1/billing/subscription — requires billing.read permission.
curl http://localhost:8080/api/v1/billing/subscription \
-H "Authorization: Bearer $TOKEN"
Response:
{
"subscription": {
"provider": "stripe",
"plan": "pro",
"status": "active",
"seats": 10,
"limits": {
"environments": 10,
"flags": 500,
"seats": 10,
"monthly_evaluations": 1000000
},
"provider_customer_id": "cus_abc123",
"provider_subscription_id": "sub_xyz789",
"current_period_start": "2026-03-01T00:00:00Z",
"current_period_end": "2026-04-01T00:00:00Z",
"cancel_at_period_end": false
}
}
Create a checkout session
Starts a Stripe checkout flow to upgrade to a paid plan. The response contains a url to redirect the user to.
POST /api/v1/billing/checkout — requires billing.write permission.
| Field | Type | Required | Description |
|---|
plan | string | Yes | pro or enterprise |
success_url | URI | No | Redirect URL after successful payment |
cancel_url | URI | No | Redirect URL if the user cancels checkout |
curl -X POST http://localhost:8080/api/v1/billing/checkout \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"plan": "pro",
"success_url": "https://app.example.com/billing?success=true",
"cancel_url": "https://app.example.com/billing"
}'
Response:
{
"url": "https://checkout.stripe.com/pay/cs_live_..."
}
Redirect the user to url to complete payment. After checkout, Stripe delivers a webhook event that syncs the subscription automatically.
Create a billing portal session
Opens the Stripe self-service billing portal where users can manage payment methods, view invoices, and cancel their subscription.
POST /api/v1/billing/portal — requires billing.read permission.
| Field | Type | Required | Description |
|---|
return_url | URI | No | URL to return to after the user exits the portal |
curl -X POST http://localhost:8080/api/v1/billing/portal \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"return_url": "https://app.example.com/billing"
}'
Response:
{
"url": "https://billing.stripe.com/session/..."
}
Stripe webhook
Togul exposes a webhook endpoint that Stripe uses to deliver subscription lifecycle events. You configure this URL in your Stripe dashboard.
POST /api/v1/webhooks/stripe
The endpoint verifies the Stripe-Signature header on every request and applies subscription changes idempotently — duplicate or out-of-order events are handled safely.
curl -X POST http://localhost:8080/api/v1/webhooks/stripe \
-H "Stripe-Signature: t=1234567890,v1=abc..." \
-H "Content-Type: application/json" \
-d '{...stripe event payload...}'
Response:
You do not need to call this endpoint directly. Configure your Stripe webhook to point to this URL and Togul handles subscription synchronization automatically.