UNPEGDocsOpen app →

API

Everything the app reads is public. Anyone can build on the same endpoints.

Base URL and conventions

https://api.unpeg.io/v1
https://api.unpeg.io/openapi.json
  • Lamports, lots, slots, ids and ratio parts are decimal integer strings. Parse them as BigInt, never as a float.
  • Timestamps are ISO 8601 UTC. Basis points and durations are JSON integers.
  • Errors come as { code, message, requestId }. No provider details, keys or RPC text ever appear.
  • Unknown fields, numeric amounts in place of strings and mismatched action fields are rejected.
  • 120 requests per minute per IP; 30 per minute for transaction builds. Back off on 429.
  • Browsers need their origin listed in the API's CORS configuration; there is no wildcard and no cookie auth.

Read endpoints

EndpointReturns
GET /v1/configCluster, program id, fixed terms, supported actions, oracle trust model and limitation flags.
GET /v1/marketsRegistered markets with the latest current-price observation and the latest qualified settlement interval.
GET /v1/markets/:idOne market. Ids are jitosol, msol, hsol.
GET /v1/markets/:id/observationsDiscount history, newest first. Paginate with limit, before, from, to.
GET /v1/markets/:id/referencesNet asset value history.
GET /v1/observations/:id/evidenceThe exact stored evidence for one observation and its SHA-256 digest.
GET /v1/seriesRegistered series with their decoded on-chain state. Optional marketId filter.
GET /v1/series/:addressOne series.
GET /v1/series/:address/offersOpen escrow sell offers. Optional side=BREAK|HOLD.
GET /v1/wallets/:wallet/positionsBREAK and HOLD balances per series.
GET /v1/wallets/:wallet/offersOffers made by the wallet, including expired ones awaiting cancellation.
GET /v1/transactions/:signatureNOT_FOUND, PROCESSED, CONFIRMED, FINALIZED or FAILED.
GET /v1/eventsServer-sent events for observations, references and registrations, with replay by Last-Event-ID.
GET /health/liveProcess is up.
GET /health/ready503 while any market lacks a fresh qualified interval or no program is configured.

Quotes and previews

EndpointBodyReturns
POST /v1/quotes{ seriesAddress, side, lots }Cheapest legs from current offers, filled and unfilled lots, total premium. Nothing is reserved.
POST /v1/payoff-preview{ discountBps, durationSeconds, lots }Deterministic BREAK and HOLD lamports for a constant discount. Scenario only.

Transaction builder

POST /v1/transactions/build takes seriesAddress, wallet, action and the fields below, simulates the transaction, and returns it unsigned as base64 together with the blockhash, last valid block height, required signer and program id. Failing simulations return 422 instead of a transaction. The server never signs and has no submit endpoint: verify the payer, program and blockhash in the browser, sign with the wallet, and send through your own RPC connection.

ActionExtra fields
mint_pairslots
redeem_pairslots
redeem_break, redeem_holdlots
create_offerlots, side, pricePerLotLamports, expiresAt, offerId (u64 string, maker-chosen, one use)
fill_offerofferAddress, lots
cancel_offerofferAddress
skip_intervalnone; uses the next unresolved interval
settlenone

SDK

The backend ships a dependency-free TypeScript client (UnpegClient) and shared types; the app vendors them into its own tree. The OpenAPI document at /openapi.json is generated from the same schemas that validate every request, so any generator will produce a matching client.

curl https://api.unpeg.io/v1/markets
curl https://api.unpeg.io/v1/markets/jitosol/observations?limit=50
curl -X POST https://api.unpeg.io/v1/payoff-preview \
  -H 'content-type: application/json' \
  -d '{"discountBps":180,"durationSeconds":129600,"lots":"1"}'