Skip to Content
API ReferenceSubscription

Subscription

Manage your workspace’s billing plan, AI add-on, and subscription lifecycle — including plan previews, downgrade readiness checks, and pending-change management.

Base URL

https://api.voxburst.io/v1/subscription

All subscription endpoints require a valid bearer token. The workspace is resolved from the token. Endpoints that write to Stripe (change-plan, preview-change, ai-addon, update, cancel-pending) return 503 Service Unavailable if the Stripe integration is not configured in the current environment.


Preview Plan Change

POST /v1/subscription/preview-change

Preview the proration cost for a plan change without executing it. Use this before calling change-plan to show the user exactly what they will be charged (upgrade) or credited (downgrade).

Request Body

FieldTypeRequiredDescription
planstringYesTarget plan: starter, pro, or agency
billingPeriodstringNomonthly (default) or yearly
curl -X POST https://api.voxburst.io/v1/subscription/preview-change \ -H "Authorization: Bearer vb_live_xxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "plan": "pro", "billingPeriod": "monthly" }'

Response

{ "currentPlan": "starter", "newPlan": "pro", "billingPeriod": "monthly", "isUpgrade": true, "prorationAmount": 18.39, "effectiveDate": "2026-05-06T00:00:00.000Z", "message": "You will be charged $18.39 immediately for the prorated difference." }
FieldTypeDescription
currentPlanstringWorkspace’s current plan
newPlanstringTarget plan
billingPeriodstringBilling cadence for the new plan
isUpgradebooleantrue if moving to a higher-priced plan
prorationAmountnumberAmount charged (upgrade) or credited (downgrade) in USD
effectiveDatestringISO 8601 timestamp when the change takes effect
messagestringHuman-readable summary of the charge or credit

Change Plan

POST /v1/subscription/change-plan

Execute a plan change. For upgrades, the prorated amount is charged immediately. For downgrades, a credit is applied to the next invoice. Preview the cost first with POST /preview-change.

Request Body

FieldTypeRequiredDescription
planstringYesTarget plan: free, starter, pro, or agency
billingPeriodstringNomonthly (default) or yearly
curl -X POST https://api.voxburst.io/v1/subscription/change-plan \ -H "Authorization: Bearer vb_live_xxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "plan": "pro", "billingPeriod": "monthly" }'

Response

{ "success": true, "message": "Plan updated to Pro successfully.", "plan": "pro", "billingPeriod": "monthly" }

Error Codes

StatusDescription
400Invalid plan transition or Stripe error (e.g. no payment method on file)
503Stripe not configured in this environment

Add or Update AI Add-On

POST /v1/subscription/ai-addon

Add, change, or remove the AI add-on for the authenticated user. Pass tier: null to remove the add-on.

Request Body

FieldTypeRequiredDescription
tierstring | nullYesAI add-on tier: starter, pro, or null to cancel
# Add the Pro AI add-on curl -X POST https://api.voxburst.io/v1/subscription/ai-addon \ -H "Authorization: Bearer vb_live_xxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "tier": "pro" }' # Remove the AI add-on curl -X POST https://api.voxburst.io/v1/subscription/ai-addon \ -H "Authorization: Bearer vb_live_xxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "tier": null }'

Response

{ "success": true, "message": "AI add-on updated to Pro.", "tier": "pro" }

Error Codes

StatusDescription
400Invalid tier or subscription state
401User not authenticated
422Payment processing error — card declined, no payment method, etc. The message field contains the Stripe error text
503Stripe not configured

Stripe payment errors are returned as 422 Unprocessable Entity rather than 500. Check the message field in the response body for the human-readable Stripe error (e.g. “Your card was declined.”).


Update Subscription (Combined)

POST /v1/subscription/update

Change the plan and/or AI add-on tier in a single atomic operation. Useful when the user wants to upgrade their plan and add an AI tier at the same time.

Request Body

