Skip to main content
POST
Create a price for a product

Authorizations

Authorization
string
header
required

Use a Bouclay secret key (sk_test_..., sk_live_...) or restricted key (rk_test_..., rk_live_...).

A secret key can call every endpoint. A restricted key can only call the endpoints its scopes cover. A scope is {resource}:{access}, for example customers:read or refunds:write, and write includes read. GET requests need read access and everything else needs write, except POST /subscriptions/{id}/items/{item}/preview, which only needs subscriptions:read. A request outside the key's scopes gets 403 permission_denied naming the missing scope, and its Idempotency-Key is not used up.

Publishable keys (pk_...) are rejected by server-side API endpoints. A key's mode scopes what it can see and charge: a test key can never reach a live card.

Headers

Idempotency-Key
string
required

Required for POST and PATCH requests. Replays identical method + path + body requests and rejects mismatched re-use.

Required string length: 1 - 255

Path Parameters

product
string
required

Body

application/json
type
enum<string>
required
Available options:
one_time,
recurring
pricingModel
enum<string>
required

Early access: graduated, volume and package are refused until tiered pricing is turned on for your account; standard always works.

graduated prices each slice of the quantity at its own tier's rate. volume prices every unit at the rate of the tier the whole quantity lands in, plus that tier's flat fee, so 12 seats on "1 to 10 at 5,000, 11 or more at 4,000" cost 12 × 4,000. volume is for fixed (licensed) prices only; a usage price uses graduated.

package is for usage prices only: usage is rounded up to whole packages of packageSize units, each charged unitAmount.

Available options:
standard,
graduated,
volume,
package
name
string | null
unitAmount
number | null

Major currency units. For example, 15000 means NGN 15,000.

Required range: x >= 0
usageType
enum<string>
default:licensed

Early access: metered is refused until metered billing is turned on for your account.

metered charges for what a meter measured over each period, billed at the end of it. It needs meterId, a recurring price, and billingTiming left out or arrears. The subscription item's quantity is always 1.

Available options:
licensed,
metered
meterId
string

The meter a metered price charges for (mtr_…). Early access, with metered.

packageSize
integer

Units per package, for package pricing.

Required range: x >= 1
unitDivisor
integer
default:1

"Per N units" pricing for a metered price: unitAmount and every tier's unitAmount are the price of this many units, so a unit can cost less than the currency's smallest unit. ₦4,500 per 1,000,000 tokens is unitAmount: 4500, unitDivisor: 1000000. A usage line bills usage × unitAmount ÷ unitDivisor, tier slices summed first, rounded half up to the minor unit once per line: 10 tokens bill ₦0.05, 2,345,678 tokens ₦10,555.55. Tier upTo bounds stay in units and a tier's flatAmount is never divided. Refused on a licensed price and with package pricing (a package rounds usage up to whole blocks). Frozen like the rest of the price.

Required range: 1 <= x <= 1000000000
minQuantity
integer

The fewest one purchase of this price can hold, for a licensed price ("Team: 5 seats or more"). Leave it out for no minimum. A subscription, item change or invoice line below it is refused. A payment link on a price with a range lets the buyer choose a quantity inside it (up to 1,000).

Required range: x >= 1
maxQuantity
integer

The most one purchase of this price can hold, for a licensed price. At least minQuantity.

Required range: x >= 1
creditAmount
number

A credit pack only: the credit it gives, when more than unitAmount ("pay ₦50,000, get ₦55,000"). The difference is a bonus, its own promotional lot.

setupFee
number

A recurring price only: a one-time fee (a gym's joining fee, a setup fee) billed once when a subscription starts on this price, on its first paid invoice: at once, or when a free trial ends. Never billed on a renewal, a plan change or a resume. Payment links show it separately and charge it with the first payment. Fixed once the price is in use, like unitAmount.

setupFeeName
string

The setup fee's line on the invoice, such as "Joining fee". Defaults to "Setup fee".

Maximum string length: 100
setupFeeAgainAfterMonths
integer | null

A returning customer pays the setup fee again only once this many months have passed since their last subscription to the product ended; back sooner, they rejoin without it. Leave it out to charge it on every new subscription. A subscription still live doesn't count: a second one pays it. A payment link's page shows the fee to everyone, and the checkout leaves it off for a returning buyer.

Required range: 1 <= x <= 120
tiers
object[]

Required for graduated and volume pricing. Included units are a first tier priced at 0, for example upTo: 10000, unitAmount: 0 then upTo: null, unitAmount: 3.

currency
string | null
Required string length: 3
billingInterval
enum<string> | null
Available options:
day,
week,
month,
year,
null
billingFrequency
integer
default:1
Required range: x >= 1
billingTiming
enum<string>
default:advance

Early access: arrears is refused until metered billing is turned on for your account.

When a recurring price is billed. advance charges at the start of each period. arrears charges once the period has ended, prorated to the time the subscription had it, so nothing is due at signup. Ignored for one-time prices. Fixed once the price is in use.

Available options:
advance,
arrears
planId
string

The plan a recurring price belongs to (plan_…), required for recurring prices on POST /products/{id}/prices. An inline price on POST /products takes planName instead and gets a plan created alongside.

chargeId
string

Which of the plan's charges the price is for (chg_…). Required when the plan has several; otherwise the price goes to its only charge. A charge's prices are all fixed, or all usage of one meter, and a meter is billed by one charge per plan.

planName
string

Inline price on POST /products only; the plan created for a recurring price. Defaults to the product name.

trialLength
integer

A free trial on this price. Recurring prices only.

Required range: x >= 1
trialUnit
enum<string>

Required with trialLength.

Available options:
day,
week,
month
trialRequiresPaymentInfo
boolean
default:false

The trial starts only once the customer saves a card (a small charge, refunded): the subscription waits incomplete until then. Without it, the trial starts at once with no card.

trialOncePerCustomer
boolean
default:true

Once per customer per plan, across all the plan's prices.

customData
object | null

Response

Price response.

data
object
required
meta
object
required