Skip to content

API reference ​

Public read-only endpoints at https://api.zebra.pub. All responses are JSON; amounts are wei strings (1 BNB = 10¹⁸ wei) and times are Unix seconds.

Rate limits and caching ​

ItemRule
Most endpoints120 requests per minute per IP
/api/flap*, /api/meta, /api/tx*, /api/bind/*30 per minute per IP (reads the chain, simulates a call or calls Flap)
Over the limit429 with retry_after_s in the body
CachingResponses carry cache-control and x-cache: HIT/MISS; the same URL returns the same data within its cache window
EndpointCache
/api/launches, /api/launch/*, /api/recent3 s
/api/me/*, /api/airdrops*5 s
/api/stats, /api/profile/*10 s
/api/dao, /api/hot15 s
/api/name/*, /api/address/*, /api/search30 s
/api/flap, /api/flap/estimate, /api/vanity, /api/timeline60 s
/api/binding/*3 seconds
/api/decode5 minutes
/api/health, /api/meta, /api/admin/*, /api/tx*, /api/bind/*not cached

For anything more frequent, read the on-chain events directly (see Contracts).

Rounds ​

GET /api/launches ​

List rounds. By default open rounds come first, then full, then launched; each group is ordered by the sort.

ParamNotes
sortprogress (default, fill progress) · people · amount
stageOpen · Full · Launched · Done · Refunding; all if omitted
limitdefault 50, max 200

Each item has: address, creator (the address that sent the transaction), creator_id (the Agent ID the issuer acts for: itself, or the ID it is bound to; null if none), creator_name, template_id (game template, 0 = Classic), binding (binding contract this round locked in), kind (TaxV6/TaxV6Vault/PlainV7), name, symbol, meta, pool, quote_token, slip_bps, fee_bps, buy_tax_bps, sell_tax_bps, min_per_id, max_per_id, target, raised, left_bnb, progress (0–1, fill progress), subscribers, stage, created_time, filled_at, launched_at, graduated_at (when it graduated on Flap and liquidity moved to the DEX), token, spent, tokens_bought, fee_charged.

GET /api/launch/:addr ​

All fields for one round, plus its current subscribers (subscribers: who is the address that paid and receives, id the Agent ID it counts for, name that ID's name; with a bound wallet who ≠ id), exits and settlements, and stats:

FieldNotes
first_sub_time, exits, exited_peoplefirst subscription time; number of exits and of people who exited
distributed, distributed_atpeople paid out at distribution, and when it finished
graduated_at, dex_poolgraduation time and DEX pool
holdersaddresses holding the token after launch (replayed from its on-chain transfers)
real_holders, real_sharehow many of them hold an Agent ID, and their share of the supply (0–1)
top10_shareshare of the 10 largest holders, leaving out contracts (bonding curve, DEX pool, the round) unless the contract itself holds an Agent ID

GET /api/launch/:addr/wall ​

Name wall: subscription events (subscribe, top up, exit). limit defaults to 100, max 500.

GET /api/me/:addr ​

addr may also be a name (with or without .ai); looking needs no wallet. An address's Agent ID, rounds it joined or created, its amounts, and the DAO airdrops it received (airdrops: one row per batch and token, with amount, delivered or not, transaction hash). Joined rounds also carry my_balance (current holding), my_since (when this holding began), my_received, my_refunded and my_exit_back; my_payee is the address that actually paid and receives in that round (the bound wallet when the ID joined through it). For an Agent ID, rounds its bound wallet joined for it are listed too. binding is the first three fields of /api/binding below. profile is as below.

GET /api/profile/:id ​

Name-card data; id is a name (with or without .ai) or an address. profile has joined (rounds joined), at_launch (rounds still in at launch), created, holding (launch tokens still held), hold_days (days the longest current holding has lasted), airdrops (airdrop batches received), early (among the first 50,000 claims) and pending_airdrops (airdrops being sent but not yet delivered, summed per token).

GET /api/hot?limit=10 ​

Real-person leaderboard: open rounds by current subscribers, launched ones by holders with an Agent ID (real_people), most first, up to 50.

Wallet binding ​

GET /api/binding/:who ​

who is an address or a name. Returns:

FieldMeaning
contractbinding contract new rounds use
walletwhen who is an Agent ID: its bound wallet (address, bound_at, tx), or null
idwhen who is a wallet: the Agent ID it acts for (address, name, bound_at, tx), or null
next_bind_at, nonceAgent ID: earliest time it may bind again (0 = now), current signature nonce
wallet_free_atwallet: earliest time it may be bound (0 = now)
historylast 50 binding events: kind (bound / unbound / revoked), id_addr, wallet, detail (how it was unbound: wallet / id / id_signature / replaced), block_time, tx_hash

Agent hand-off (order codes) ​

The Agentic Wallet only works through chat. These endpoints prepare and check a transaction or an authorization to sign, store it under a 6-character code (valid 30 minutes, fetched once) for the Agent to run with the Zebra skill. They only ever produce calls to Zebra round contracts or the binding contract, never token approvals or transfers.

POST /api/tx ​

json
{ "action": "subscribe", "launch": "0x…", "from": "0x…", "amount": "0.05" }
FieldMeaning
actionsubscribe (subscribe or top up) · exit · claim · refund · withdraw · withdraw_tokens
launchround contract
fromthe address that will send it (Agentic Wallet or bound wallet)
amountBNB to subscribe (or amount_wei); subscribe only
langoptional; en gives an English summary (default Chinese); /api/bind/request takes it too

Checks, in order: the round exists and is at the right stage; which Agent ID from acts for; whether that ID already joined this round from another address; the amount against the per-person limits and the room left; finally a simulation from from. On failure: 400 with {"error": "reason (Chinese)", "code": "ErrorCode"}. On success:

json
{ "kind": "tx", "code": "NHJQU3", "expires_at": 1793008991, "chain_id": 56, "action": "subscribe",
  "launch": "0x…", "from": "0x…", "to": "0x…", "value": "50000000000000000", "value_bnb": "0.05",
  "data": "0x8f449a05", "function": "subscribe()", "summary": "…" }

POST /api/bind/request ​

json
{ "name": "alice", "wallet": "0x…" }        // bind
{ "action": "unbind", "name": "alice" }     // unbind the current wallet

Checks the name, cooldowns and whether the wallet is taken, and returns the EIP-712 authorization to sign: kind: "sign", code, signer (the Agent ID address), wallet, binding, deadline, digest (the contract's own hash, to check the signature against), summary, and typed_data (domain Zebra Binding / 1 / 56 / binding contract, primaryType Bind or Unbind; ready for eth_signTypedData_v4).

GET /api/tx/:code ​

The Agent fetches either of the above with the code (verbatim, typed_data keys in field order). Once only: again returns 410 (CodeUsed); expired returns 410 (CodeExpired); unknown returns 404.

Error codes ​

Contracts revert with error codes, which an Agent's preview may show only as hex.

EndpointMeaning
GET /api/decode?data=0x…turns revert data (or a whole error message containing it) into words: code, selector, text (Chinese)
GET /api/errorsevery error code with its 4-byte selector and text

Zebra DAO ​

GET /api/dao ​

Total income (launch_fees, exit_fees, swept), recent flows, and the multisig safe: address, live BNB balance (bnb_wei), signers (owners) and threshold.

totals: tax commission (commission_bnb), donations (donations_bnb, donations count including token gifts), spending (spent_bnb, split into token buys spent_buy_bnb and other spent_other_bnb), airdrop_batches, airdrop_people.

ledger: the multisig's inflows and outflows, newest first. Each entry has dir (in / out), kind, time, tx, n (transfers) and amounts:

kindMeaning
launch_fee · exit_fee · sweeplaunch fees, exit fees (merged per round and day), swept dust
tax_commissionFlap's tax commission from a tax token (symbol = the source token; paid in a pool token it carries token_symbol and decimals)
donationBNB sent straight to the multisig
token_intokens sent to the multisig (token_symbol, decimals)
buy · spendBNB sent by the multisig: to Flap or PancakeSwap counts as a token buy, anything else as spending (each MultiSend entry counted)
airdrop · token_outtokens sent by the multisig, one entry per transaction (tokens lists each token); entries matched to an airdrop batch carry batch_id and batch_name

GET /api/airdrops ​

Published airdrop batches (sending, done, cancelled), newest first. Each has id, name, note, rule (all_ids / launches / custom), tokens (per token: token, symbol, decimals, total_wei, sent_wei), recipients, sent (people fully paid), transfers, transfers_sent, status (active / done / cancelled), created_at, published_at, done_at, snapshot_block.

GET /api/airdrops/:id ​

One batch and its recipients, paged. Params: page, size (max 500), q (address or name prefix), status (pending still owed something / sent fully paid). Each recipient has address, handle, status (pending / partial / sent) and items (one per token: pos, amount_wei, status, tx_hash, sent_at).

GET /api/airdrops/:id/csv ​

The full list as CSV, one row per recipient and token, with delivery status.

Flap parameters ​

GET /api/flap ​

The zebra field holds the factory's current settings for new rounds: factory, binding, fee_bps, min_target / max_target (raise range, wei), min_per_id_floor, official_vaults_only, twap_window, paused, and templates (each with id, name, impl, status, ready_at; active ones carry creation_cost, what creating a round costs).

The rest are Flap's current parameters read from chain: Portal version, trading fee (bps), BNB curve (r, h, k, graduation reserve), and enabled pools with their average-price routes. A pool is enabled when Flap allows BNB swaps into it and every pool on its route keeps a full 1,800 observations of price history (oracle_ready); otherwise the factory refuses new rounds on it.

GET /api/flap/estimate?progress=58&pool=BNB ​

Estimate the raise needed to reach a curve progress after launch, on the BNB curve. progress is in (0, 100]; non-BNB pools include 20% headroom at 100%.

Logo upload ​

POST /api/meta ​

Used when creating a launch: uploads the token logo and its details to Flap, pinned on IPFS, and returns a cid. That cid is the token's meta field, which Flap and zebra.pub both read the logo and links from. Browsers can't call Flap's upload endpoint directly because of cross-origin rules, so our backend forwards it.

The request is multipart/form-data:

FieldRequiredNotes
imageyesLogo: PNG, JPEG, WebP, SVG or GIF, up to 3 MB (same as Flap); square, 512×512 or more, is best
descriptionnoToken description, up to 256 characters (same as Flap)
websitenoWebsite link
twitternoX link
telegramnoTelegram link

Success returns 200:

json
{ "cid": "bafkreictuhft3yl5icnswbh52nhth3sjjcgrk7d4qnxglhuqehwgfznw3q" }

The cid points to a JSON document (description, website, twitter, telegram, image, …) whose image is the picture's own CID. You can view it through Flap's gateway, e.g. https://flap.mypinata.cloud/ipfs/<cid>.

StatusMeaning
400No image, image over 3 MB or not a supported format, description over 256 characters, or a malformed form
429Rate limited (30 per minute per IP, shared with /api/flap*)
502Flap's upload failed or returned no cid (the body's detail carries Flap's error)

Example:

bash
curl -X POST https://api.zebra.pub/api/meta \
  -F "image=@logo.png;type=image/png" \
  -F "description=One-line pitch" \
  -F "website=https://example.com" \
  -F "twitter=https://x.com/example"

Uploads are public and permanent on IPFS and can't be deleted, so only upload the material meant for the token.

Other ​

The admin endpoints under /api/admin/* are for DAO multisig signers only (wallet sign-in) and aren't listed here.

Agent ID ​

EndpointNotes
GET /api/statsTotal Agent IDs and growth
GET /api/name/:handleLook up by name (without .ai)
GET /api/address/:addrLook up by address
GET /api/search?q=Name prefix search, up to 20
GET /api/recent?limit=Latest registrations, default 50, max 200
GET /api/timeline?bucket=3600&hours=72Registrations over time
GET /api/vanityThree-character names, lucky-number names, earliest names
GET /api/healthService status and cache stats