Subscription

Manage team subscriptions and browse self-serve plans.

Subscription endpoints require billing:read (view) or billing:write (create, change, cancel, portal). Plan listing is public.

Billing API — balance top-ups and saved payment methods


List plans

GET /plans

Returns active plans. No authentication required.

By default the endpoint returns base tier plans (Starter, Pro, Team, Enterprise, and any custom plans). Filter with the type query parameter:

typeReturns
base (default)Tier plans for POST /subscription signup
addonAdd-on plans for POST /subscription/addon checkout
allBoth base and add-on plans

Use the self_serve field to see which plans support Stripe Checkout signup. The default Starter tier is included for limits reference but is not subscribable — teams without a paid subscription receive Starter entitlements automatically.

In the workspace, browse base plans at Pricing with a comparison table and monthly/yearly toggle. Logged-in users can start Stripe Checkout from that page; existing subscribers are routed to Settings → Subscription. Browse and purchase add-ons at Settings → Billing → Add-ons.

Provider price IDs are stripped from the public response.

Response

Array of plan objects:

FieldTypeDescription
idstringPlan ID (use in subscription requests)
namestringDisplay name
descriptionstringPlan description
plan_typestringbase or addon
price_monthlyintMonthly price in cents (nullable)
price_yearlyintYearly price in cents (nullable)
credits_monthlyint64Included credits per period (microcents)
limitsobjectPlan limit definitions (maps to entitlement resources)
required_plan_idsstring[]Add-on plans only — base plan IDs the team must have an active primary subscription on before checkout. Omitted or empty means any team can purchase the add-on.
required_plan_namesstring[]Add-on plans only — display names resolved from required_plan_ids (same order) on GET /plans. Use for UI labels; compare the team's plan_id against required_plan_ids to check eligibility. Omitted on embedded PlanDTO objects from subscription endpoints.
stackablebooleanAdd-on plans only — when true, the team can purchase multiple subscriptions to the same add-on plan (each checkout adds another instance). When false, POST /subscription/addon rejects checkout if the add-on is already active. Base tier plans return false.
self_servebooleanWhether users can subscribe via checkout

Example:

bash
1curl https://api.inference.sh/plans \2  -H "X-API-Version: 2"34curl "https://api.inference.sh/plans?type=addon" \5  -H "X-API-Version: 2"

Get subscription

GET /subscription

Returns the current team's paid subscription, or null when no Stripe subscription is active.

Teams with null still run on the Starter tier: entitlements come from the Starter plan (see GET /entitlements and GET /entitlements/usage). Add credits via Billing or subscribe to Pro or Team for higher limits and included monthly credits.

Requires billing:read.

Response

FieldTypeDescription
plan_idstringSubscribed plan ID
planobjectEmbedded PlanDTO when loaded
intervalstringmonthly or yearly
statusstringtrialing, active, past_due, canceled, or paused
current_period_startstringISO timestamp
current_period_endstringISO timestamp
trial_endstringISO timestamp (optional)
cancel_at_period_endbooleanSubscription ends at period end if true
credits_per_periodint64Credits granted each period (microcents)

Stripe subscription IDs are omitted from public responses.

Example:

bash
1curl https://api.inference.sh/subscription \2  -H "Authorization: Bearer inf_your_key" \3  -H "X-API-Version: 2"

Create subscription

POST /subscription

Creates a Stripe Checkout session for subscription signup. Requires billing:write.

Body:

FieldTypeRequiredDescription
plan_idstringYesPlan ID from GET /plans
intervalstringNomonthly (default) or yearly
success_urlstringNoRedirect after success (defaults to {origin}/settings/billing/subscription?success=1)
cancel_urlstringNoRedirect if canceled (defaults to {origin}/settings/billing/subscription)

Response:

json
1{2  "url": "https://checkout.stripe.com/..."3}

Redirect the user to url to complete signup. After Stripe Checkout, the workspace reads ?success=1 on the subscription settings page, refreshes subscription state, and shows a confirmation toast.


Change plan

PUT /subscription

Upgrade or downgrade the active subscription. Requires billing:write.

Body:

json
1{2  "plan_id": "plan_pro"3}

Returns the updated SubscriptionDTO.


Cancel subscription

DELETE /subscription

Cancel the team's subscription. Requires billing:write.

Body (optional):

json
1{2  "at_period_end": true3}

Defaults to at_period_end: true (cancel at end of billing period). Set false for immediate cancellation.


Resume subscription

POST /subscription/resume

Resume a subscription that was set to cancel at period end. Requires billing:write.


Billing portal

POST /subscription/portal

Creates a Stripe Customer Portal session for managing payment methods and invoices. Requires billing:write.

Body:

FieldTypeRequiredDescription
return_urlstringYesURL to return to after the portal session

Response:

json
1{2  "url": "https://billing.stripe.com/..."3}

Add-on subscriptions

Add-on plans extend a team with extra features or capacity (for example a store-app feature gate like feature:seedance). They are billed as separate Stripe subscriptions and grant entitlements with source: "addon". Tier and add-on limits for the same resource are merged — boolean features use OR, numeric limits are summed (see Entitlements API).

