{"openapi":"3.1.0","info":{"title":"BuxAPI","version":"1.0.0","summary":"Crypto payment gateway and API. Invoices, wallets, sends and transfers.","description":"Accept Bitcoin, Litecoin, and USDC, USDT, DAI and native coins on Base, Ethereum, Polygon, BNB Chain and Solana.\n\n**Identity is a keypair, not an account.** `POST /v1/wallets` is unauthenticated and returns\na public key, a private key and a recovery phrase. There is nothing to sign up for.\nThe server stores a SHA-256 hash of the private key and never sees the recovery phrase, so\nneither can be recovered for you.\n\n**Amounts are integers, always.** Invoice amounts priced in `usd` are cents. Every other\namount (deposits, sends, transfers, quotes) is an integer in the token smallest unit. Raw\n18-decimal amounts exceed 2^53, so they are carried as JSON **strings**: parse them with a\nbig-integer type, never with a float.\n\n**Fees.** A confirmed deposit is charged a network fee (the estimated sweep cost, locked at\ncredit time and reported as `network_fee_amount` on the deposit) plus 0.5% of the remainder,\nso `credited = gross - network_fee - fee`. Plain native deposits (eth, bnb, sol) pay no\nnetwork fee. Invoice quotes add the estimated network fee on top, so the payer covers the\nsweep. Sends cost their network fee. Internal transfers are free. Live per-pair estimates:\n`GET /v1/network-fees`.","contact":{"name":"BuxAPI","url":"https://buxapi.com/contact"},"license":{"name":"Proprietary"}},"servers":[{"url":"https://buxapi.com","description":"Production"}],"tags":[{"name":"Wallets","description":"Create and manage a wallet"},{"name":"Addresses","description":"Deposit addresses"},{"name":"Invoices","description":"Fixed-amount payments with a hosted checkout"},{"name":"Sends","description":"On-chain payouts"},{"name":"Transfers","description":"Free internal moves between BuxAPI wallets"},{"name":"Activity","description":"Deposits and the ledger"},{"name":"Public","description":"Unauthenticated, used by the checkout page"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Your `bux_sec_...` private key, as `Authorization: Bearer bux_sec_...`. Server side only: it is the whole credential, and there is no second factor."}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable code."},"message":{"type":"string","description":"Human-readable explanation."}},"required":["code","message"]}},"required":["error"]},"Amount":{"type":"string","description":"Integer in the smallest unit, as a string. Raw 18-decimal amounts exceed 2^53 and lose digits as a JSON number.","examples":["25000000"]},"Pair":{"type":"string","pattern":"^[a-z0-9]+:[a-z0-9]+$","description":"A chain and token, e.g. `base:usdc`.","examples":["base:usdc","solana:usdc","polygon:usdt"]},"Wallet":{"type":"object","properties":{"public_key":{"type":"string","examples":["bux_pub_7Yd4Qk9v2mTb8sXaLpR3ZnHc6JwEuFgKmQ2Ts9VbXe1Z"]},"settlement_mode":{"type":"string","enum":["raw","convert"]},"label":{"type":["string","null"]},"webhook_url":{"type":["string","null"]},"balances":{"type":"array","items":{"type":"object"}},"activated_tokens":{"type":["object","null"]}}},"NewWallet":{"type":"object","description":"Returned once, at creation, and never again.","properties":{"public_key":{"type":"string"},"private_key":{"type":"string","description":"Shown once. Not recoverable."},"mnemonic":{"type":"string","description":"Shown once. Not recoverable."},"webhook_secret":{"type":"string","description":"Signs every webhook to this wallet."},"settlement_mode":{"type":"string","enum":["raw","convert"]},"warning":{"type":"string"}}},"Invoice":{"type":"object","properties":{"id":{"type":"string","examples":["inv_4kR2QpN7vXsB1mLdZaYc9F"]},"status":{"type":"string","enum":["pending","detected","paid","partially_paid","overpaid","expired"]},"currency":{"type":"string","description":"'usd' or a token symbol."},"amount":{"$ref":"#/components/schemas/Amount"},"accepted":{"type":"array","items":{"$ref":"#/components/schemas/Pair"}},"quotes":{"type":"object","description":"Payable amount per pair, locked at creation. Each quote is the invoice amount plus that pair's estimated network fee, so the payer covers the sweep and the merchant is credited the invoice amount minus only the percentage fee.","additionalProperties":{"type":"string"}},"received":{"type":"object","description":"Running total received per pair.","additionalProperties":{"type":"string"}},"expires_at":{"type":"string","format":"date-time"},"order_id":{"type":["string","null"]},"metadata":{"type":["object","null"]},"checkout_url":{"type":"string","format":"uri"},"idempotent_replay":{"type":"boolean","description":"Present and true when this order_id already existed. Nothing new was created."}}}}},"paths":{"/v1/wallets":{"post":{"tags":["Wallets"],"summary":"Create a wallet","description":"The only authenticated-free write endpoint. Returns the private key and recovery phrase ONCE. Store both before doing anything else: the server keeps only a hash of the key and never receives the phrase.\n\nSend `public_key` and `sec_hash` together to register a keypair you generated yourself, in which case no secret material is transmitted at all.","security":[],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"settlement_mode":{"type":"string","enum":["raw","convert"],"default":"raw","description":"`raw` credits the token that arrived. `convert` swaps everything to USDC on arrival and credits USD cents. Changeable later only while the wallet is empty."},"label":{"type":"string","maxLength":100},"webhook_url":{"type":"string","format":"uri"},"public_key":{"type":"string","description":"Client-side keygen. Requires sec_hash."},"sec_hash":{"type":"string","pattern":"^[0-9a-f]{64}$","description":"SHA-256 of the private key. Requires public_key."}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewWallet"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/wallet":{"get":{"tags":["Wallets"],"summary":"Read the authenticated wallet","description":"Balances, settlement mode, activated pairs and webhook URL. Use it to verify a key works.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Wallet"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Wallets"],"summary":"Update wallet settings","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","minProperties":1,"properties":{"label":{"type":["string","null"],"maxLength":100},"webhook_url":{"type":["string","null"],"format":"uri"},"activated_tokens":{"type":["object","null"],"description":"Chain to token-array map limiting what this wallet accepts.","additionalProperties":{"type":"array","items":{"type":"string"}}},"settlement_mode":{"type":"string","enum":["raw","convert"],"description":"Only changeable with zero balances and nothing in flight."}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Wallet"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/addresses":{"post":{"tags":["Addresses"],"summary":"Allocate a deposit address","description":"Permanent, unlimited and free to hold. One `evm` address receives on Base, Ethereum, Polygon and BNB Chain; `solana` is derived separately from the same wallet.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"family":{"type":"string","enum":["evm","solana"]},"label":{"type":"string","maxLength":100},"callback_url":{"type":"string","format":"uri","description":"Webhook target for deposits to this address specifically."}},"required":["family"]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"family":{"type":"string","enum":["evm","solana"]},"index":{"type":"integer","description":"BIP44 derivation index."},"address":{"type":"string"},"label":{"type":["string","null"]},"callback_url":{"type":["string","null"]}}}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"tags":["Addresses"],"summary":"List deposit addresses","security":[{"bearerAuth":[]}],"parameters":[{"name":"family","in":"query","schema":{"type":"string","enum":["evm","solana"]},"required":false},{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"Opaque cursor from the previous page. Omit for the first page."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/invoices":{"post":{"tags":["Invoices"],"summary":"Create an invoice","description":"A `usd` invoice locks a per-token quote at creation, so the payable amount is fixed for its lifetime.\n\n`order_id` is unique per wallet: reusing one returns HTTP **200** with the original invoice and `idempotent_replay: true` rather than creating a second. That is the intended way to make checkout retry-safe.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"amount":{"oneOf":[{"type":"integer","minimum":1},{"type":"string"}],"description":"USD cents when currency is `usd`, otherwise the token smallest unit."},"currency":{"type":"string","description":"'usd' or a token symbol.","examples":["usd"]},"accepted":{"type":"array","maxItems":40,"items":{"$ref":"#/components/schemas/Pair"},"description":"Subset of the wallet activated pairs. Omit to accept all of them."},"expires_in":{"type":"integer","minimum":60,"maximum":86400,"description":"Seconds. Capped at 3600 when a volatile (non-stablecoin) pair is accepted, because a locked quote on a moving asset is a free option against the merchant."},"success_url":{"type":"string","format":"uri","maxLength":500},"cancel_url":{"type":"string","format":"uri","maxLength":500},"order_id":{"type":"string","maxLength":100},"metadata":{"type":"object","description":"Max 4000 characters serialized. Returned on every webhook."},"webhook_url":{"type":"string","format":"uri","maxLength":500}},"required":["amount","currency"]}}}},"responses":{"200":{"description":"Existing invoice for this order_id","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invoice"}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invoice"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"tags":["Invoices"],"summary":"List invoices","security":[{"bearerAuth":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["pending","detected","paid","partially_paid","overpaid","expired"]}},{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"Opaque cursor from the previous page. Omit for the first page."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/invoices/{id}":{"get":{"tags":["Invoices"],"summary":"Read an invoice","description":"Also the safety net when a webhook does not arrive: this is authoritative and can be polled.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invoice"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/invoices/{id}/cancel":{"post":{"tags":["Invoices"],"summary":"Cancel an unpaid invoice","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Cancelled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invoice"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/send":{"post":{"tags":["Sends"],"summary":"Send funds on-chain","description":"Irreversible. Costs the estimated network fee with no service fee added.\n\n`amount` may be the literal string `max`, which resolves at debit time to the full debit balance minus the network fee: the send that empties the balance exactly. Pair it with `GET /v1/send-fee` to preview what `max` will resolve to.\n\n**Always pass `idempotency_key`.** A retry after a timeout returns the original send instead of broadcasting a second one, and a timeout on this endpoint is exactly when you cannot tell whether the first one went out.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"chain":{"type":"string","enum":["base","eth","polygon","bsc","solana"]},"token":{"type":"string","examples":["usdc"]},"to_address":{"type":"string","description":"Validated before broadcast. EVM addresses with a mixed-case EIP-55 checksum must have a correct one; Solana addresses must be on-curve."},"amount":{"oneOf":[{"$ref":"#/components/schemas/Amount"},{"type":"string","const":"max","description":"Resolves at debit time to the full debit balance minus the network fee."}]},"idempotency_key":{"type":"string","maxLength":100}},"required":["chain","token","to_address","amount"]}}}},"responses":{"201":{"description":"Queued","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/sends":{"get":{"tags":["Sends"],"summary":"List sends","security":[{"bearerAuth":[]}],"parameters":[{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"Opaque cursor from the previous page. Omit for the first page."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/sends/{id}":{"get":{"tags":["Sends"],"summary":"Read a send","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/send-fee":{"get":{"tags":["Sends"],"summary":"Quote the network fee a send would be charged","description":"Uses the same estimator `POST /v1/send` prices the debit with, and also reports the debit balance and what `amount: \"max\"` would resolve to. An estimate only: the fee actually charged is computed at send time.\n\n`to_address` is optional but worth passing on Solana, since an existing recipient token account avoids the ATA rent.\n\nErrors: 422 `unsupported_chain` / `unsupported_token`, 503 `fee_estimate_unavailable`.","security":[{"bearerAuth":[]}],"parameters":[{"name":"chain","in":"query","required":true,"schema":{"type":"string","enum":["base","eth","polygon","bsc","solana"]}},{"name":"token","in":"query","required":true,"schema":{"type":"string"},"example":"usdc"},{"name":"to_address","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"chain":{"type":"string"},"token":{"type":"string"},"debit_asset":{"type":"string","description":"The asset the fee is charged in ('usd' for a convert-mode wallet)."},"network_fee":{"type":"string","description":"Raw units of the debit asset. Authoritative figure of this quote."},"network_fee_usd_cents":{"type":["integer","null"],"description":"Display figure. Null when the price feed is down."},"balance":{"type":"string"},"max_amount_raw":{"type":"string","description":"What `amount: \"max\"` would resolve to right now."}}}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/transfer":{"post":{"tags":["Transfers"],"summary":"Transfer to another BuxAPI wallet","description":"A ledger move. Instant, free, nothing broadcast. Same asset on both sides by construction.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"to":{"type":"string","description":"Destination `bux_pub_...` public key."},"asset":{"type":"string","examples":["usdc"]},"chain":{"type":"string","description":"Omit for a `convert`-mode USD balance."},"amount":{"$ref":"#/components/schemas/Amount"},"idempotency_key":{"type":"string","maxLength":200}},"required":["to","asset","amount"]}}}},"responses":{"201":{"description":"Transferred","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/transfers":{"get":{"tags":["Transfers"],"summary":"List transfers","security":[{"bearerAuth":[]}],"parameters":[{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"Opaque cursor from the previous page. Omit for the first page."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/deposits":{"get":{"tags":["Activity"],"summary":"List deposits","description":"Use `credited_amount`, not `amount_raw`: the network fee (`network_fee_amount`, the sweep cost, zero for plain native deposits) and the 0.5% fee (`fee_amount`, taken on the amount after the network fee) have already been taken out of it.","security":[{"bearerAuth":[]}],"parameters":[{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"Opaque cursor from the previous page. Omit for the first page."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/transactions":{"get":{"tags":["Activity"],"summary":"The wallet ledger","description":"Every credit and debit with its reason. This is the audit trail.","security":[{"bearerAuth":[]}],"parameters":[{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"Opaque cursor from the previous page. Omit for the first page."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/webhook-test":{"post":{"tags":["Activity"],"summary":"Deliver a signed test webhook","description":"Proves an endpoint is reachable and that your signature verification works, without waiting for a real payment.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Queued","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/rates":{"get":{"tags":["Public"],"summary":"USD rates per token","description":"Stablecoins always return exactly 1. Rate limited per IP.","security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"429":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/network-fees":{"get":{"tags":["Public"],"summary":"Estimated sweep fee per pair, in USD cents","description":"What a deposit of that pair will be charged as its network fee at credit time, and what an invoice quote adds on top for the payer. A pair whose chain RPC or price feed is down reports `usd_cents` null. Estimates only: the charged fee is locked at credit time. Cached about 15 seconds. Rate limited per IP.","security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"buffer":{"type":"number","description":"The multiplier applied to the raw gas estimate.","examples":[1.5]},"fees":{"type":"object","description":"Keyed by pair, e.g. `base:usdc`.","additionalProperties":{"type":"object","properties":{"usd_cents":{"type":["integer","null"]}}}},"updated_at":{"type":"string","format":"date-time"}}}}}},"429":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/public/invoices/{id}":{"get":{"tags":["Public"],"summary":"Payer-facing invoice view","description":"What the hosted checkout page reads. Deliberately exposes nothing about the merchant: the wallet id, the public key, the webhook URL and every other invoice all stay hidden.","security":[],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/public/invoices/{id}/select":{"post":{"tags":["Public"],"summary":"Choose a chain and token to pay with","description":"Allocates the deposit address the payer sends to.","security":[],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"pair":{"$ref":"#/components/schemas/Pair"}},"required":["pair"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"webhooks":{"invoice.paid":{"post":{"summary":"An invoice was paid in full and credited","description":"Signed with `X-Buxapi-Signature: t=<unix>,v1=<hex>`, where the hex is\n`HMAC-SHA256(webhook_secret, \"{t}.{raw body}\")`.\n\nVerify over the RAW body: re-serialising parsed JSON changes the bytes and no signature\nwill match. Compare in constant time. Reject timestamps older than a few minutes.\n\nRetried up to 7 times over roughly 33 hours, so the same event can arrive more than once.\n`X-Buxapi-Delivery` is stable per event and is what you deduplicate on.\n\nOther events: `invoice.detected`, `invoice.partially_paid`, `invoice.overpaid`,\n`invoice.expired`, `deposit.detected`, `deposit.confirmed`, `send.sent`, `send.confirmed`,\n`send.failed`, `transfer.received`.\n\nThe `deposit.confirmed` payload carries `credited_amount`, `fee_amount` and\n`network_fee_amount`; `deposit.detected` omits those credit-time fields.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invoice"}}}},"responses":{"200":{"description":"Any 2xx marks the delivery successful. Anything else is retried."}}}}}}