Billing API
REST endpoints for billing in SKUFlow: 4 operations with parameters, request and response fields, permissions and curl examples.
Base URL: https://app.skuflow.ai/api. Every call needs Authorization: Bearer skf_… (Authentication); {organizationId} ($ORGANIZATION_ID in the examples) is your business's id.
| Operation | Endpoint | Risk |
|---|---|---|
| Get the SKUFlow plan | GET /organizations/{organizationId}/billing/plan | read |
| List the plans to choose from | GET /organizations/{organizationId}/billing/plan-options | read |
| Choose a plan (first run) | POST /organizations/{organizationId}/billing/choose-plan | sensitive |
| List AI credit packs | GET /organizations/{organizationId}/billing/credit-packs | read |
Get the SKUFlow plan
GET /organizations/{organizationId}/billing/plan
The business's SKUFlow plan: tier, trial, which plan features are included, and this period's AI credits, texts and SKUFlow emails (used, allowance, purchased credits, remaining). Also lists every plan for comparison. Read-only; any member.
| Permission | organization.read (Owner, Admin, Staff, Member) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | billing_plan (toolset settings) |
Example
curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/billing/plan" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
tier | enum or null | Null when billing is not set up on this server. One of core, connect, grow, pro. |
planName | string or null | |
status | string or null | TRIALING, ACTIVE, PAST_DUE, CANCELED, ... |
trialEndsAt | string or null | |
trialDaysLeft | integer or null | Whole days left in the trial; null when not trialing. |
currentPeriodEnd | string or null | |
cancelAtPeriodEnd | boolean | |
features | object | Plan feature key → included. |
usage | object | |
usage.ai_credits | object or null | |
usage.ai_credits.used | number | |
usage.ai_credits.limit | number or null | Null is unlimited. |
usage.ai_credits.credits | number | Purchased or granted on top of the plan's allowance. |
usage.ai_credits.remaining | number or null | Below zero: past the allowance (texts are then billed per segment). |
usage.ai_credits.overage | boolean | |
usage.sms | object or null | |
usage.sms.used | number | |
usage.sms.limit | number or null | Null is unlimited. |
usage.sms.credits | number | Purchased or granted on top of the plan's allowance. |
usage.sms.remaining | number or null | Below zero: past the allowance (texts are then billed per segment). |
usage.sms.overage | boolean | |
usage.emails | object or null | SKUFlow emails this period (allowance, used); null when the plan version predates the email allowance (then see emails below). |
usage.emails.used | number | |
usage.emails.limit | number or null | Null is unlimited. |
usage.emails.credits | number | Purchased or granted on top of the plan's allowance. |
usage.emails.remaining | number or null | Below zero: past the allowance (texts are then billed per segment). |
usage.emails.overage | boolean | |
usage.telephony_usage | object or null | Telephony billed this period, in cents (numbers, call minutes, recordings at Twilio's cost + 20%); null when not priced. |
usage.telephony_usage.used | number | |
usage.telephony_usage.limit | number or null | Null is unlimited. |
usage.telephony_usage.credits | number | Purchased or granted on top of the plan's allowance. |
usage.telephony_usage.remaining | number or null | Below zero: past the allowance (texts are then billed per segment). |
usage.telephony_usage.overage | boolean | |
usage.shipping_usage | object or null | Shipping labels bought on SKUFlow's carrier account this period, in cents (postage + markup); null when not priced. |
usage.shipping_usage.used | number | |
usage.shipping_usage.limit | number or null | Null is unlimited. |
usage.shipping_usage.credits | number | Purchased or granted on top of the plan's allowance. |
usage.shipping_usage.remaining | number or null | Below zero: past the allowance (texts are then billed per segment). |
usage.shipping_usage.overage | boolean | |
emails | object or null | SKUFlow email against the plan's allowance; null when it cannot be counted. |
emails.usedThisMonth | number | Emails sent through SKUFlow email this calendar month (UTC), counted here. |
emails.allowance | number or null | The plan's monthly email allowance (null: unknown plan). |
officeUsers | object | Team members (everyone who can sign in) against the plan's number. |
officeUsers.used | integer or null | Office members plus pending office invitations; null when it could not be counted. |
officeUsers.limit | integer or null | Null is unlimited. Every member counts. |
degraded | boolean | Billing could not be reached: this is the last known plan, or (planSource outage) none, and paid add-ons and new users are paused. |
planSource | enum | Where the plan came from: live (Base316), memory or stored (the last answer, Base316 unreachable), outage (nothing known), fake (development). One of live, memory, stored, outage, fake. |
tiers | array of object | Every plan, cheapest first, for comparison and upgrade prompts. |
tiers[].key | string | |
tiers[].name | string | |
tiers[].tagline | string | |
tiers[].monthlyPrice | number | |
tiers[].yearlyPrice | number | |
tiers[].features | array of string | |
tiers[].officeUsers | number or null | |
tiers[].aiCredits | number | |
tiers[].smsSegments | number | |
tiers[].emails | number | SKUFlow emails a month. |
trial | object | |
trial.tier | string | |
trial.days | number | |
addons | array of object | Paid add-ons sold on any plan, and whether this business has each one. |
addons[].key | string | Add-on key: phone or ads. |
addons[].feature | string | The plan feature it includes. |
addons[].name | string | |
addons[].description | string | |
addons[].monthlyPrice | number | USD per month on a monthly plan. |
addons[].yearlyPrice | number | USD per year on a yearly plan. |
addons[].includedInTrial | boolean | The free trial includes it, within the trial's telephony limits. |
addons[].requires | string or null | The add-on it needs first (phone). |
addons[].includedNumbers | integer | Local numbers it includes. |
addons[].draft | boolean | Not on sale yet: its price is not decided, and adding it is refused (409). |
addons[].attached | boolean | On this business's subscription now. |
addons[].terms | object | The fee and every usage rate today: shown and accepted before adding it. |
addons[].terms.key | string | |
addons[].terms.name | string | |
addons[].terms.monthlyPrice | number | USD per month on a monthly plan. |
addons[].terms.yearlyPrice | number | USD per year on a yearly plan. |
addons[].terms.includedNumbers | integer | Local numbers whose monthly charge is included. |
addons[].terms.requires | string or null | The add-on it needs (phone), or null. |
addons[].terms.markup | number | Usage is billed at cost × this (1.2 = cost + 20%). |
addons[].terms.rates | array of object | Every usage rate at the price the business pays. |
addons[].terms.example | object | |
addons[].terms.trial | object | What the free trial includes before the phone system pauses. |
addons[].terms.ratesSource | enum | Twilio's Pricing API today, or SKUFlow's documented fallback table. One of twilio, fallback. |
addons[].terms.priceVersion | string | Send this back in acknowledgement.priceVersion. |
addons[].acknowledgement | object or null | The last acceptance of its terms (who, when, which version), or null. |
addons[].acknowledgement.userId | string | |
addons[].acknowledgement.userName | string or null | |
addons[].acknowledgement.acceptedAt | string (date-time) | |
addons[].acknowledgement.priceVersion | string | |
addons[].acknowledgement.context | enum | One of ADD_ADDON, MANAGED_TELEPHONY, REVIEW. |
addons[].acknowledgement.terms | object or null | Exactly what was shown and accepted (“View terms”). |
addons[].needsReview | boolean | Attached, and its prices changed since they were accepted: an owner should review and accept them again (billing.acknowledgeTerms). Nothing is removed. |
billingInterval | enum or null | The subscription's interval: usage is billed in arrears at the end of each. One of month, year. |
List the plans to choose from
GET /organizations/{organizationId}/billing/plan-options
The SKUFlow plans a business can choose, cheapest first, as Base316 sells them: name, description, monthly and yearly price (integer cents), users included (null = unlimited), the features included, and the free-trial days on the trial plan. Also trial (the plan and days a new business starts on with no card) and whether this business still has to choose (needsChoice). Read-only; any member. Choose with POST /billing/choose-plan.
| Permission | organization.read (Owner, Admin, Staff, Member) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | billing_planOptions (toolset settings) |
Example
curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/billing/plan-options" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
plans | array of object | |
plans[].key | string | |
plans[].name | string | |
plans[].description | string or null | |
plans[].monthlyCents | integer or null | |
plans[].yearlyCents | integer or null | |
plans[].officeUsers | integer or null | |
plans[].features | array of string | |
plans[].trialDays | integer or null | |
trial | object | |
trial.tier | string | |
trial.days | integer | |
needsChoice | boolean |
Choose a plan (first run)
POST /organizations/{organizationId}/billing/choose-plan
Money: the owner's plan choice after sign-up. plan: "trial" keeps the free trial the business started on (no card, nothing billed) and returns url: null. A plan key (with interval month or year) returns a one-time Base316 checkout link for that plan, where the owner enters a card and pays; the trial ends once the paid plan starts. Either way the business no longer sees the plan screen. Owner only.
| Permission | organization.accessBillingPortal (Owner) |
| Risk | sensitive, OAuth scope skuflow.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access. |
| MCP tool | billing_choosePlan (toolset settings) |
| Approval | Waits for your approval in SKUFlow when called with an API key or a connected app: the first call answers 428 APPROVAL_REQUIRED; once you approve it, repeat the call with the X-SKUFlow-Approval header. See Approvals. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
plan | enum | Yes | "trial" to keep the free trial, or a plan key from GET /billing/plan-options. One of trial, core, connect, grow, pro. |
interval | enum | No | One of month, year. Default month. |
Example
curl -X POST "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/billing/choose-plan" \
-H "Authorization: Bearer $SKUFLOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"plan":"trial"}'Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
url | string or null | The Base316 checkout page to open; null when nothing is to be paid. |
List AI credit packs
GET /organizations/{organizationId}/billing/credit-packs
The AI credit packs on sale (credits, price), cheapest first. Buy one with billing.buyCredits. Read-only.
| Permission | organization.read (Owner, Admin, Staff, Member) |
| Risk | read, OAuth scope skuflow.read. Read: reads only. |
| MCP tool | billing_creditPacks (toolset settings) |
Example
curl "https://app.skuflow.ai/api/organizations/$ORGANIZATION_ID/billing/credit-packs" \
-H "Authorization: Bearer $SKUFLOW_API_KEY"Response
200: the answer's fields
| Field | Type | Description |
|---|---|---|
packs | array of object | |
packs[].key | string | |
packs[].name | string | |
packs[].credits | number | |
packs[].price | string | |
packs[].currency | string |