# payd > Self-custodial crypto payments. A merchant gives payd an extended PUBLIC key; > payd works out one receiving address per order and watches the chain. payd > never holds coins and cannot sign a transaction, so there is no balance, no > payout, and no refund it can carry out for anybody. A refund here is a record > of a transfer a person made. Base URL: https://app.payd.sh for every /api and /i path. The documents listed below are served from the origin you fetched this from. Auth: Authorization: Bearer payd_sk_... (a bare key with no scheme also works) payd 4.2.0 - schema generation 20 - OpenAPI 3.1 at /openapi.json ## Read these, in this order - /agent.md The whole contract as one file: every route, every request field, every response field, every status code, every refusal sentence, every enum. Written to be read whole. Start here. - /openapi.json The same surface as OpenAPI 3.1. Generate a client from this. - /docs The same material as a page, if a person is reading. - /health Whether this deployment is alive and watching the chain, and a sorted list of behaviour tokens to branch on. No key. Both machine files are generated from the route table this server registered and the enums its own modules export. They cannot describe a payd you are not running, and where they disagree with anything written about payd elsewhere, they are right. ## Taking a payment, in two calls POST /api/orders {"goodsCents":12000,"shippingCents":590} POST /api/orders/PP-4821903/payment {"rail":"BTC"} The second answers with an instruction carrying address, quotedAmount and asset. Send your customer to /i/ and wait for the payment.settled webhook. That is the whole integration. Do not build a payment page: that one already shows the amount, the address, a code to scan and the live state, and it is the only surface with the information to do it. A rail alone bills the first network the order offers for that coin, and the invoice does not let your customer move it afterwards. Send an asset to name the network, or skip the second call: an unbilled order's invoice offers its coins and their networks, and bills the one your customer presses. ## The six things that get got wrong here 1. Money is integer minor units (goodsCents, amountCents) or exact decimal strings (quotedAmount, chainAmount). Never a float: one ether in wei is past Number.MAX_SAFE_INTEGER and cents lose the same way. 2. goodsCents: null is NOT 0. null means not priced yet (quote_requested). 0 means free, and the order is paid the moment it is registered. 3. A RAIL is a ticker your customer picks: BTC LTC ETH USDT USDC. An ASSET is one ledger: USDT_ERC20 is USDT on Ethereum (ERC-20). Sending asset narrows to one network; sending rail alone bills the first network the order offers, and the invoice does not let the customer move it. To let the customer pick, leave the order unbilled. 4. There is no Idempotency-Key header and no request de-duplication. Send your own reference; a repeat then answers 400 {"errors":{"reference":"... is already in use."}} - which a retry after a timeout must read as ALREADY REGISTERED, not as a bad request. It is deliberately not a 409. IT IS NOT BY ITSELF A SUCCESS. The reference is yours to choose, so the one that collided may belong to an order you never sent - a reused counter, a different amount, a different customer. Read it back with GET /api/orders/:reference and check the figures are the ones you meant before you treat it as registered. A retry that skips the read is how a customer gets shown somebody else's invoice. 5. 404 never distinguishes gone from not-yours from not-a-route. Do not branch. 6. Nothing settles a payment that arrived short, however deeply confirmed, ever. It waits for a person, and so does every refund. ## Not documented, and not to be scripted /app is the merchant's browser portal: form-encoded HTML behind a session cookie, outside the compatibility promise in VERSIONS.md. Use a key. ## Reference GET /health open Is this deployment alive, and is it watching the chain. GET /api/merchant any Who am I, what may this key do, and can this shop be paid yet. GET /api/merchant/keys admin Every key this shop holds, and when each was last used. POST /api/merchant/keys admin Mint a key, and see it once. DELETE /api/merchant/keys/:id admin Revoke one, including the one making the request. GET /api/merchant/wallets admin The extended PUBLIC keys this shop is billed on, and where each lives. POST /api/merchant/wallets admin Point a keyring at an extended public key, in two steps. GET /api/merchant/addresses admin Every address this shop has been issued on one keyring. GET /api/merchant/webhooks admin Where settlement notices are sent. POST /api/merchant/webhooks admin Add an endpoint — an https URL or a Telegram chat — and see a URL's signing secret once. DELETE /api/merchant/webhooks/:id admin Stop delivering to an endpoint. POST /api/merchant/webhooks/:id/enable admin Turn an endpoint the breaker disabled back on. GET /api/merchant/webhooks/deliveries admin What was actually sent, and what happened to it. POST /api/orders any Register something to bill. GET /api/orders any Every order this key may read, newest first, a page at a time. GET /api/orders/:reference any Read one order back, with its outstanding instruction. POST /api/orders/:reference/quote any Fill in a price that was outstanding. POST /api/orders/:reference/status any Move an order along by hand. POST /api/orders/:reference/metadata any Replace your own blob on an order. POST /api/orders/:reference/payment any Issue a payment instruction against an order. POST /api/orders/:reference/payment/requote any Refresh the crypto amount against the current rate. POST /api/orders/:reference/paid any 'I've sent it' — which the server goes and checks. GET /api/orders/:reference/refunds any What has been sent back, and what is still owed. POST /api/orders/:reference/refunds any Write down that money was sent back. POST /api/orders/:reference/refund-destination any Where the customer would like it sent. GET /api/payments/config any What this shop can actually be billed on right now. GET /api/payments/outstanding any Every crypto instruction still being watched, for this shop, a page at a time. GET /api/payments/:id any One instruction, with the order it bills. POST /api/payments/:id/confirm any Record by hand that money arrived in full. POST /api/payments/:id/settle-short any Accept a payment that landed short. GET /api/payments/audit/log deployment The deployment's audit trail — every merchant's. GET /i/:token/state token What is happening to one invoice, as JSON. GET /i/:token/socket token The WebSocket the invoice page patches itself from. GET /i/:token/events token Server-sent events, for a deployment the socket cannot get through. GET /i/:token token The invoice itself, as a page for a person. POST /i/:token/rail token The buyer picks which coin to be billed in. POST /i/:token/sideshift token The buyer opens a SideShift.ai swap to pay in a coin the invoice does not take.