Search docs ⌘K
esc
Type to search across all documentation pages

Billing & Tokens

Manage subscriptions and billing for organizations. SaaSignal uses Stripe for payment processing.

List Plans

GET
/core/billing/packages
none (public)

List available subscription packages.

curl
curl https://api.saasignal.saastemly.com/core/billing/packages \
  -H "Authorization: Bearer sk_live_..."
json — 200 OK
[
  { "id": "free", "name": "Free", "price_monthly": 0, "tokens_monthly": 0.5, "rate_limit_rps": 10 },
  { "id": "pro", "name": "Pro", "price_monthly": 49, "tokens_monthly": 12, "rate_limit_rps": 500 }
]
typescript
const plans = await ss.core.billing.packages()
  1. Open Dashboard → select your organization
  2. Go to Billing to see all available plans and their features
Error responses
401 Unauthorized

Get Subscription

GET
/core/billing/{org_id}/subscription
billing:read

Get the active subscription for an organization.

curl
curl https://api.saasignal.saastemly.com/core/billing/{org_id}/subscription \
  -H "Authorization: Bearer sk_live_..."
json — 200 OK
{
  "id": "sub_01JNXS...",
  "packageId": "pro",
  "status": "active",
  "currentPeriodEnd": "2026-04-01T00:00:00Z",
  "cancelAtPeriodEnd": false
}
typescript
const sub = await ss.core.billing.subscription('org_01JNXS...')
  1. Open Dashboard → select your organization
  2. Go to Billing to see your current plan, status, and renewal date
Path param
Type
Description
org_id required
string
Organization ID
Error responses
401 Unauthorized
404 Not found

Create Subscription

POST
/core/billing/subscription
session auth
typescript
await ss.core.billing.subscribe({
  org_id: 'org_01JNXS...',
  package_id: 'pro',
})
  1. Open Dashboard → select your organization
  2. Go to Billing → click Upgrade
  3. Select a plan and complete payment
Body field
Type
Description
org_id required
string
Organization ID
package_id required
string
Plan ID: free, indie, pro, or scale
payment_method_id
string
Stripe payment method ID (if not already on file)
Error responses
400 Invalid body (validation error)
401 Unauthorized
403 Forbidden

Cancel Subscription

DELETE
/core/billing/subscription
session auth
typescript
await ss.core.billing.cancel('org_01JNXS...')
  1. Open Dashboard → select your organization
  2. Go to Billing → click Cancel Plan
  3. Your plan stays active until the end of the billing period
Query param
Type
Description
org_id required
string
Organization ID
Error responses
401 Unauthorized
403 Forbidden
404 No active subscription

Switch to Free Plan

POST
/core/billing/{org_id}/free-plan
billing:write

Switch an organization to the free plan without checkout. This powers dashboard flows that only need the local state change and do not require a live Stripe completion.

curl
curl -X POST https://api.saasignal.saastemly.com/core/billing/{org_id}/free-plan \
  -H "Authorization: Bearer sk_live_..."
json — 200 OK
{
  "id": "sub_01JNXS...",
  "packageId": "free",
  "status": "active",
  "currentPeriodEnd": null,
  "cancelAtPeriodEnd": false
}
typescript
const sub = await ss.core.billing.switchToFreePlan('org_01JNXS...')
  1. Open Dashboard → select your organization
  2. Go to Billing → choose the Free plan card
  3. Click Downgrade to switch immediately without Stripe checkout
Path param
Type
Description
org_id required
string
Organization ID
Error responses
401 Unauthorized
404 Not found

Billing Portal

POST
/core/billing/portal
session auth
typescript
const { url } = await ss.core.billing.portal({
  org_id: 'org_01JNXS...',
  return_url: 'https://app.acme.com/settings/billing',
})
window.location.href = url
  1. Open Dashboard → select your organization
  2. Go to Billing → click Manage Payment Methods
  3. You'll be redirected to Stripe's billing portal
