UCP FAQ
Answers to merchants' and developers' questions — from payments and testing to several shops and languages.
On this page
Short answers, each with a pointer to the chapter that has the detail. The
examples use the shop https://shop.example.com.
Payments and orders
Can an agent pay for the buyer through UCP?
No. The shop's profile and every checkout carry payment_handlers: {}.
POST …/complete places no order and changes nothing: it answers what a
read of the checkout answers, and any payment data in its body is
ignored. A ready checkout has the status requires_escalation with the
message payment_required and a continue_url; the buyer opens that
link and pays on the shop's website,
with the shop's own payment methods. See
Concepts and lifecycle and
UCP conformance.
How do I learn that the buyer ordered? Is there a webhook?
There are no webhooks. Read the checkout with
GET /ucp/v1/checkout-sessions/{id} until status is completed (with
order.id, order.label — the shop's order number, when the order has
one — and order.permalink_url, the shop's order confirmation page,
which opens without a sign-in) or canceled.
Only a checkout is ever completed, never a cart: convert the cart
first and hand over the checkout. completed means the order was
placed, not that it was paid; the checkout's lines and totals stay
your last quote, and the buyer may have changed the order on the shop.
Keep one request per session in flight: a checkout read takes the
session's lock and can answer 503 with Retry-After: 1.
A reasonable rhythm is a read every 5–10 seconds while the buyer is likely
on the shop (the first quarter of an hour), then once a minute. The 600
checkout reads a minute per IP cover all your sessions together. One read
just after expires_at gives a final answer: completed if the order came
first, otherwise canceled. See
Idempotency, concurrency and limits.
What happens when the buyer never opens the continue_url?
Nothing happens on the shop: no order, and no stock is reserved. A
checkout stays open until its expires_at, 24 hours after the last
create or update (reads do not extend it); the next read after that
answers canceled. A cart lives 7 days after its last change and then
answers HTTP 200 with the error message not_found. Before the handoff
every create or update extends the deadline; after it, nothing does. The
stored data is deleted 30 days after expiry.
The buyer ordered, but the checkout stays requires_escalation. Why?
The checkout completes only when the order comes from the cart the link
filled and holds at least one of the checkout's items. It does not when the
buyer signed in to the shop only at its checkout (the guest cart is then
merged into the customer cart, and the order comes from that one), or when
the order holds none of the checkout's items; rarely, the completion
itself failed on Monokaido's side (it is best effort). Such a checkout
ends canceled at its expiry, although the order exists. (A checkout
whose link was opened while it was still incomplete stays incomplete
instead; it completes and expires the same way.) Do not treat a missing
completion as proof that there is no order; let the buyer see the shop's
own confirmation.
Can an agent cancel or change an order?
No. Cancelling closes the UCP cart or checkout only. Cancelling a completed
checkout answers it with the message checkout_completed, and the order
stays as it is. Changes to an order are a matter between the buyer and the
shop.
Testing
Is there a sandbox or a test shop?
There is no separate sandbox. You test against a Monokaido shop that has
UCP switched on, on its own custom domain. Catalog, cart and checkout calls
create no order and take no payment; an order exists only once someone
opens a continue_url and orders on the shop — and that is a real order of
that shop. Agree the test with the merchant: agent carts also show up in
the shop's cart statistics. How a merchant switches UCP on is in
Turning UCP on for a shop.
What do I have to host before the first call?
Your platform profile: a JSON document at a public https:// address you
control, answering 200 with no redirect within 5 seconds, at most
256 KiB, with ucp.version 2026-04-08 and the capabilities you want.
Every call under /ucp/v1 names it in the UCP-Agent header. The
Developer quickstart shows a minimal one.
Can I call the API from a web page in the browser?
No. The API sends no CORS headers for other origins, so a page on your own
domain cannot call it. Call it from your server. The only page meant for a
browser is the continue_url, which the buyer opens.
Shops, domains and buyers
Does one integration work with every Monokaido shop?
Yes. Every shop serves the same API on its own domain. Read each shop's
profile and use the endpoint it publishes. Sessions belong to one shop:
a cart or checkout id used on another shop's domain answers HTTP 200 with
the error message not_found. Rate limits are counted per IP across all
Monokaido shops together.
A shop has several domains. Which one do I call?
The profile answers on every served domain of the shop, but every address
it publishes — the endpoint, continue_url, the order and product links —
uses the shop's verified primary domain. Call the published endpoint.
Do I need an API key, OAuth or request signatures?
No. The shop is chosen by the domain you call. Your platform is identified
by the profile address in UCP-Agent, which is not verified
cryptographically. A cart or checkout id is the only key to that session:
keep it on your server and out of links and logs. The continue_url holds
a separate secret meant for the buyer. See
Security and data protection.
Guest or signed-in buyers?
Every UCP session is anonymous; there is no identity linking. When the
buyer opens the continue_url, the items go to the cart the shop shows in
that browser tab: their customer cart if they are signed in to the shop in
that tab, otherwise a guest cart. A link opened in a new tab therefore
usually fills a guest cart. A buyer who then signs in at the shop's
checkout normally keeps the items (the shop merges the guest cart into
the customer's), but the UCP checkout will not complete (see above).
What does the buyer have to enter again on the shop?
Everything except the items and the applied discount code: contact details, the shipping address, the shipping method and the payment. The buyer data you sent stays in the UCP session.
Prices, languages and currencies
Are prices with or without VAT?
Amounts are integers in the minor units of the currency next to them (EUR
and HUF both have two decimals: 69900 EUR is 699.00 €). They include VAT
wherever the shop has a price with VAT, and the shop's price markup rules;
the payload carries no separate flag for it. In a cart or checkout the
totals are subtotal, a negative discount (only while a code applies),
fulfillment (the shipping fee, only once a shipping option is selected)
and total, and everything but total adds up to total. A percentage
discount code is computed on the subtotal without VAT, exactly as the
shop's own checkout does, so 10 % off is not 10 % of the displayed
subtotal. Surcharges of payment methods are not quoted.
Which language and currency does the shop answer in?
The language is context.language from the request body, else the first
usable tag of Accept-Language (in header order — the weights are
ignored), else the shop's first language; only a language the shop offers
is used. The currency follows the language: context.currency does
not change it and only says in which currency a catalog filters.price
(search or lookup) is given. To get prices in another currency, pick a
language the shop sells in that currency. A cart or checkout keeps its
language until a request
body names another context.language; switching re-prices the items in
the new language, and their line ids change.
Stock, discounts and shipping
How current is the stock, and is anything reserved?
The catalog says per variant availability.status — in_stock,
out_of_stock, preorder or discontinued — without counts. Every
create, and every update that sends line_items (a cart update always
does), checks the stock again: a quantity above stock is lowered with the
warning quantity_adjusted, a sold-out line is removed with
out_of_stock, and a pre-order variant is not limited by stock (any line
is capped at 999). Nothing is reserved until the buyer places the order on
the shop; stock is checked again when the items are handed over and on the
shop's checkout.
How do discount codes work?
Only when your profile declares dev.ucp.shopping.discount. One code
applies per cart or checkout: the first one the shop accepts, and every
code after it gets the warning discount_code_combination_disallowed. A
refused code gets discount_code_expired, discount_code_user_ineligible or
discount_code_invalid — and on a cart with no items yet every code is
discount_code_invalid until items are added. The applied code travels
with the items to the buyer's cart, where the shop checks it again.
Which shipping options are there, and what about pickup points?
With dev.ucp.shopping.fulfillment declared, a checkout offers the shop's
active shipping methods for the destination country (before an address is
known, all of them) as options of one shipping method, each with its fee,
computed by the same rule as the shop's checkout. Selecting a method that
needs a pickup point (a Packeta method) adds the message
pickup_point_required: the point is chosen on the shop, and the checkout
can still become requires_escalation. The chosen option is not carried
to the shop; the buyer picks the shipping again there.
Limits, data and versions
What are the rate limits?
Per client IP and per operation, each minute: 600 for reads (the profile,
the catalog, reading a cart or a checkout), 300 for writes, 60 for each of
the two handoff routes (loading the continue_url page, and the request
that page then sends). They are shared across all Monokaido shops. Over the limit
the answer is 429 rate_limited with Retry-After: 60. In front of the API
the web server allows 100 requests a second per IP (burst 200) and answers
above that with its own HTML 429. One client (an IPv4 address, or an
IPv6 /64) may make Monokaido fetch at most 5 platform profiles a minute
that it has not cached yet (a fetched profile serves every shop); more get
503 with a Retry-After. See
Idempotency, concurrency and limits.
What data is stored, and for how long?
A cart or checkout keeps what you sent — the buyer's name, e-mail, phone,
the shipping address, the request context, the discount codes — with
your platform profile address and its last answer, until 30 days after
its expires_at. Answers stored for an Idempotency-Key are deleted
after 25 hours. The UCP tables store no IP address or User-Agent. What
the buyer enters on the shop's checkout is ordinary order data of the
shop. Who is responsible for which data in law is set by the shop's and
Monokaido's contractual terms. See
Security and data protection.
Which protocol version, and how will changes be handled?
Exactly 2026-04-08. Your platform profile's ucp.version must be that
date — any other is refused with 422 version_unsupported — and each
capability you use must list it: a capability declared only at another
version is not negotiated, and an operation that needs it answers with
the message capabilities_incompatible. The shop publishes no
supported_versions. Unknown fields in requests are ignored, never
refused. The shop's profile
always states what it speaks today; this manual and the
OpenAPI document describe
the deployed code, and each page shows when it was last updated.
Whom do I contact?
Questions about a shop's products, prices, delivery or an order go to that
shop. Questions about the UCP implementation go to Monokaido at
support@monokaido.com. Include the shop's
domain, the time (UTC), the method and path, the HTTP status and the
code of the answer — the API returns no request id, so log your own.
A cart or checkout id and a continue_url are credentials: never send
them in full, not even to us — give their first eight characters (see
Reporting a security problem).