By default, add-on checkout does not require a paid base subscription — teams on Starter can purchase self-serve add-ons directly. When an add-on plan sets required_plan_ids, checkout succeeds only if the team has an active primary subscription (active, trialing, or complimentary) on one of those base plans. Inspect required_plan_ids and required_plan_names on GET /plans?type=addon before starting checkout — names are resolved server-side so clients do not need a separate ID-to-name lookup.

List active add-ons

GET /subscription/addons

Returns the team's active add-on subscriptions. Requires billing:read.

Response: array of TeamPlanDTO objects:

FieldTypeDescription
idstringTeam plan ID (use when canceling)
plan_idstringAdd-on plan ID
statusstringactive, canceled, or complimentary
is_primarybooleanAlways false for add-ons
planobjectEmbedded PlanDTO when loaded
created_atstringISO timestamp when the add-on was activated

Example:

bash
1curl https://api.inference.sh/subscription/addons \2  -H "Authorization: Bearer inf_your_key" \3  -H "X-API-Version: 2"

Purchase add-on

POST /subscription/addon

Creates a Stripe Checkout session for an add-on purchase. Requires billing:write.

Body:

FieldTypeRequiredDescription
plan_idstringYesAdd-on plan ID from GET /plans?type=addon
intervalstringNomonthly (default) or yearly
success_urlstringNoRedirect after success (defaults to {origin}/settings/billing/subscription?addon_success=1)
cancel_urlstringNoRedirect if canceled (defaults to {origin}/settings/billing/subscription)

Response:

json
1{2  "url": "https://checkout.stripe.com/..."3}

Redirect the user to url to complete checkout. In the workspace, the add-ons settings page reads ?addon_success=1, refreshes add-on state, and shows a confirmation toast. Pass success_url with that query parameter (for example {origin}/settings/billing/addons?addon_success=1) to land users on the add-ons page after checkout. The API default redirect is {origin}/settings/billing/subscription?addon_success=1.

Errors (400, code subscription_error):

MessageCause
plan {id} is not an addonplan_id is a base tier plan
invalid planUnknown plan ID
this add-on requires a qualifying base plan. upgrade your subscription firstTeam is not on any plan listed in the add-on's required_plan_ids
this add-on is already active on your teamAdd-on has stackable: false and the team already has an active subscription to that plan

Cancel add-on

DELETE /subscription/addon/{teamPlanId}

Cancels an add-on immediately and revokes its entitlements. Requires billing:write. Use the id from GET /subscription/addons, not the plan ID.

Returns an empty success body on completion.

Example:

bash
1curl -X DELETE "https://api.inference.sh/subscription/addon/tp_abc123" \2  -H "Authorization: Bearer inf_your_key" \3  -H "X-API-Version: 2"

Workspace add-ons page

Settings → Billing → Add-ons lists active add-ons (with cancel confirmation) and, when any exist, an available add-ons section for active self-serve plans (self_serve not false). Each card shows monthly price, included limits, and a subscribe button with the price in the CTA (for example subscribe - $14/mo). When stackable is true, an active add-on shows add another so the team can purchase another instance. Non-stackable add-ons (stackable: false) show a disabled active button instead.

When an add-on sets required_plan_ids, the card also shows a requirement line (for example requires pro or team plan) using required_plan_names from the API. A green check appears when the team's current base plan_id matches one of the required IDs; otherwise a lock icon is shown and the CTA becomes upgrade plan to unlock, which routes to Settings → Billing → Subscription to change the base plan.

When a blocked store app returns addon_plan_id in an entitlement error, the workspace opens an add-on purchase modal with the plan name, price, and a subscribe CTA that routes to this add-ons page — the same POST /subscription/addon checkout flow as the cards above.


Plan limits

Plan limits define caps enforced at runtime — concurrency, request rate, storage, team seats, triggers, data retention, BYOK, and more. When a limit is exceeded, the API returns 402 (limit_exceeded) or 403 (feature_not_available) with structured error metadata.

Each limit in GET /plans responses includes a label field with a human-readable name (for example concurrent tasks, triggers) and an optional unit field for display formatting (for example mb, days for retention_days). Limits with a zero cap or no label are omitted from workspace plan cards.

Use GET /entitlements/usage (requires authentication) to inspect current usage vs limits. Use GET /entitlements to list entitlement rows without usage counts.

In the workspace, entitlement errors open an upgrade modal that lists higher tiers and marks the recommended plan — the cheapest option that resolves the blocked resource. When the error includes addon_plan_id, the modal switches to an add-on purchase flow instead (see Add-on subscriptions). The subscription settings page shows live resource usage from GET /entitlements/usage with progress bars (warning at 80%, highlighted at the cap) and a manage link to the add-ons page when the team has active add-ons. Manage subscriptions at Settings → Billing → Subscription. See REST overview — Workspace modals.

Entitlements API — Get usage


we use cookies

we use cookies to ensure you get the best experience on our website. for more information on how we use cookies, please see our cookie policy.

by clicking "accept", you agree to our use of cookies.
learn more.