After the sale over UCP
Orders, files a shopper bought, cancellations, returns, buying again, errands, gift cards, subscriptions and terms, through UCP REST, UCP MCP and A2A.
The jobs a shop's own MCP server does for an assistant also work through UCP. Each is declared on the shop's profile at https://<shop>/.well-known/ucp under a Storeware name, with its schema at https://api.storeware.ai/schemas/ucp/<date>/<name>.json. Every call takes the agent key and your profile, as in Calling it. Over MCP the arguments sit beside meta, and over A2A they are a DataPart naming the tool, as for Ask.
A shopper's orders and returns
ai.storeware.shopping.post_purchase. These need a key a shopper linked (see Identity linking). A key nobody linked is refused with identity_required. Writes also need the shop to let linked assistants act, a setting the merchant controls. When it is off, the answer is capability_unsupported and the shopper can do it on the shop's website.
| Job | REST, under /api/ucp/v1 | MCP tool |
|---|---|---|
| List my orders | GET /orders?limit= | list_my_orders |
| Stop an unpaid, undispatched order | POST /orders/{id}/cancel | cancel_order |
| Ask the shop to stop one | POST /orders/{id}/cancellation-request | request_cancellation |
| What can go back | GET /orders/{id}/returnable-lines | returnable_lines |
| Open a return | POST /returns | request_return |
| One return, or all of them | GET /returns/{id}, GET /returns | get_return, list_my_returns |
| Withdraw a return | POST /returns/{id}/cancel | cancel_return |
| Buy an order again | POST /orders/{id}/reorder | reorder |
| A link to a file the order bought | POST /orders/{id}/downloads | get_download_link |
A return names order_id and line_items, each with a line_item_id from the returnable lines, a quantity and a reason code. An agent may also open a return on an order it placed itself, without a linked shopper. Buying again answers with a new checkout, and anything that could not be repeated is a warning in its messages.
Files a shopper bought
When an order bought downloads, Get Order (GET /orders/{id} or get_order) lists them under ai.storeware.shopping.post_purchase.downloads. This happens only when your profile declares ai.storeware.shopping.post_purchase and a shopper linked the key, and only for that shopper's own order. Each entry has line_item_id, asset_id, the file's name, downloads_remaining (null is unlimited) and available. When a file cannot be had, unavailable says why (unpaid, canceled, refunded or exhausted) and reason says it in a sentence. Reading the order spends nothing.
To fetch one, send line_item_id and asset_id to POST /orders/{id}/downloads, or call get_download_link with the order's id. The answer has the file's name, a url, its expires_at and the downloads_remaining after it. The link is the one the shop's own receipt page hands out. It works for a few minutes and anybody holding it can open the file, so pass it to the shopper straight away and do not store it. Each new link counts as one download. Asking again while the last link still works answers with an equivalent link, marked reissued, and counts nothing.
An unpaid, cancelled or fully refunded order is refused with download_unavailable, and a spent allowance with download_limit_reached. A file that is not on the order, and an order that is not the shopper's, are both not_found. Over the shop's own MCP server, track_order lists the same files and get_download_link takes order_id, line_item_id and asset_id.
Errands
ai.storeware.shopping.watch, open to any agent key. Leave an errand against a variant with POST /watches or watch_for_it: when it is back in stock, or at or under a price, the shop records it. Read it with GET /watches/{id} or get_watch. The first read after the condition is met carries handoff, a single-use token for one checkout at that price, and no later read does. List with GET /watches and withdraw with POST /watches/{id}/cancel.
Gift cards and discount codes
ai.storeware.shopping.gift_card. Redeem a code into a basket with POST /checkout-sessions/{id}/gift-cards or POST /carts/{id}/gift-cards, sending { "code": "..." }, or the tools apply_gift_card and apply_cart_gift_card. The answer is the checkout or cart, with what the card was worth under ai.storeware.shopping.gift_card. A code is spent once, so send an idempotency key when you retry.
A cart takes discounts.codes the way a checkout does, and shows what they took off under discounts.
Subscriptions
ai.storeware.shopping.selling_plan. When your profile declares it, a product lists its plans under that key. To subscribe, send selling_plan_id on a checkout or cart line. A plan the item is not sold on is refused with selling_plan_not_offered and the line is left out, never bought once in its place. Send null to buy a line once. Leave the field out and a line keeps the plan it had.
A subscription is kept on an account, so a basket holding one is placed only for a shopper who signed in or linked the shop. Managing a subscription after it starts (pausing, skipping, cancelling) is for the shopper on the shop's own website. No key can do it.
Terms
request_terms and accept_terms on UCP MCP do what POST /checkout-sessions/{id}/terms and POST /checkout-sessions/{id}/terms/{offer_id}/accept do over REST: ask the shop to take something off a basket, with a reason and the total you want, then take the signed offer.