API overview
A small HTTP API over the same ledger the site uses. The reads need no key and no signup: JSON out, rate limited by IP. Everything that moves money sits behind an X sign-in or a wallet signature.
Base URL and conventions
| Item | Value |
|---|---|
| Base path | /api on this origin, https://slicepad.fun/api |
| Content type | application/json |
| Money | Lamports, as a decimal string, in fields ending in Lamports |
| Times | ISO 8601 in UTC |
| Addresses | Base58, exactly as on chain. Case-sensitive |
| Handles | handle is the lowercase key; displayHandle keeps the casing |
| Errors | { "error": "human readable" } with a correct status. See Errors |
The public reads
GET /api/tokens?sort=new|fees|mcap&q=&limit=&cursor=
GET /api/tokens/:mint
GET /api/x/:handle
GET /api/stats
GET /api/ledger?limit=&before=
GET /api/proof
GET /api/token-images/:mint
GET /api/launch/config
GET /api/ca
GET /api/cron/health
GET /api/openapi.json/api/token-images/:mint serves the small WebP preview made at launch, with a one-year immutable cache; the full image is on IPFS at the token’s metadataUri. /api/launch/config is what the launch form reads first: whether launches are open, the platform share and recipient limit for new launches, the largest first buy, and pump.fun’s creator fee read live. /api/ca returns the platform token’s address once it is published, and null until then.
Behind an X sign-in
GET /api/auth/x/start?returnTo=/claim redirect to X
GET /api/me the signed-in account
POST /api/claim {wallet, lamports?} queue a payout
POST /api/routing {routing, wallet?, declined?}
POST /api/auth/logoutThese act on the X account in the signed session cookie and on nothing named in the request. See Claim & routing.
The launch routes
POST /api/launch/intent {draft, wallet, mint, digest}
POST /api/launch/metadata multipart: intent, signature, image, thumbnail
POST /api/launch/confirm {intent, signature}
POST /api/rpc JSON-RPC, this site's pages onlyThey follow the steps on Launching a token: prepare, upload the metadata with the wallet’s message signature, and confirm with the transaction signature. /api/launch/confirm answers 202 with {"status": "pending"} until the transaction is final, so poll it. They are built for the launch page and can change with it; do not treat them as a stable integration surface. /api/rpc forwards the few Solana JSON-RPC methods the launch page uses to our provider without exposing its key. It answers only requests from this site’s own pages, and sends or simulates only transactions that call pump.fun’s program.
The spec
/api/openapi.json describes the public data reads as an OpenAPI 3.1 document, for client generators and HTTP clients.
curl -s https://slicepad.fun/api/openapi.json | jq '.paths | keys'Lamports are strings, always
Every field ending in Lamports is a decimal string of whole lamports, never a number. Lifetime totals pass what a double can hold exactly, and a client that parses them as numbers loses precision without an error.
const res = await fetch("/api/stats");
const data = await res.json();
const swept = BigInt(data.sweptLamports); // correct
const wrong = Number(data.sweptLamports); // loses precision above 2^53
const sol = Number(swept) / 1e9; // fine for display onlyMissing data is null, never 0. A token with no market data has "marketCapUsd": null, which means we do not know, not that it is worth nothing.
Rate limits and caching
Each route is limited per IP in a fixed window, one minute for all but the metadata upload. Public reads may be served from the edge for a few seconds, which is why a figure can lag the chain slightly. Nothing derived from a session is ever stored by a shared cache.
| Endpoint | Per IP | Cache-Control |
|---|---|---|
/api/tokens | 120 a minute | public, max-age=0, s-maxage=10, stale-while-revalidate=30 |
/api/tokens/:mint | 60 a minute | public, max-age=0, s-maxage=10, stale-while-revalidate=30 |
/api/x/:handle | 120 a minute | public, max-age=0, s-maxage=10, stale-while-revalidate=30 |
/api/stats | 120 a minute | public, max-age=0, s-maxage=10, stale-while-revalidate=30 |
/api/ledger | 120 a minute | public, max-age=0, s-maxage=5, stale-while-revalidate=15 |
/api/proof | 60 a minute | public, max-age=0, s-maxage=15, stale-while-revalidate=45 |
/api/token-images/:mint | 600 a minute | public, max-age=31536000, immutable |
/api/launch/config | 60 a minute | public, max-age=0, s-maxage=10, stale-while-revalidate=30 |
/api/me | 120 a minute | private, no-store |
/api/claim | 10 a minute | private, no-store |
/api/routing | 20 a minute | private, no-store |
/api/launch/intent | 10 a minute | private, no-store |
/api/launch/metadata | 20 an hour | private, no-store |
/api/launch/confirm | 60 a minute | private, no-store |
/api/rpc | 120 a minute | no-store |
Every limited answer carries the state of your window, success or not:
x-ratelimit-limit: 120
x-ratelimit-remaining: 117
x-ratelimit-reset: 1790000000 # unix seconds
retry-after: 23 # only on a 429/api/cron/health
The scheduled jobs themselves run behind a key. Their health is public, because whether sweeps and payouts are running is something every recipient has a fair claim to know.
{
"ok": true,
"staleAfterSec": 1800,
"jobs": [
{
"job": "sweep",
"lastRunAt": "2026-09-29T12:00:04.211Z",
"lastOkAt": "2026-09-29T12:00:09.870Z",
"secondsSinceOk": 131,
"stale": false,
"running": false,
"runs": 1440,
"lastError": null
}
],
"checkedAt": "2026-09-29T12:02:21.002Z"
}One entry each for sweep, payouts, burns, launches and market. The first four are started every one to five minutes and market every fifteen, each under a lease so two starts never overlap. A job that has not finished cleanly for half an hour, or never has, is stale. Error text is scrubbed of URLs and setting names before it leaves the server.
The chain is the source of truth
This API serves our ledger. Everything in it that involves money is also on chain: the launch, every sweep, every payout, every buy and burn, each by signature. Where the two disagree, the chain is right.
Stability
- Fields may be added. Ignore ones you do not recognise.
- Existing fields of the public reads will not change type or meaning without an entry in the changelog.
- There is no version prefix in the path.
- The routes under
/api/adminand the job routes under/api/cron, other than health, are not part of the public API.