FieldTypeRequiredDescription
planstringNoTarget plan: free, starter, pro, or agency
billingPeriodstringNomonthly (default) or yearly
aiTierstring | nullNoAI add-on tier (starter, pro) or null to remove
curl -X POST https://api.voxburst.io/v1/subscription/update \ -H "Authorization: Bearer vb_live_xxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "plan": "pro", "billingPeriod": "yearly", "aiTier": "starter" }'

Response

{ "success": true, "message": "Subscription updated successfully.", "plan": "pro", "billingPeriod": "yearly", "aiTier": "starter" }

Get AI Add-On Usage

GET /v1/subscription/ai-usage

Return the authenticated user’s current AI add-on status, credit usage, and billing period. If the user is on a legacy AI tier that has a recommended migration path, a migration object is included.

curl https://api.voxburst.io/v1/subscription/ai-usage \ -H "Authorization: Bearer vb_live_xxxxxxxxxxxxx"

Response (subscribed)

{ "subscribed": true, "tier": "pro", "credits_used": 1240, "credits_limit": 5000, "credits_remaining": 3760, "billing_period_start": "2026-05-01T00:00:00.000Z", "billing_period_end": "2026-06-01T00:00:00.000Z", "migration": null }

Response (not subscribed)

{ "subscribed": false, "tier": null, "credits_used": 0, "credits_limit": null, "credits_remaining": null, "billing_period_start": null, "billing_period_end": null, "migration": null }

Response Fields

FieldTypeDescription
subscribedbooleanWhether the user has an active AI add-on
tierstring | nullCurrent tier: starter, pro, or null
credits_usednumberCredits consumed this billing period
credits_limitnumber | nullCredits allotted per period (null = unlimited)
credits_remainingnumber | nullRemaining credits (null = unlimited)
billing_period_startstring | nullISO 8601 start of current billing period
billing_period_endstring | nullISO 8601 end of current billing period
migrationobject | nullMigration banner info if on a legacy tier (see below)

Migration Object

Present only when the user is on a legacy AI tier that has a recommended upgrade path:

FieldTypeDescription
bannerstringHuman-readable migration notice for display in the UI
recommendedTierstringThe recommended new tier (starter or pro)
monthlySavingsnumberMonthly savings in USD if the user switches
isClearUpgradebooleantrue if the new tier offers strictly more for less cost

Get Pending Changes

GET /v1/subscription/pending-changes

Returns any scheduled subscription changes — a pending downgrade to a lower plan, or a pending cancellation (reverts to free at period end). Returns { "pendingChanges": null } if no changes are scheduled.

curl https://api.voxburst.io/v1/subscription/pending-changes \ -H "Authorization: Bearer vb_live_xxxxxxxxxxxxx"

Response (pending downgrade)

{ "pendingChanges": { "type": "downgrade", "effectiveDate": "2026-06-01T00:00:00.000Z", "newPlan": "starter" } }

Response (pending cancellation)

{ "pendingChanges": { "type": "cancellation", "effectiveDate": "2026-06-01T00:00:00.000Z", "newPlan": "free" } }

Response (no pending changes)

{ "pendingChanges": null }
FieldTypeDescription
typestringdowngrade or cancellation
effectiveDatestring | nullISO 8601 date when the change takes effect
newPlanstringThe plan the workspace will move to

Cancel Pending Changes

POST /v1/subscription/cancel-pending

Cancel a scheduled downgrade or cancellation, keeping the current plan active. This calls Stripe to reverse the cancel_at_period_end flag if set, and clears any pending-downgrade metadata from the subscription record.

curl -X POST https://api.voxburst.io/v1/subscription/cancel-pending \ -H "Authorization: Bearer vb_live_xxxxxxxxxxxxx"

Response

{ "success": true, "message": "Pending changes cancelled. Your subscription will continue as normal." }

Error Codes

StatusDescription
404No subscription found for the workspace owner
503Stripe not configured

Downgrade Readiness Check

GET /v1/subscription/downgrade-readiness?targetPlan=<plan>

