A Price says how much a Product costs. A Product can have many Prices, for example one per currency. A Price never changes its amount or currency: to charge something else, add another Price and archive this one.
The API serves create, retrieve, update, list and search. A Price has no delete: you archive it. The full list of parameters is in the Prices API reference.
Amounts#
A Price is paid once, so its type is one_time. unit_amount is a whole number of the currency's smallest unit, so 4900 with usd means $49.00. When a Price
must hold part of that unit, such as a tenth of a cent, send it as a decimal string in unit_amount_decimal instead,
with no more than 12 digits after the point.
curl https://api.fluveo.com/v1/prices \
-H "Authorization: Bearer sk_test_..." \
-H "Idempotency-Key: 9b3e51a0-pro-tee" \
-d product=prod_... \
-d currency=usd \
-d unit_amount=2900 \
-d lookup_key=pro_teeconst response = await fetch("https://api.fluveo.com/v1/prices", {
method: "POST",
headers: { Authorization: "Bearer sk_test_...", "Idempotency-Key": "9b3e51a0-pro-tee" },
body: new URLSearchParams({
product: "prod_...",
currency: "usd",
unit_amount: "2900",
lookup_key: "pro_tee",
}),
});
const price = await response.json();Name the Product with product, or create one in the same request with product_data[name]; send exactly one of
the two. An archived Product still takes new Prices. To create a Product and its first Price together, see
Create a product with its first price.
Other options:
nickname: free text, up to 5,000 characters, to tell your Prices apart. The dashboard calls it the price description.custom_unit_amount[enabled]=true: the buyer chooses the amount, with an optionalminimum,maximumandpreset, in the smallest currency unit.minimumis at least 50 and belowmaximum;maximumis at most 1,000,000, or 4,000,000 inbrl;presetis between them. Never together withunit_amount.transform_quantity:divide_byandround(upordown), both required.tax_behavior:inclusivewhen the amount already holds the tax,exclusivewhen tax goes on top, andunspecifieduntil you decide. You can set it later on anunspecifiedPrice, and from then on it stays.metadata(see Metadata).
Fluveo refuses what it does not support, each by name and never silently: tiered prices and currency_options
(a Price has one currency; create one Price per currency).
Lookup keys#
Store a short name such as pro_tee in lookup_key (200 characters at most), and your code can ask for the
Price by that name rather than keep its price_... id. A key sits on one Price at a time in your store and mode. If
another Price already has it, the request is refused and the error says which Price that is. Add
transfer_lookup_key=true and the request takes the key over instead: the former holder drops it in the same write
and sends a price.updated of its own.
Raising the Pro T-shirt from $29.00 to $32.00 takes three calls:
- Create the
3200Price withlookup_key=pro_teeandtransfer_lookup_key=true. - If the old Price was the Product's default, point
default_priceat the new one. - Archive the old Price with
active=false.
From the first call on, a read of pro_tee answers the new amount.
curl -G https://api.fluveo.com/v1/prices \
-H "Authorization: Bearer sk_test_..." \
-d "lookup_keys[]=pro_tee"const query = new URLSearchParams({ "lookup_keys[]": "pro_tee" });
const response = await fetch("https://api.fluveo.com/v1/prices?" + query, {
headers: { Authorization: "Bearer sk_test_..." },
});
const { data } = await response.json();Update and archive#
POST /v1/prices/{id} takes active, nickname, lookup_key, transfer_lookup_key, tax_behavior and
metadata. unit_amount, currency and product are refused. An empty nickname= or
lookup_key= sets it to null.
active=false archives a Price. It stays readable and active=true brings it back. The Product's default Price
can't be archived: first make another Price the default with default_price on the
Product update.
List prices#
GET /v1/prices returns your store's Prices, newest first, paged with limit (1 to 100, default 10),
starting_after and ending_before (see Pagination). Filter with active, currency,
product, type, lookup_keys[] (at most 10) and created.
expand[]=data.product returns each Price with its Product.
Search prices#
GET /v1/prices/search works like Product search. The fields are active,
currency, lookup_key, metadata, product and type. created is not a
search field.
| Query | Finds |
|---|---|
product:"prod_..." AND active:"true" | the active Prices of one Product |
currency:"brl" AND active:"true" | active Prices in reais |
lookup_key:"pro_tee" | the Price that holds this key |
metadata["line"]:"pro" | Prices whose line metadata is pro |
Events#
A create sends price.created, and an update price.updated with previous_attributes. A Price
is never deleted, so no price.deleted is sent. See Event types.