API overview
The HashPay API is small on purpose. Most integrations only touch the embed and webhooks — but everything is here, grounded in the running service.
Base URL
https://api.hashpay.dev/v1
The version is pinned in the path (/v1). The embed widget ships with this base built in, so you rarely type it yourself.
Conventions
- JSON in, JSON out. Send
Content-Type: application/json; every response is JSON. - Timestamps are RFC 3339 / ISO 8601 strings in UTC, e.g.
"2026-06-28T12:15:30Z". - Enums serialize as their uppercase name, e.g.
"CONFIRMED". - Modes. Every object carries
mode—"test"or"live"— decided entirely by the key that created it. Test and live data never mix.
Amounts
Money appears in two forms on every payment, and you should use the right one for the job:
| Field | Example | Use for |
|---|---|---|
amount | "29.00" | Display. USD-pegged decimal string (stablecoins are 1:1 USD). |
amountBaseUnits | "29000000" | Exactness. The integer on-chain amount in the token's base units. |
decimals | 6 | The token's decimals — 6 everywhere except BNB Chain (18). |
Never hard-code 1e6: pair amountBaseUnits with decimals. See Chains & tokens.
Object IDs
IDs are prefixed for legibility — the prefix tells you the type at a glance.
| Prefix | Object |
|---|---|
acct_ | Account |
pay_ | Payment |
prod_ · price_ · plink_ | Product · Price · Payment Link |
cs_ | Checkout Session |
store_ · key_ | Store · API key |
pk_ · sk_ · whsec_ | Publishable key · Secret key · Webhook signing secret |
Authentication at a glance
Three styles, depending on who's calling. Full detail in Authentication.
| Caller | How | Endpoints |
|---|---|---|
| Browser / embed | publishableKey in the body + the page's Origin | Checkout create & info |
| Buyer's browser | the unguessable payment id (capability) | Payment status & cancel |
| Your server | Authorization: Bearer sk_… | Checkout Sessions · store & account management |
Limits & quota
- Rate limit.
POST /checkoutis limited to 120 requests per minute per IP; over that returns429 rate_limited. - Status polling via
GET /payments/{id}triggers a fresh on-chain check at most once every ~12 seconds per payment; poll as often as you like, but you'll see cached state in between. - Monthly volume ceiling. Billing is by USD volume received per month, account-wide: the free plan includes $2,000/month, paid plans raise the ceiling. Past it,
POST /checkoutreturns402 volume_cap_reacheduntil you upgrade or the month rolls over (in-flight payments still settle). Test payments never count.
Idempotency
Two things to know:
- Creating a payment is not idempotent. Each
POST /checkoutclaims a new payment slot, so call it once per buyer attempt and keep the returnedpaymentIdrather than re-posting. (In the embed, the widget handles this for you.) - Webhooks are safely de-dupable. Every delivery carries a stable
id(also in theX-HashPay-Deliveryheader); dedupe on it so retries don't double-process. See Webhooks.
The rest of the reference
Authentication
Keys, origins, and what turns a live key on or off.
Errors
The error envelope and every code you can get back.
Checkout
Create a payment from a price, link, or session.
Payments
The payment object, status lifecycle, polling and cancel.
Checkout Sessions
Server-created sessions for dynamic amounts.
Products & Prices
The catalogue objects you reference by id.
Webhooks
Events, payloads, signing, and delivery.
Embed SDK
The HashPay global, attributes, and options.
Chains & tokens
Networks, contracts, decimals, confirmations.