Skip to main content
POST /agent/orders lets an AI agent place an order and pay for it in the same request flow. The agent doesn’t need a Zinc account, an API key, or a pre-funded balance: payment travels with the request over HTTP 402 Payment Required, and Zinc ships the order once it’s paid. One 402 advertises every payment rail Zinc accepts, so the same endpoint works for whatever wallet your agent already has:

How It Works

1

Request without payment

The agent sends POST /agent/orders with the order body and no payment.
2

Receive the payment challenge

Zinc checks the body, then responds 402 Payment Required with one challenge per rail:
  • MPP — one WWW-Authenticate: Payment ... header per method (stripe, tempo)
  • x402 — a single PAYMENT-REQUIRED header (base64 x402 v2 envelope)
A client reads whichever it understands and ignores the rest.
3

Pay

The agent pays on its chosen rail and gets a payment proof: an SPT credential for Link, a signed transfer for Tempo or x402.
4

Resubmit with the proof

The agent repeats the same request with the proof attached:
  • MPP (Link, Tempo) — Authorization: Payment <credential>
  • x402 — PAYMENT-SIGNATURE (x402 v2) or X-PAYMENT (x402 v1)
5

Order confirmed

Zinc verifies the payment and returns 201 with the order and an X-Api-Key header for following the order afterward. MPP payments also return a Payment-Receipt header; x402 payments return PAYMENT-RESPONSE.
Only want one rail? Add ?method=stripe, ?method=tempo, or ?method=x402 to get a 402 with just that challenge. Many HTTP clients fold repeated WWW-Authenticate headers into one comma-joined string and can’t pick the right one out. An unknown method returns 400 listing the available ones.

What You Pay

The challenge amount is max_price + the $1.00 API fee. max_price is the most you’re willing to spend on the order (product, shipping, and tax), in cents. Zinc charges the full amount upfront, then returns whatever wasn’t used:
  • Partial refund — when the retailer’s actual total comes in under max_price, Zinc refunds the difference. You effectively pay actual_total + $1.00.
  • Full refund — if the order ends in failed (the retailer rejects it, the item is out of stock, and so on), Zinc refunds everything you paid.
Refunds go back to the original payment on every rail. No action is needed on your side.

Validation runs before payment

A malformed or incomplete body returns 422 before any challenge is issued. An order Zinc can’t fulfill (unsupported retailer, unreachable product URL, unsupported shipping country, invalid address) is checked on the paid retry, before the proof is charged, and returns 400. Either way nothing is charged, so you can fix the body and retry with the same payment.

Retrying safely

Pass an idempotency_key in the body. If a timeout made you lose the 201, retry with the same key: Zinc checks for an existing order after verifying your payment but before settling it. A duplicate returns 409 with the existing order’s id in error.details.order_id and an X-Api-Key to read it, and the new payment is never taken. Link lets an agent pay with a card the user has already saved in their Link wallet. The agent mints a one-time Shared Payment Token (SPT) for the purchase, the user approves the spend in the Link app, and Zinc charges the token as the merchant. The card number never reaches the agent or Zinc, and there’s no checkout page to open. Consumer agents with Link built in, and anything using link-cli, can pay Zinc this way. link-cli mpp pay runs the whole flow: it requests the challenge, creates the spend request, waits for the user to approve it in the Link app, and resubmits with the SPT.
The amount comes from the challenge (max_price + $1.00). --context is shown to the user when they approve, and must be at least 100 characters.
Link caps a single spend request at **500∗∗,soset‘maxprice‘to500**, so set `max_price` to 499 or less on this rail.

Wire-level

If you’re minting the SPT yourself, here’s the flow link-cli automates. 1. Get the challenge. POST /agent/orders?method=stripe with your order and no Authorization header. The 402 carries:
request decodes to JSON whose methodDetails.networkId is Zinc’s Stripe agentic-commerce profile. Pass it as the SPT’s network ID. 2. Mint the SPT for max_price + 100 cents against that network ID, and have the user approve it. 3. Resubmit the identical request with Authorization: Payment <credential>. The credential is an MPP Credential: an echo of the challenge plus a payload of {"spt": "<spt_xxx>"}. Build it with pympp rather than by hand:
SPTs are single-use. If the request fails after the token is charged, mint a new one to retry. If it fails validation (400), the token wasn’t charged and you can reuse it.

Pay with MPP (Tempo)

The Machine Payments Protocol client libraries handle the 402 flow for you. Install one:
The quickest test is the mppx CLI:
Or from code:
TypeScript

Pay with x402

Any x402 client can pay. The 402 carries a PAYMENT-REQUIRED header (a base64 x402 v2 envelope) with one accepts[] entry per chain Zinc currently takes: USDC on Base, and on Solana. Pick a chain your wallet holds USDC on, sign the payment, and resubmit with the proof in PAYMENT-SIGNATURE (or X-PAYMENT for x402 v1 clients). Settlement uses the scheme’s sponsored flow. On Base you sign an EIP-3009 transferWithAuthorization. On Solana you sign a partial SPL transfer that the facilitator co-signs as fee payer, so you don’t need SOL for gas.

After the Order

The X-Api-Key header on the 201 is an API key for the paying agent. Store it. It’s the only way to follow the order without paying again. With it you can:

Agent Data Endpoints

The product data endpoints under /agent/* (such as search and product details) use the same 402 flow at $0.01 per call. That’s below the card network minimum, so these endpoints only offer the stablecoin rails (Tempo and x402), not Link.

Next Steps

Agent Playground

Place an agent order in the interactive playground.

API Reference

Full spec for POST /agent/orders.

Link for Agents

Set up a Link agent wallet.