Advisory pre-flight check that compares the workspace’s current usage against the limits of the target plan. Returns a list of readiness items — one per resource category — each flagged as ok, heads_up, or action_needed. No changes are made; this endpoint is purely informational.

Categories checked: social_accounts, workspaces, ai_credits, monthly_posts.

Query Parameters

ParameterTypeRequiredDescription
targetPlanstringYesTarget plan: free, starter, pro, or agency
curl "https://api.voxburst.io/v1/subscription/downgrade-readiness?targetPlan=starter" \ -H "Authorization: Bearer vb_live_xxxxxxxxxxxxx"

Response

{ "targetPlan": "starter", "effectiveDate": "2026-06-01T00:00:00.000Z", "graceExpiresDate": "2026-06-06T00:00:00.000Z", "graceDays": 5, "items": [ { "category": "social_accounts", "current": 12, "allowed": 5, "excess": 7, "severity": "action_needed", "message": "You have 12 connected accounts. Starter allows 5. Designate 5 to keep before June 6 — posts to undesignated accounts will stop publishing.", "actionUrl": "/accounts?mode=downgrade-select&targetPlan=starter", "requiresDesignation": true }, { "category": "workspaces", "current": 1, "allowed": 1, "excess": 0, "severity": "ok", "message": "Your 1 workspace fits within Starter." }, { "category": "ai_credits", "current": 500, "allowed": 0, "excess": 500, "severity": "heads_up", "message": "Starter has no bundled AI credits. AI-assisted post generation stops on June 1.", "actionUrl": "/ai" } ] }

Response Fields

FieldTypeDescription
targetPlanstringThe plan being evaluated
effectiveDatestring | nullISO 8601 date the downgrade takes effect
graceExpiresDatestring | nullISO 8601 date the 5-day grace period expires after the downgrade
graceDaysnumberNumber of grace days (currently 5)
itemsobject[]Array of readiness items (one per category checked)

Readiness Item Fields

FieldTypeDescription
categorystringResource category: social_accounts, workspaces, ai_credits, or monthly_posts
currentnumberCurrent usage count (-1 = unlimited)
allowednumberLimit under the target plan
excessnumberAmount over the limit (0 if within limits)
severitystringok, heads_up, or action_needed
messagestringHuman-readable explanation, suitable for display in a checklist UI
actionUrlstringOptional URL to the settings page where the user can resolve the issue
requiresDesignationbooleantrue if the user must designate which accounts to keep (see Downgrade Designations)

severity: "action_needed" items with requiresDesignation: true require the user to explicitly choose which accounts to keep before the downgrade takes effect. Save their selection with PUT /v1/subscription/downgrade-designations.


Save Downgrade Designations

PUT /v1/subscription/downgrade-designations

Save (or update) the list of social accounts the workspace wants to keep when downgrading. If the workspace has more connected accounts than the target plan allows, the user must designate which ones to retain — posts to undesignated accounts will stop publishing after the grace period expires.

Calling this endpoint again with the same effectiveAt replaces the previous designation list (upsert by workspaceId + effectiveAt).

Request Body

FieldTypeRequiredDescription
effectiveAtstringYesISO 8601 datetime matching the downgrade effective date
targetPlanstringYesTarget plan: free, starter, pro, or agency
accountIdsstring[]YesArray of social account IDs to keep. Length must not exceed the target plan’s account limit.
curl -X PUT https://api.voxburst.io/v1/subscription/downgrade-designations \ -H "Authorization: Bearer vb_live_xxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "effectiveAt": "2026-06-01T00:00:00.000Z", "targetPlan": "starter", "accountIds": ["acc_111", "acc_222", "acc_333", "acc_444", "acc_555"] }'

Response

{ "saved": true, "count": 5 }

Error Codes

StatusDescription
400accountIds length exceeds the target plan’s account limit, or effectiveAt is not a valid ISO 8601 datetime

Billing Information Endpoints

The following endpoints live under /v1/billing/ and provide current subscription state, plan listings, and Stripe portal access.

