Skip to content

What a change of plan would do, and cost

POST
/orgs/{org}/billing/plan/preview
curl --request POST \
--url https://api.sloose.com/orgs/org_9f3c/billing/plan/preview \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "planKey": "example", "interval": "example", "previewToken": "example" }'

Works out a change of plan for an org with a Stripe subscription, without making it: whether it lands now or at the renewal, what it charges now and at the renewal — from Stripe’s own preview, tax included, never worked out here — what the org would hold past the new plan once it lands (connections; runs start again at the renewal), and how the history’s window moves, with the date a shorter one would start to apply (thirty days after the change).

Nothing is charged or changed. Administrators, through their own session.

org
required

The org id the session was issued for. A token for one org can never read another.

string
Example
org_9f3c

The org id the session was issued for. A token for one org can never read another.

Media typeapplication/json
object
planKey

The plan to move to: team, business or enterprise, or free for a cancellation at the period’s end.

string
interval

month or year, for a paid plan. Defaults to month.

string
previewToken

The token of the preview the person confirmed (#1482 review): the change is held to the terms it priced — the subscription as read, the change, and the moment its proration was priced at — and refused PREVIEW_STALE when they no longer hold. Without one, the change is priced as it is made.

key
additional properties
Examplegenerated
{
"planKey": "example",
"interval": "example",
"previewToken": "example"
}

What the change would do.

Media typeapplication/json
object
change
required

now: a higher plan (or a year in place of a month), charged now with proration. at_renewal: a lower plan (or a month in place of a year), from the period’s end, which can be taken back until then. cancel: Free, the subscription ending at the period’s end.

string
Allowed values: now at_renewal cancel
plan
required
object
key
required
string
name
required
string
from
required

The plan the change is measured from, as it stands now — what the confirm names, never what a page read earlier.

object
key
required
string
name
required
string
interval
required
string | null
Allowed values: month year
effectiveAt
required

Now, or the period’s end.

string
amountDue
required

Charged now, in the currency’s smallest unit, tax included: an upgrade’s prorated invoice. Null for a change at the renewal.

number | null
renewalAmount
required

The first renewal on the new plan, tax included. Null for Free.

number | null
renewsAt
required

When that renewal is. For a change made now, from Stripe’s preview, since a change of interval moves it; for a move at the renewal, the period’s end, where the schedule’s next phase starts. Null for Free.

string | null
currency
required
string | null
over
required

What the org would hold past the new plan when it lands: allowed, and said, as the banner says it after (#330).

Array<object>
object
limit
required
string
Allowed values: connections runs
used
required
number
max
required
number
historyDays
required
object
from
required
number
to
required
number
historyHeldUntil
required

When the new window is shorter: the date until which the history is held after the change lands. Null otherwise.

string | null
token
required

These terms, signed for half an hour: send it as the change’s previewToken, and the change is made on them or refused PREVIEW_STALE.

string
Example
{
"change": "now",
"interval": "month",
"over": [
{
"limit": "connections"
}
]
}

The plan key is not one we sell, or the interval is neither month nor year.

Media typeapplication/json
object
error
required
string
key
additional properties
Examplegenerated
{
"error": "example"
}

No bearer, or one that is expired, revoked or no longer resolves to a member.

Media typeapplication/json

The error envelope every non-2xx answer uses.

object
error
required

Human-readable explanation.

string
code

Machine-readable reason. Absent on a few legacy 400s.

string
key
additional properties
Examplegenerated
{
"error": "example",
"code": "example"
}

The bearer’s role is too low, it was issued for a different org, or it is an API token (SESSION_REQUIRED).

Media typeapplication/json

The error envelope every non-2xx answer uses.

object
error
required

Human-readable explanation.

string
code

Machine-readable reason. Absent on a few legacy 400s.

string
key
additional properties
Examplegenerated
{
"error": "example",
"code": "example"
}

NOT_SUBSCRIBED: no Stripe subscription to change, so Checkout starts one. INVOICE_BILLED: a plan billed by invoice is changed by Sloose’s team. NO_CHANGE: the org is on that plan and interval already, or Free is already set for the period’s end. NOT_CHANGEABLE: the subscription is not active — a payment owed, or ended. PLAN_SETTLING: the last change, a renewal, or a change made at Stripe is still reaching the org — what Stripe bills and what Sloose has recorded differ — so nothing is decided until they agree; try again in a minute. error says which, in words to show.

Media typeapplication/json
object
error
required
string
code
required
string
Allowed values: NOT_SUBSCRIBED INVOICE_BILLED NO_CHANGE NOT_CHANGEABLE PLAN_SETTLING
key
additional properties
Example
{
"code": "NOT_SUBSCRIBED"
}

Stripe refused the request (PAYMENT_PROVIDER_REFUSED) — nothing was charged, though a step taken before the refusal stands: the org’s first Stripe customer, or an existing customer’s billing email brought up to date — or was unavailable (PAYMENT_PROVIDER_UNAVAILABLE: unreachable, failing or rate-limiting), which may or may not have gone through — check before retrying. Stripe’s own words are logged, not returned.

Media typeapplication/json
object
error
required
string
code
required
string
Allowed values: PAYMENT_PROVIDER_REFUSED PAYMENT_PROVIDER_UNAVAILABLE
key
additional properties
Example
{
"code": "PAYMENT_PROVIDER_REFUSED"
}

Stripe, or the plan’s price, is not configured.

Media typeapplication/json
object
error
required
string
key
additional properties
Examplegenerated
{
"error": "example"
}

Report a problem with this page