A payment link is a page the store shares to sell the same Prices many times. Create one with line items that name the store's own Prices, send the buyer to its url, and switch it off with active=false. Each completed payment goes through a Checkout Session; payment_link.created and payment_link.updated tell the store's endpoints about the link itself.
Send every request to https://api.fluveo.com/v1 with your secret key as a Bearer token. This page lists only what Fluveo serves; the OpenAPI file holds the same operations.
An operation or a parameter marked Preview works, but it is not locked yet and may change: what Preview means.
Creates a payment linkPreview#
POST/v1/payment_linksrak_payment_links_write
Preview: this operation works, but it is not locked yet; it may change.
Send a unique key, 1 to 255 characters, on every POST. A retry with the same key and the same body returns the first answer instead of acting twice (with Idempotent-Replayed: true); the same key with another body is refused. Keys are kept 7 days, except on POST /v1/checkout/sessions, POST /v1/checkout/sessions/{session} and POST /v1/webhook_endpoints, where a key holds 24 hours; webhook endpoint keys are also capped at the newest 32 per store and mode. Do not rely on a replay after that window. GET and DELETE ignore it.
Optional. The only version Fluveo serves is 2026-05-27.dahlia; any other value is refused with a 400. Every answer names that version in its own Fluveo-Version header, except the refusals Fluveo gives before it reads the request (no key, an unknown key, an unknown URL, a body that is not a form) and a file's bytes, which name no version and no Request-Id.
One of:
2026-05-27.dahlia.
What the buyer sees after paying: type=hosted_confirmation with an optional hosted_confirmation[custom_message], or type=redirect with redirect[url].
automatic_tax[enabled]: only false is taken; Fluveo has no tax engine, so true answers automatic_tax_unavailable.
auto (the default) or required: whether the page always asks the buyer for the whole address.
One of:
auto,required.The message the link's page shows once the link is inactive, up to 500 characters.
What the link sells, at most 20 lines, all in the store's currency. Each line takes quantity and either price, the id of one of the store's active one-time Prices, or price_data (currency, unit_amount, product_data[name]), from which Fluveo first creates the Price. A line may also take adjustable_quantity (enabled, and an optional minimum from 0 and maximum from 1 to 999999, 99 when unset; the minimum below the maximum and the line's quantity within them): the link's page then lets the buyer pick that line's quantity within them, and the session charges the unit amount times the chosen quantity. A Price whose amount the customer chooses (custom_unit_amount) must be the only line, with quantity 1 and no adjustable quantity.
managed_payments[enabled]: only false is taken; true answers managed_payments_unavailable. Set on create only.
Up to 50 key-value pairs of your own, sent as metadata[key]=value: keys of 1 to 40 characters, values up to 500. Keys starting with fluveo_ are reserved. On an update, an empty value removes a key.
name_collection[individual] and name_collection[business], each with enabled and optional: whether the page asks for the buyer's or the business's name.
The methods the link's page offers: any of card, pix and boleto the store takes. Without it the link offers the default methods of a Checkout Session created without payment_method_types.
One of:
card,pix,boleto.phone_number_collection[enabled]: whether the page asks for the buyer's phone number.
restrictions[completed_sessions][limit]: how many payments the link takes before it turns inactive on its own.
shipping_address_collection[allowed_countries][]: the two-letter countries the page takes a shipping address in. The link's sessions ask a name and address, on card and on Pix and Boleto alike.
The word on the page's pay button: auto, book, donate or pay.
One of:
auto,book,donate,pay,subscribe.
Use only the documented body parameters. Send a new Idempotency-Key with each new request, and the same key again only to retry that request.
Returns a payment_link object.
curl https://api.fluveo.com/v1/payment_links \
-H "Authorization: Bearer sk_test_..." \
-H "Idempotency-Key: $(uuidgen)" \
--data-urlencode "line_items[0][price]=price_1QxExample000000000000" \
--data-urlencode "line_items[0][quantity]=1"const response = await fetch("https://api.fluveo.com/v1/payment_links", {
method: "POST",
headers: {
"Authorization": "Bearer sk_test_...",
"Idempotency-Key": crypto.randomUUID(),
},
body: new URLSearchParams([["line_items[0][price]","price_1QxExample000000000000"],["line_items[0][quantity]","1"]]),
});
console.log(await response.json());import uuid
import requests
response = requests.post(
"https://api.fluveo.com/v1/payment_links",
headers={"Authorization": "Bearer sk_test_...", "Idempotency-Key": str(uuid.uuid4())},
data=[("line_items[0][price]", "price_1QxExample000000000000"), ("line_items[0][quantity]", "1")],
)
print(response.json())<?php
$ch = curl_init("https://api.fluveo.com/v1/payment_links");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer sk_test_...",
"Idempotency-Key: " . bin2hex(random_bytes(16)),
],
CURLOPT_POSTFIELDS => "line_items%5B0%5D%5Bprice%5D=price_1QxExample000000000000&line_items%5B0%5D%5Bquantity%5D=1",
]);
echo curl_exec($ch);Lists payment link objects, newest firstPreview#
GET/v1/payment_linksrak_payment_links_read
Preview: this operation works, but it is not locked yet; it may change.
true lists only the links buyers can pay through now, false only the inactive ones.
Cursor: the id of the first object of the current page, to get the previous page. Do not send it with starting_after.
How many objects to return, from 1 to 100. Default 10.
Cursor: the id of the last object of the previous page, to get the next page. Do not send it with ending_before.
Optional. The only version Fluveo serves is 2026-05-27.dahlia; any other value is refused with a 400. Every answer names that version in its own Fluveo-Version header, except the refusals Fluveo gives before it reads the request (no key, an unknown key, an unknown URL, a body that is not a form) and a file's bytes, which name no version and no Request-Id.
One of:
2026-05-27.dahlia.
Returns a list of payment_link objects.
curl -G https://api.fluveo.com/v1/payment_links \
-H "Authorization: Bearer sk_test_..." \
--data-urlencode "active=true"const response = await fetch("https://api.fluveo.com/v1/payment_links" + "?" + new URLSearchParams([["active","true"]]), {
method: "GET",
headers: {
"Authorization": "Bearer sk_test_...",
},
});
console.log(await response.json());import requests
response = requests.get(
"https://api.fluveo.com/v1/payment_links",
headers={"Authorization": "Bearer sk_test_..."},
params=[("active", "true")],
)
print(response.json())<?php
$ch = curl_init("https://api.fluveo.com/v1/payment_links?active=true");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer sk_test_...",
],
]);
echo curl_exec($ch);Updates a payment linkPreview#
POST/v1/payment_links/{payment_link}rak_payment_links_write
Preview: this operation works, but it is not locked yet; it may change.
active=false switches the link off and active=true on again. A link switched off, or at its payment limit, takes any change, line item quantities by their id included, and stays off until active=true; a link at its limit switches on only with a limit above its count. An expired link takes no change but active.
The id of the payment link.
Send a unique key, 1 to 255 characters, on every POST. A retry with the same key and the same body returns the first answer instead of acting twice (with Idempotent-Replayed: true); the same key with another body is refused. Keys are kept 7 days, except on POST /v1/checkout/sessions, POST /v1/checkout/sessions/{session} and POST /v1/webhook_endpoints, where a key holds 24 hours; webhook endpoint keys are also capped at the newest 32 per store and mode. Do not rely on a replay after that window. GET and DELETE ignore it.
Optional. The only version Fluveo serves is 2026-05-27.dahlia; any other value is refused with a 400. Every answer names that version in its own Fluveo-Version header, except the refusals Fluveo gives before it reads the request (no key, an unknown key, an unknown URL, a body that is not a form) and a file's bytes, which name no version and no Request-Id.
One of:
2026-05-27.dahlia.
true or false: whether buyers can still pay through the link.
What the buyer sees after paying, as on create.
automatic_tax[enabled]: only false is taken.
auto or required.
One of:
auto,required.The message the page shows while the link is inactive; an empty value removes it.
Changes to the link's lines, each by its id (li_...) with a new quantity or adjustable_quantity (as on create); lines are not added or removed here.
Up to 50 key-value pairs of your own, sent as metadata[key]=value: keys of 1 to 40 characters, values up to 500. Keys starting with fluveo_ are reserved. On an update, an empty value removes a key.
name_collection[individual] and name_collection[business], each with enabled and optional; an empty name_collection removes both.
The methods the link's page offers, by the same rule as on create; an empty payment_method_types removes them, so the link offers the default methods.
One of:
card,pix,boleto.phone_number_collection[enabled]: whether the page asks for the buyer's phone number.
restrictions[completed_sessions][limit]: a new limit of payments. A raised limit keeps counting every payment so far; a limit set where there was none, or lowered, counts payments from this update. A link at its limit stays inactive until active=true is sent with a limit above its count.
shipping_address_collection[allowed_countries][]: the countries the page takes a shipping address in; an empty shipping_address_collection stops asking it.
The word on the page's pay button: auto, book, donate or pay.
One of:
auto,book,donate,pay,subscribe.
Use only the documented body parameters. Send a new Idempotency-Key with each new request, and the same key again only to retry that request.
Returns a payment_link object.
curl https://api.fluveo.com/v1/payment_links/plink_123 \
-H "Authorization: Bearer sk_test_..." \
-H "Idempotency-Key: $(uuidgen)" \
--data-urlencode "active=false"const response = await fetch("https://api.fluveo.com/v1/payment_links/plink_123", {
method: "POST",
headers: {
"Authorization": "Bearer sk_test_...",
"Idempotency-Key": crypto.randomUUID(),
},
body: new URLSearchParams([["active","false"]]),
});
console.log(await response.json());import uuid
import requests
response = requests.post(
"https://api.fluveo.com/v1/payment_links/plink_123",
headers={"Authorization": "Bearer sk_test_...", "Idempotency-Key": str(uuid.uuid4())},
data=[("active", "false")],
)
print(response.json())<?php
$ch = curl_init("https://api.fluveo.com/v1/payment_links/plink_123");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer sk_test_...",
"Idempotency-Key: " . bin2hex(random_bytes(16)),
],
CURLOPT_POSTFIELDS => "active=false",
]);
echo curl_exec($ch);Retrieves a payment linkPreview#
GET/v1/payment_links/{payment_link}rak_payment_links_read
Preview: this operation works, but it is not locked yet; it may change.
The id of the payment link.
Optional. The only version Fluveo serves is 2026-05-27.dahlia; any other value is refused with a 400. Every answer names that version in its own Fluveo-Version header, except the refusals Fluveo gives before it reads the request (no key, an unknown key, an unknown URL, a body that is not a form) and a file's bytes, which name no version and no Request-Id.
One of:
2026-05-27.dahlia.
Returns a payment_link object.
curl https://api.fluveo.com/v1/payment_links/plink_123 \
-H "Authorization: Bearer sk_test_..."const response = await fetch("https://api.fluveo.com/v1/payment_links/plink_123", {
method: "GET",
headers: {
"Authorization": "Bearer sk_test_...",
},
});
console.log(await response.json());import requests
response = requests.get(
"https://api.fluveo.com/v1/payment_links/plink_123",
headers={"Authorization": "Bearer sk_test_..."},
)
print(response.json())<?php
$ch = curl_init("https://api.fluveo.com/v1/payment_links/plink_123");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer sk_test_...",
],
]);
echo curl_exec($ch);Lists line item objects of the parent objectPreview#
GET/v1/payment_links/{payment_link}/line_itemsrak_payment_links_read
Preview: this operation works, but it is not locked yet; it may change.
The id of the line item.
Cursor: the id of the first object of the current page, to get the previous page. Do not send it with starting_after.
How many objects to return, from 1 to 100. Default 10.
Cursor: the id of the last object of the previous page, to get the next page. Do not send it with ending_before.
Optional. The only version Fluveo serves is 2026-05-27.dahlia; any other value is refused with a 400. Every answer names that version in its own Fluveo-Version header, except the refusals Fluveo gives before it reads the request (no key, an unknown key, an unknown URL, a body that is not a form) and a file's bytes, which name no version and no Request-Id.
One of:
2026-05-27.dahlia.
Returns a list of item objects.
curl https://api.fluveo.com/v1/payment_links/plink_123/line_items \
-H "Authorization: Bearer sk_test_..."const response = await fetch("https://api.fluveo.com/v1/payment_links/plink_123/line_items", {
method: "GET",
headers: {
"Authorization": "Bearer sk_test_...",
},
});
console.log(await response.json());import requests
response = requests.get(
"https://api.fluveo.com/v1/payment_links/plink_123/line_items",
headers={"Authorization": "Bearer sk_test_..."},
)
print(response.json())<?php
$ch = curl_init("https://api.fluveo.com/v1/payment_links/plink_123/line_items");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer sk_test_...",
],
]);
echo curl_exec($ch);The payment_link object#
Ids start with plink_.
activebooleanafter_completionobjectautomatic_taxobjectOne of:
auto,required.currencystringcustom_fieldsarraycustom_textobjectOne of:
always,if_required.idstringline_itemsobjectlivemodebooleanmetadataobjectname_collectionobjectobjectenumOne of:
payment_link.An id by default; send
expand[]=on_behalf_ofto get the full account object.One of:
always,if_required.phone_number_collectionobjectshipping_optionsarraysubmit_typeenumOne of:
auto,book,donate,pay,subscribe.tax_id_collectionobjecturlstring
The item object#
amount_subtotalintegeramount_taxintegeramount_totalintegercurrencystringidstringobjectenumOne of:
item.taxesarray