Get Current Billing Status

GET /v1/billing/current

Returns the workspace’s current plan, billing interval, subscription status, trial information, and AI add-on status. This is the primary endpoint for checking what plan a workspace is on.

curl https://api.voxburst.io/v1/billing/current \ -H "Authorization: Bearer vb_live_xxxxxxxxxxxxx"

Response fields:

FieldTypeDescription
planstringCurrent plan: free, starter, pro, or agency
billingIntervalstringmonthly or annual (note: "annual" not "yearly")
statusstringStripe subscription status: active, canceled, past_due, trialing, etc.
currentPeriodStartstring | nullISO 8601 start of current billing period
currentPeriodEndstring | nullISO 8601 end of current billing period
cancelAtPeriodEndbooleantrue if the subscription will cancel at period end
trialEndstring | nullISO 8601 trial end date (if on trial)
trialTotalDaysnumber | nullTotal trial length in days
recentlyExpiredTrialbooleantrue if the trial has expired and the user has not yet chosen a paid plan
currentAmountCentsnumber | nullCurrent subscription amount in cents
isFoundingPricebooleantrue if the workspace is on a grandfathered founding member price
pendingDowngradestring | nullPlan slug if a downgrade is scheduled, else null
pendingDowngradeEffectivestring | nullISO 8601 date the pending downgrade takes effect
subscriptionIdstring | nullStripe subscription ID
aiAddonobject | nullCurrent AI add-on status. See AI Add-On Object below.

AI Add-On Object

The aiAddon field is an object (or null if no AI add-on data is available). It has the following shape:

FieldTypeDescription
subscribedbooleantrue if the workspace has an active AI add-on subscription or complimentary AI access.
tierstring | nullCurrent tier: starter, pro, or null. null is valid even when subscribed is true — this indicates complimentary or admin-granted AI access that is not tied to a specific Stripe-billed tier.
creditsUsednumberCredits consumed in the current billing period.
creditsLimitnumber | nullCredits allotted per period. null means unlimited — this occurs for complimentary subscriptions and admin-granted accounts. Do not treat null as missing data; treat it as no credit cap.
creditsRemainingnumber | nullRemaining credits. null means unlimited (same condition as creditsLimit: null).
billingPeriodEndstring | nullISO 8601 end of the current AI billing period. null for non-Stripe-billed (complimentary) subscriptions.

Known valid state combinations:

subscribedtiercreditsLimitMeaning
true"starter" or "pro"numberStandard paid AI add-on
truenullnullComplimentary or admin-granted AI access (unlimited, not Stripe-billed)
falsenullnullNo AI access

When creditsLimit is null, do not show a credit usage bar or a “credits remaining” counter — instead show an “Unlimited” badge or omit the field entirely. Rendering null as 0 will incorrectly suggest the workspace has no credits.


List Plans

GET /v1/billing/plans

Returns all available plans with pricing and limits. No authentication required.

curl https://api.voxburst.io/v1/billing/plans

Response:

{ "plans": [ { "id": "free", "name": "Free", "description": "Get started for free", "priceMonthly": 0, "priceYearly": 0, "limits": { "socialAccounts": 3, "monthlyPosts": 30 }, "popular": false } ] }

Create Checkout Session

POST /v1/billing/checkout

Creates a Stripe Checkout session for upgrading to a paid plan. Redirect the user to the returned url to complete payment.

Request body:

FieldTypeRequiredDescription
planIdstringYesTarget plan: starter, pro, or agency
billingPeriodstringNomonthly (default), yearly, or annual
successUrlstringYesURL to redirect to after successful payment
cancelUrlstringYesURL to redirect to if the user cancels checkout

Response:

{ "sessionId": "cs_live_xxxxxxxxxxxxx", "url": "https://checkout.stripe.com/..." }

Get Stripe Portal URL

GET /v1/billing/portal or POST /v1/billing/portal

Returns a Stripe Customer Portal URL for managing payment methods, invoices, and subscription settings.