Body field
Type
Description
org_id required
string
Organization ID
return_url required
string (URL)
URL to redirect back to after the portal session
Error responses
401 Unauthorized
403 Forbidden

Tokens

Purchase top-up bundles, check balances, and query usage analytics. Token balances are managed at the organization level.

List Top-up Bundles

GET
/core/tokens/topup-bundles
none (public)

List available top-up token bundles.

curl
curl https://api.saasignal.saastemly.com/core/tokens/topup-bundles \
  -H "Authorization: Bearer sk_live_..."
json — 200 OK
[
  { "id": "topup_5", "tokens": 5, "price": 32 },
  { "id": "topup_15", "tokens": 15, "price": 84 },
  { "id": "topup_50", "tokens": 50, "price": 240 }
]
typescript
const bundles = await ss.core.billing.topupBundles()
  1. Open Dashboard → select your organization
  2. Go to BillingTop-up Tokens to see available bundles
Error responses
401 Unauthorized

Get Token Balance

GET
/core/tokens/balance
billing:read

Get the current included and top-up token balances for an organization.

curl
curl https://api.saasignal.saastemly.com/core/tokens/balance \
  -H "Authorization: Bearer sk_live_..."
json — 200 OK
{
  "included_remaining": 3.42,
  "topup_balance": 1.40,
  "total": 4.82
}
typescript
const balance = await ss.core.billing.tokenBalance('org_01JNXS...')
// balance.total, balance.included_remaining, balance.topup_balance
  1. Open Dashboard → select your organization
  2. Your token balance is shown at the top of the Billing page
Query param
Type
Description
org_id required
string
Organization ID
Error responses
400 Bad request
401 Unauthorized

Purchase Tokens

POST
/core/tokens/topup-bundles/purchase
session auth
typescript
const result = await ss.core.billing.purchaseTopup({
  org_id: 'org_01JNXS...',
  bundle_id: 'topup_5',
})
// result.tokens_added, result.new_balance
  1. Open Dashboard → select your organization
  2. Go to BillingTop-up Tokens
  3. Select a bundle and click Purchase
Body field
Type
Description
org_id required
string
Organization ID
bundle_id required
string
Bundle ID from /core/tokens/topup-bundles
Error responses
400 Invalid bundle ID
401 Unauthorized
403 Forbidden

Usage Analytics

GET
/core/billing/{org_id}/usage
billing:read

Get usage dashboard data for an organization.

curl
curl https://api.saasignal.saastemly.com/core/billing/{org_id}/usage \
  -H "Authorization: Bearer sk_live_..."
json — 200 OK
{
  "granularity": "day",
  "series": [
    {
      "period_start": "2026-03-01T00:00:00Z",
      "total": 0.14,
      "by_primitive": { "kv": 0.085, "channels": 0.0325, "jobs": 0.025 }
    }
  ]
}
typescript
const usage = await ss.core.billing.usage({
  org_id: 'org_01JNXS...',
  from: '2026-03-01',
  to: '2026-03-05',
  granularity: 'day',
})
  1. Open Dashboard → select your organization
  2. Go to BillingUsage
  3. View usage charts broken down by primitive (KV, Channels, Jobs)
Path param
Type
Description
org_id required
string
Organization ID
Error responses
401 Unauthorized
404 Not found

Token Usage

GET
/core/tokens/usage
billing:read

Get time-series token usage analytics with configurable granularity (hour, day, or month).

curl
curl https://api.saasignal.saastemly.com/core/tokens/usage \
  -H "Authorization: Bearer sk_live_..."
json — 200 OK
{ "status": "ok" }
typescript
const usage = await ss.core.billing.tokenUsage('org_01JNXS...')
  1. Open Dashboard → select your organization
  2. Go to BillingUsage
Query param
Type
Description
org_id required
string
Organization ID
from
string
Start date (ISO 8601 format, e.g. 2026-03-01)
to
string
End date (ISO 8601 format, e.g. 2026-03-05)
granularity
string
Aggregation interval: hour, day, or month. Default day.
Error responses
401 Unauthorized
403 Forbidden