Skip to main content
POST
Error

Authorizations

Authorization
string
header
required

A staff session token, uk_st_…. Minted by sign-up, sign-in or the two-factor exchange. Only a 401 means it is spent; not_a_member (403) is about the organization named in X-Organization-Id and leaves the token good for the others.

Headers

X-Organization-Id
string

The organization the caller is acting on — the org_… code that appears in the panel URL. It identifies; the membership JOIN is what authorizes, so a forged code reads nothing: the answer is not_a_member (403), which does not mean the session is over. Absent, the session's default organization answers, or — if that membership was revoked while the session was open — any other one the caller still holds.

Path Parameters

id
string<uuid>
required

The plan this price belongs to.

Query Parameters

environment
enum<string>
default:live

Which environment to act in. A view parameter, valid only on the staff surface — a machine credential never chooses its environment, it is resolved from the key.

Available options:
live,
test

Body

application/json

A price on the way in — what both creating and repricing send. Every field is stated: there is no PATCH on a price, so no request carrying this is editing one, and "leave that field as it was" has no meaning here.

kind
enum<string>
required
Available options:
recurring,
one_time
currency
string
required

ISO 4217, uppercase. Required — an amount with no currency is not a price, and 1000 is R$10.00 in BRL and ¥1000 in JPY.

Example:

"BRL"

amount_minor
integer<int64>
required

An integer in the currency's minor unit: 14900 is R$149.00. Never a decimal, and never divided by 100 on the way in — the currency's exponent is 0 for JPY and CLP and 3 for KWD.

Required range: x >= 0
tax_behavior
enum<string>
required

Whether amount_minor already contains the tax. Required, with no third "undecided" value: we calculate no tax — that is the payment provider's job — but whether the number includes it is an input only the person who typed the number knows, and the moment it matters is the moment somebody is charged.

Available options:
inclusive,
exclusive
interval_unit
enum<string>

Required on a recurring price and refused on a one_time one, rather than ignored: a lifetime deal carrying a monthly interval is how it ends up in a renewal job's query.

Available options:
day,
week,
month,
year
interval_count
integer

How many intervals between charges. Required on recurring, refused on one_time.

Required range: x >= 1
trial_days
integer

The free period this offer promises before the first charge, in days. Part of the offer — checkouts started on this price carry it by default — and therefore as immutable as the amount: changing the trial is a reprice. Omit (or send 0) for no trial. Refused on a one_time price rather than ignored: a payment has no trial.

Required range: x >= 1
per_seat
boolean
default:false

The quantity of this price follows the customer's own member count: a checkout on it derives the quantity from the roster and refuses one in the request, and the count is kept in step at the gateway as members join and leave. Part of the offer and as immutable as the amount — changing it is a reprice. Refused on a one_time price rather than ignored: a payment has no period over which a head count could be re-billed.

Response

The price. providers is empty until the price is mapped onto a payment provider — until then nothing can charge it.

One plan's amount in one currency. A plan has many prices, one per currency: selling in BRL and USD is a price per currency, a number you chose, never a conversion at display time.

A price is immutable. Repricing means creating a new price and archiving the old one, because a subscription refers to the price it was sold at and editing the amount would silently change what somebody agreed to pay.

id
string<uuid>
kind
enum<string>

one_time is a lifetime deal or a one-off purchase and carries no interval; recurring always carries one.

Available options:
recurring,
one_time
currency
string

ISO 4217, uppercase. Never absent — an amount with no currency is not a price.

Example:

"BRL"

amount_minor
integer<int64>

The amount as an integer in the currency's minor unit. 14900 is R$149.00; in a zero-decimal currency the same integer is 14,900 whole units.

currency_exponent
integer | null

How many decimal places the currency has, so amount_minor can be rendered without hard-coding a divisor: 2 for BRL and USD, 0 for JPY and CLP, 3 for KWD. null only if the stored code is one this API no longer prices in.

interval_unit
enum<string> | null

null on a one_time price.

Available options:
day,
week,
month,
year,
null
interval_count
integer | null

How many intervals between charges. null on a one_time price — never 0.

trial_days
integer | null

The free period this offer promises before the first charge, in days. null is no trial — never 0, so a screen never decides what a zero-day trial means. Checkouts started on this price carry it by default.

per_seat
boolean

The quantity of this price follows the customer's own member count — derived at checkout and kept in step automatically as members join and leave. Part of the offer, so it is as immutable as the amount.

tax_behavior
enum<string>

Whether amount_minor already contains tax. There is no third “undecided” value: the calculation belongs to the payment provider, but this input is yours and is answered when the price is created.

Available options:
inclusive,
exclusive
archived
boolean

No longer sold. Existing subscriptions keep it.

providers
object[]

How this price is known at each payment provider. Empty means nothing can charge it yet. A price may be mapped onto more than one provider, and onto more than one account of the same provider.

created_at
string<date-time>