# GET with query parameter curl "https://api.voxburst.io/v1/billing/portal?returnUrl=https://app.voxburst.io/settings/billing" \ -H "Authorization: Bearer vb_live_xxxxxxxxxxxxx" # POST with JSON body curl -X POST https://api.voxburst.io/v1/billing/portal \ -H "Authorization: Bearer vb_live_xxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "returnUrl": "https://app.voxburst.io/settings/billing" }'

Response:

{ "url": "https://billing.stripe.com/session/..." }

Cancel Subscription

POST /v1/billing/cancel

Schedules the subscription for cancellation at the end of the current billing period. The workspace continues on its current plan until currentPeriodEnd, then reverts to Free.

curl -X POST https://api.voxburst.io/v1/billing/cancel \ -H "Authorization: Bearer vb_live_xxxxxxxxxxxxx"

Resume Subscription

POST /v1/billing/resume

Reverses a pending cancellation. Only valid when cancelAtPeriodEnd is true. The subscription continues normally at the next renewal.

curl -X POST https://api.voxburst.io/v1/billing/resume \ -H "Authorization: Bearer vb_live_xxxxxxxxxxxxx"

Create Trial Checkout Session

POST /v1/billing/checkout/trial

Creates a Stripe Checkout session for starting a free trial. Redirect the user to the returned url.

Request body:

FieldTypeRequiredDescription
planstringYesPlan to trial: starter, pro, or agency
billingstringNomonthly (default) or annual
successUrlstringYesURL to redirect to after checkout completes
cancelUrlstringYesURL to redirect to if the user cancels

Response:

{ "sessionId": "cs_live_xxxxxxxxxxxxx", "url": "https://checkout.stripe.com/..." }

Create AI Add-On Checkout Session

POST /v1/billing/checkout/ai-addon

Creates a Stripe Checkout session to subscribe to an AI add-on tier.

Request body:

FieldTypeRequiredDescription
tierstringYesAI add-on tier: starter or pro
successUrlstringYesURL to redirect to after checkout completes
cancelUrlstringYesURL to redirect to if the user cancels

Response:

{ "sessionId": "cs_live_xxxxxxxxxxxxx", "url": "https://checkout.stripe.com/..." }

Get Subscription Details

GET /v1/billing/subscription

Returns the current Stripe subscription record for the workspace, including plan limits.

curl https://api.voxburst.io/v1/billing/subscription \ -H "Authorization: Bearer vb_live_xxxxxxxxxxxxx"

Response:

{ "plan": "pro", "status": "active", "currentPeriodStart": "2026-05-01T00:00:00.000Z", "currentPeriodEnd": "2026-06-01T00:00:00.000Z", "cancelAtPeriodEnd": false, "limits": { "maxWorkspaces": 3, "maxAccountsPerOrg": 35, "maxPostsPerMonth": 1000, "aiEnabled": true } }

Get Usage Summary

GET /v1/billing/usage

Returns current usage versus plan limits.

curl https://api.voxburst.io/v1/billing/usage \ -H "Authorization: Bearer vb_live_xxxxxxxxxxxxx"

Response:

{ "plan": "pro", "usage": { "workspaces": { "used": 1, "limit": 3 }, "accounts": { "used": 8, "limit": 35 }, "posts": { "used": 124, "limit": 1000 } }, "features": { "aiEnabled": true }, "billing": { "currentPeriodStart": "2026-05-01T00:00:00.000Z", "currentPeriodEnd": "2026-06-01T00:00:00.000Z", "cancelAtPeriodEnd": false } }

Acknowledge Trial End

POST /v1/billing/acknowledge-trial-end

Acknowledge that the user has seen the trial-ended notification. Clears the recentlyExpiredTrial flag on the workspace.

curl -X POST https://api.voxburst.io/v1/billing/acknowledge-trial-end \ -H "Authorization: Bearer vb_live_xxxxxxxxxxxxx"

Response:

{ "success": true }
Last updated on