API

Monero price API for everyone, on the clearnet and on an onion address for hidden services. Base path /api/v1. Machine-readable: swagger.json, swagger.yaml.

Getting a token

  1. POST /api/v1/challenges returns a challenge id, its difficulty (24 bits) and the window to redeem it, which opens 30 seconds after it was issued and closes after 1 hour.
  2. Compute a hashcash stamp for the id. Redeeming early is refused however fast you are.
  3. POST /api/v1/tokens with the stamp returns a token valid for 90 days.
  4. Send it as X-API-Token to GET /api/v1/price, once every 30 seconds.

Every price response tells you when to ask next in next_request_at. A 429 carries Retry-After in seconds, at most 30 seconds, and retry_at in UTC; a request without a token also gets 429, and an invalid or expired token gets 401.

Stamp format

Hashcash version 1, seven fields separated by colons:

1:BITS:TIME:CHALLENGE_ID:EXTENSION:RANDOM:COUNTER

BITS is at least the challenge difficulty and TIME uses the layout 2006-01-02T15/04/05Z0700. COUNTER is 8 bytes, big endian, standard base64. The stamp is valid when its SHA-224 digest starts with BITS zero bits.

The pow command makes one, using every core. PAYLOAD is the challenge id and DIFFICULTY its number of bits:

go run github.com/RogueTeam/xmrgateway/cmd/xmrgateway@latest pow PAYLOAD DIFFICULTY

Add -until with the challenge's not_before to have it wait until the stamp can be redeemed before printing it.

Endpoints

POST /api/v1/challenges

Request a challenge
Solve it with a hashcash stamp and redeem the stamp at /tokens between not_before and expires_at.

StatusBodyDescription
201ChallengeCreated
503Errortoo many pending challenges
GET /api/v1/challenges/{id}

Look up a pending challenge

ParameterInDescription
id *pathchallenge id
StatusBodyDescription
200ChallengeOK
404Errorunknown, used or expired
GET /api/v1/price

Price of 1 XMR
One request per token per rate limit window. next_request_at says when the token may ask again.

Requires the X-API-Token header.

ParameterInDescription
currencyqueryISO 4217 code, or BTC
StatusBodyDescription
200PriceOK
401Errorinvalid or expired token
404Errorunknown currency
429Errorrate limited, or no token
503Errorno recent price
POST /api/v1/tokens

Redeem a stamp for a token
A stamp that fails the proof of work burns its challenge.

ParameterInDescription
body *bodysolved stamp
StatusBodyDescription
201TokenCreated
400Errormalformed stamp
403Errornot enough work, challenge burned
404Errorunknown or already used challenge
410Errorchallenge expired
425Errortoo early, see retry_at

Objects

Challenge

FieldTypeExample
difficultyinteger24
expires_atstring2026-11-07T13:00:00Z
idstring0d5e4bd2-2c32-4f3e-9a7a-2f6a0e1c9b11
not_beforestring2026-11-07T12:00:30Z

Error

FieldTypeExample
errorstringrate limited
retry_atstring2026-11-07T12:01:00Z

Price

FieldTypeExample
currencystringUSD
next_request_atstring2026-11-07T12:01:00Z
pricestring312.45
updated_atstring2026-11-07T11:55:30Z

RedeemRequest

FieldTypeExample
stampstring1:24:2026-11-07T12/00/01Z:0d5e4bd2-2c32-4f3e-9a7a-2f6a0e1c9b11::0:AAAAAAAB4zA=

Token

FieldTypeExample
expires_atstring2027-02-05T12:00:30Z
tokenstring