Normies API

On-Chain Normies Data for Builders

The Normies API provides programmatic access to on-chain Normies NFT data, active rendering, Canvas history, Zombies, ERC-8004 agents, Legendary Canvas, and rarity data.

Base URL: https://api.normies.art. Token IDs range from 0 to 9999. Most mutable data is served from the Ponder indexer to avoid per-request RPC reads. See also: /llms.txt for LLM-friendly documentation.

Endpoints

Active Rendering: The active /normie/:id/* endpoints apply current zombie and Canvas state. Zombie-converted tokens use zombie art and attributes; Canvas-edited tokens use active base art XOR transform. Use /normie/:id/original/* for original mint data.

Core

GET/text/html

Human-readable API documentation.

Cache: none

GET/llms.txttext/plain

Markdown-style documentation intended for LLM and tool ingestion.

Cache: none

GET/healthapplication/json

Health check returning { "status": "ok" }.

Cache: none

Normie Token Data

GET/normie/all/originalapplication/json

Bulk original mint dump with token ID, raw image data, decoded traits, pixel count, block number, timestamp, and transaction hash.

Cache: public, max-age=60, s-maxage=300

curl https://your-api-domain.com/normie/all/original
GET/normie/all/original/dataapplication/json

Alias-style bulk original mint dump with the same token rows.

Cache: public, max-age=300, s-maxage=3600

GET/normie/all/original/traitsapplication/json

Decoded original traits for all indexed tokens.

Cache: public, max-age=300, s-maxage=3600

GET/normie/all/original/traits/binaryapplication/json

Raw original bytes8 trait hex for all indexed tokens.

Cache: public, max-age=300, s-maxage=3600

GET/normie/all/original/pixelsapplication/json

Original raw image data and pixel counts for all indexed tokens.

Cache: public, max-age=300, s-maxage=3600

GET/normie/all/original/canvasapplication/json

Canvas-oriented alias for original bitmap rows.

Cache: public, max-age=300, s-maxage=3600

GET/normie/:id/ownerapplication/json

Current indexed owner for a token. Returns upstream 404 if burned or not indexed.

Parameters: id 0-9999. Cache: public, max-age=10, s-maxage=10

GET/normie/:id/pixelstext/plain

Returns the active 40x40 bitmap as a 1600-character binary string. Zombie art and Canvas transforms are applied when present.

Parameters: id 0-9999. Cache: public, max-age=60, s-maxage=300

curl https://your-api-domain.com/normie/0/pixels
GET/normie/:id/traits/binarytext/plain

Returns the raw original mint bytes8 trait data as a hex string.

Parameters: id 0-9999. Cache: public, max-age=300, s-maxage=3600

GET/normie/:id/traitsapplication/json

Returns decoded original mint traits as human-readable attributes.

Parameters: id 0-9999. Cache: public, max-age=300, s-maxage=3600

GET/normie/:id/image.svgimage/svg+xml

Returns the active SVG image. Zombie art and Canvas transforms are applied when present.

Parameters: id 0-9999. Cache: public, max-age=60, s-maxage=300

curl https://your-api-domain.com/normie/0/image.svg -o normie.svg
GET/normie/:id/image.pngimage/png

Returns the active 1000x1000 PNG image rendered from the active SVG.

Parameters: id 0-9999. Cache: public, max-age=60, s-maxage=300

GET/normie/:id/metadataapplication/json

Returns active NFT metadata including Level, Pixel Count, Action Points, Customized, zombie attributes when converted, and Legendary Canvas artist when set.

Parameters: id 0-9999. Cache: public, max-age=60, s-maxage=300

GET/normie/:id/legendary-canvasapplication/json

Legendary Canvas state for a token.

Parameters: id 0-9999. Cache: public, max-age=60, s-maxage=300

GET/normie/:id/original/pixelstext/plain

Original mint bitmap as a 1600-character binary string, ignoring zombie and Canvas state.

Parameters: id 0-9999. Cache: public, max-age=300, s-maxage=3600

GET/normie/:id/original/image.svgimage/svg+xml

Original mint SVG, ignoring zombie and Canvas state.

Parameters: id 0-9999. Cache: public, max-age=300, s-maxage=3600

GET/normie/:id/original/image.pngimage/png

Original mint PNG, ignoring zombie and Canvas state.

Parameters: id 0-9999. Cache: public, max-age=300, s-maxage=3600

Canvas

GET/canvas/statusapplication/json

Global Canvas contract status: paused state, max burn percent, tier thresholds, and tier minimum percents.

Cache: public, max-age=300, s-maxage=300

GET/normie/:id/canvas/pixelstext/plain

Canvas transform bitmap as a 1600-character string.

Parameters: id 0-9999. Cache: public, max-age=60, s-maxage=300

GET/normie/:id/canvas/diffapplication/json

Pixel diff between active base art and Canvas transform: added, removed, and net change.

Parameters: id 0-9999. Cache: public, max-age=60, s-maxage=300

GET/normie/:id/canvas/infoapplication/json

Canvas level, action points, customized flag, delegate, and delegate setter.

Parameters: id 0-9999. Cache: public, max-age=60, s-maxage=60

History

GET/history/burnsapplication/json

Paginated Canvas burn commitments.

Query: limit 1-100, offset. Cache: public, max-age=60, s-maxage=300

GET/history/burns/:commitIdapplication/json

One burn commitment plus its burned token details.

Parameters: commitId. Cache: public, max-age=60, s-maxage=300

GET/history/burns/address/:addressapplication/json

Burn commitments created by a wallet.

Parameters: Ethereum address. Query: limit, offset. Cache: public, max-age=60, s-maxage=300

GET/history/burns/receiver/:tokenIdapplication/json

Burn commitments that transferred action points to a receiver token.

Parameters: tokenId. Query: limit, offset. Cache: public, max-age=60, s-maxage=300

GET/history/burned-tokensapplication/json

Paginated list of burned token records.

Query: limit, offset. Cache: public, max-age=60, s-maxage=300

GET/history/burned/:tokenIdapplication/json

Burn record for a token.

Parameters: tokenId 0-9999. Cache: public, max-age=60, s-maxage=300

GET/history/burned/:tokenId/image.svgimage/svg+xml

Original SVG for a burned token.

Parameters: tokenId 0-9999. Cache: public, max-age=60, s-maxage=300

GET/history/burned/:tokenId/image.pngimage/png

Original PNG for a burned token.

Parameters: tokenId 0-9999. Cache: public, max-age=60, s-maxage=300

GET/history/customizedapplication/json

Canvas transform event sync feed. Returns events, unique token IDs, count, pagination flag, and requested timestamp cursor.

Query: limit, offset, after_timestamp or since_timestamp, sort=asc|desc. Cache: public, max-age=60, s-maxage=300

GET/history/normie/:id/versionsapplication/json

Transform versions for a token with change count, new pixel count, transformer, block, timestamp, and transaction hash.

Parameters: id 0-9999. Query: limit, offset. Cache: public, max-age=60, s-maxage=300

GET/history/normie/:id/version/:version/pixelstext/plain

Historical composited pixel string for a transform version.

Parameters: id, zero-based version. Cache: public, max-age=60, s-maxage=300

GET/history/normie/:id/version/:version/image.svgimage/svg+xml

Historical composited SVG for a transform version.

Parameters: id, zero-based version. Cache: public, max-age=60, s-maxage=300

GET/history/normie/:id/version/:version/image.pngimage/png

Historical composited PNG for a transform version.

Parameters: id, zero-based version. Cache: public, max-age=60, s-maxage=300

GET/history/statsapplication/json

Indexer summary counts for burn commitments, burned tokens, transforms, token data, zombies, Legendary Canvas, and total action points.

Cache: public, max-age=60, s-maxage=300

Holders

GET/holders/:addressapplication/json

Current indexed token IDs held by a wallet.

Parameters: Ethereum address. Cache: public, max-age=10, s-maxage=10

Zombies

GET/zombies/statusapplication/json

Zombie contract status and pool configuration.

Cache: public, max-age=60, s-maxage=300

GET/zombies/conversionsapplication/json

Paginated zombie conversion commitments and reveal state.

Query: limit, offset. Cache: public, max-age=60, s-maxage=300

GET/zombies/wallet/:addressapplication/json

Zombie conversions for a qualifying wallet.

Parameters: Ethereum address. Query: limit, offset. Cache: public, max-age=60, s-maxage=300

GET/zombies/token/:idapplication/json

Zombie info plus conversion history for a token.

Parameters: id 0-9999. Cache: public, max-age=60, s-maxage=300

GET/zombies/token/:id/attributesapplication/json

Zombie attributes for a token.

Parameters: id 0-9999. Cache: public, max-age=60, s-maxage=300

GET/zombies/token/:id/pixelstext/plain

Zombie bitmap as a 1600-character string.

Parameters: id 0-9999. Cache: public, max-age=60, s-maxage=300

GET/zombies/token/:id/image.svgimage/svg+xml

Zombie SVG image.

Parameters: id 0-9999. Cache: public, max-age=60, s-maxage=300

GET/zombies/token/:id/image.pngimage/png

Zombie PNG image.

Parameters: id 0-9999. Cache: public, max-age=60, s-maxage=300

Legendary Canvas

GET/legendary-canvasapplication/json

Paginated list of tokens marked with the Legendary Canvas artist trait.

Query: limit, offset. Cache: public, max-age=60, s-maxage=300

GET/legendary-canvas/token/:idapplication/json

Legendary Canvas state for a single token.

Parameters: id 0-9999. Cache: public, max-age=60, s-maxage=300

ERC-8004 Agents

GET/agents/metadata/:tokenIdapplication/json

ERC-8004 metadata JSON served as the on-chain agent URI.

Parameters: tokenId 0-9999. Cache: public, max-age=60, s-maxage=120, stale-while-revalidate=300

GET/agents/persona-preview/:tokenIdapplication/json

Persona JSON for any token, whether or not it is registered as an agent.

Parameters: tokenId 0-9999. Cache: public, max-age=30, s-maxage=60, stale-while-revalidate=300

GET/agents/identity/:tokenIdapplication/json

Trait-derived agent name, type, and raw trait map.

Parameters: tokenId 0-9999. Cache: public, max-age=300, s-maxage=600, stale-while-revalidate=3600

GET/agents/info/:tokenIdapplication/json

Registered-agent persona, traits, live Canvas state, registration metadata, and placeholder interaction/MCP status.

Parameters: tokenId 0-9999. Cache: public, max-age=30, s-maxage=60, stale-while-revalidate=300

GET/agents/by-agent-id/:agentId/infoapplication/json

Reverse lookup by ERC-8004 agent ID, returning the same shape as /agents/info/:tokenId.

Parameters: agentId integer string. Cache: public, max-age=30, s-maxage=60, stale-while-revalidate=300

GET/agents/listapplication/json

Paginated registered-agent gallery feed enriched with identity.

Query: limit 1-100, sort=newest|oldest, optional cursor agent ID. Cache: public, max-age=30, s-maxage=60, stale-while-revalidate=300

GET/agents/searchapplication/json

Search registered agents by name, token ID, or agent ID.

Query: q, limit 1-50. Cache when q is present: public, max-age=15, s-maxage=30, stale-while-revalidate=120; empty q: none.

GET/agents/countapplication/json

Total registered Normies agents.

Cache: public, max-age=30, s-maxage=60, stale-while-revalidate=300

GET/agents/agent-card/:tokenIdapplication/json

A2A v0.3.0 Agent Card JSON linked from ERC-8004 metadata.

Parameters: tokenId 0-9999. Cache: public, max-age=60, s-maxage=120, stale-while-revalidate=300

GET/agents/image/:tokenIdimage/svg+xml

Composited SVG image for an agent.

Parameters: tokenId 0-9999. Cache: public, max-age=60, s-maxage=60, stale-while-revalidate=300

GET/agents/binding/:tokenIdapplication/json

Normies-only ERC-8004 binding lookup for one token.

Parameters: tokenId 0-9999. Cache: public, max-age=30, s-maxage=60, stale-while-revalidate=300

POST/agents/binding/batchapplication/json

Batch ERC-8004 binding lookup. Body: { "tokenIds": [...] }.

Cache: public, max-age=30, s-maxage=60

GET/agents/by-agent-id/:agentIdapplication/json

Reverse lookup returning the raw binding for an agent ID.

Parameters: agentId integer string. Cache: public, max-age=60, s-maxage=300

Rarity

These routes power rarity.normies.art. They are backed by a bulk Ponder snapshot plus short API-server caches. Historical routes recompute ownership, burn counts, traits, and ranks at an Ethereum block number from indexed event state; marketplace listings are current-only and omitted from historical responses.
GET/rarity/docsapplication/json

Small JSON list of rarity endpoints.

Cache: public, max-age=15, s-maxage=30, stale-while-revalidate=120

GET/rarity/statsapplication/json

Live rarity stats: indexed count, live supply, burned count, weights, listing count, floor price, and awakened-agent count.

Cache: public, max-age=15, s-maxage=30, stale-while-revalidate=120

GET/rarity/normiesapplication/json

Paginated live rarity list with rank, score, attributes, listing data, fair value, underpriced flag, burn count, and awakened-agent metadata.

Query: page, limit 1-100, sort=rank|id|score|level|action_points|pixel_count|price|awake_registered, order=asc|desc, search, listed=1, underpriced=1, the100=1, awake=1, px_tier=low,mid,high, wallet_ids, trait_* filters. Cache: public, max-age=15, s-maxage=30, stale-while-revalidate=120

GET/rarity/normie/:idapplication/json

Full live rarity detail for one token. Returns 410 if burned.

Parameters: id 0-9999. Cache: public, max-age=15, s-maxage=30, stale-while-revalidate=120

POST/rarity/normie/:id/refreshapplication/json

Forces the live rarity collection cache to reload, then returns the same detail shape as /rarity/normie/:id.

Parameters: id 0-9999. Cache: public, max-age=15, s-maxage=30, stale-while-revalidate=120

GET/rarity/normie/:id/personaapplication/json

Awakened-agent persona fields used by the rarity modal. Returns 404 if the token is not an agent.

Parameters: id 0-9999. Cache: public, max-age=15, s-maxage=30, stale-while-revalidate=120

GET/rarity/traitsapplication/json

Trait filter counts over live, non-burned tokens.

Cache: public, max-age=15, s-maxage=30, stale-while-revalidate=120

GET/rarity/holder/:addressapplication/json

Current indexed rarity holdings for a wallet. ENS names are accepted and resolved at request time.

Parameters: Ethereum address or ENS name. Cache: public, max-age=15, s-maxage=30, stale-while-revalidate=120

GET/rarity/recursive-burn-holdersapplication/json

Leaderboard of current wallets by recursive burn count of held customized tokens.

Query: limit 1-200, optional wallet. Cache: public, max-age=15, s-maxage=30, stale-while-revalidate=120

GET/rarity/historical/:blockNumber/statsapplication/json

Rarity stats recomputed at an Ethereum block number. Listings and floor price are omitted.

Parameters: blockNumber. Cache: public, max-age=15, s-maxage=30, stale-while-revalidate=120

GET/rarity/historical/:blockNumber/normiesapplication/json

Paginated rarity list at a block number. Supports the same non-marketplace filters and sort modes as the live list.

Parameters: blockNumber. Query: live list query parameters except listing-dependent filters have no matches. Cache: public, max-age=15, s-maxage=30, stale-while-revalidate=120

GET/rarity/historical/:blockNumber/normie/:idapplication/json

Full rarity detail for one token at a block number. Returns 410 if burned at that block and 404 if not indexed yet.

Parameters: blockNumber, id 0-9999. Cache: public, max-age=15, s-maxage=30, stale-while-revalidate=120

GET/rarity/historical/:blockNumber/traitsapplication/json

Trait filter counts over live, non-burned tokens at a block number.

Parameters: blockNumber. Cache: public, max-age=15, s-maxage=30, stale-while-revalidate=120

GET/rarity/historical/:blockNumber/holder/:addressapplication/json

Indexed wallet holdings at a block number. ENS names are accepted but resolved at request time.

Parameters: blockNumber, address or ENS name. Cache: public, max-age=15, s-maxage=30, stale-while-revalidate=120

GET/rarity/historical/:blockNumber/recursive-burn-holdersapplication/json

Leaderboard of wallets by recursive burn count of held customized tokens at a block number.

Parameters: blockNumber. Query: limit 1-200, optional wallet. Cache: public, max-age=15, s-maxage=30, stale-while-revalidate=120

GET/rarity/listings/streamtext/event-stream

Server-Sent Events for listing changes: listed, sold, and cancelled.

Cache: no-store

GET/rarity/legendaryapplication/json

Rarity-app Legendary Canvas curation config with current and upcoming arrays, loaded from the indexer database.

Cache: public, max-age=15, s-maxage=30, stale-while-revalidate=120

PUT/rarity/admin/legendaryapplication/json

Admin-only save for Legendary Canvas curation config into the indexer database.

Requires x-admin-key. Body: { "current": [...], "upcoming": [...] }. Cache: no-store

Cache Policy

Every public endpoint above lists the Cache-Control header this server sets. none means the API server does not set an explicit cache header for that endpoint.

Route familyPublic cache headerNotes
/rarity/*public, max-age=15, s-maxage=30, stale-while-revalidate=120Except admin routes and listing stream.
/rarity/admin/*, /rarity/listings/streamno-storeThe SSE route also emits event-stream headers.
/canvas/statuspublic, max-age=300, s-maxage=300Derived from CANVAS_STATUS_CACHE_TTL_MS.
/zombies/statuspublic, max-age=10, s-maxage=10Derived from ZOMBIE_STATUS_CACHE_TTL_MS.
* /canvas/infopublic, max-age=60, s-maxage=60Derived from CANVAS_INFO_CACHE_TTL_MS.
Owner and holder routespublic, max-age=10, s-maxage=10/normie/:id/owner and /holders/:address.
Original data and traits routespublic, max-age=300, s-maxage=3600Immutable mint data.
/history/*public, max-age=60, s-maxage=300Indexed append-only history and version rendering.
Default rendered/indexed routespublic, max-age=60, s-maxage=300Active images, metadata, zombie aliases, Legendary Canvas, and uncategorized cached routes.
/agents/*Varies by endpointAgent routes set explicit cache headers per endpoint.
/favicon.png, /favicon.icopublic, max-age=86400Static icon.

Server-Side Cache Defaults

SettingDefaultUsed for
CACHE_TTL_MS3600000 ms / 3600 sBulk token dump cache and positive agent binding cache.
CANVAS_CACHE_TTL_MS60000 ms / 60 sCanvas transform and transformed-state caches.
CANVAS_INFO_CACHE_TTL_MS60000 ms / 60 sCanvas info cache, agent response cache, and negative agent binding TTL.
CANVAS_STATUS_CACHE_TTL_MS300000 ms / 300 sCanvas global status cache.
ZOMBIE_CACHE_TTL_MS60000 ms / 60 sZombie token info and bitmap caches.
ZOMBIE_STATUS_CACHE_TTL_MS10000 ms / 10 sZombie status response cache.
LEGENDARY_CANVAS_CACHE_TTL_MS60000 ms / 60 sLegendary Canvas token info cache.
RARITY_CACHE_TTL_MS60000 ms / 60 sLive and historical rarity collection snapshots; historical cache keeps up to 32 block snapshots.
RARITY_LISTINGS_REFRESH_MS60000 ms / 60 sOpenSea listing poll interval for rarity listings.
transformHistoryCache30000 ms / 30 sPer-token transform history in memory.
Immutable token cachesNo TTLOriginal image data, raw traits, and decoded traits are cached in-process because mint data is immutable.

Trait Categories

CategoryByte IndexPossible Values
Type0Human, Cat, Alien, Agent
Gender1Male, Female, Non-Binary
Age2Young, Middle-Aged, Old
Hair Style321 options (Short Hair, Long Hair, Curly Hair, ...)
Facial Feature417 options (Full Beard, Mustache, Goatee, ...)
Eyes514 options (Classic Shades, Big Shades, ...)
Expression67 options (Neutral, Slight Smile, Serious, ...)
Accessory715 options (Top Hat, Fedora, Cowboy Hat, ...)

Pixel Data Format

Each Normie is a 40x40 monochrome bitmap stored as 200 bytes on-chain: 1 bit per pixel, MSB first.

PropertyValue
Grid Size40 x 40 pixels
Bit OrderMSB first; most significant bit is the leftmost pixel
LayoutRow-major, top-left to bottom-right
Pixel On1 - dark gray (#48494b)
Pixel Off0 - light gray (#e3e5e4)
Storage Size200 bytes / 1600 bits

Pixel Access Formula

flatIndex = y * 40 + x
byteIndex = flatIndex >> 3        // divide by 8
bitPos    = 7 - (flatIndex & 7)   // MSB first
pixel     = (data[byteIndex] >> bitPos) & 1

Rate Limiting

Requests are rate-limited per IP address using a sliding window.

LimitValue
Requests60 per minute by default
WindowSliding 60 seconds

Rate limit headers are included in responses:

Errors

StatusMeaning
400Invalid token, address, query, or body
401Invalid admin key
403Admin disabled
404Not found, not indexed, or data not set on-chain
410Burned token on rarity detail
429Rate limit exceeded
500Internal server error
502Upstream indexer, RPC, or provider failure

Error responses are JSON:

{ "error": "Invalid token ID: \"abc\". Must be an integer 0-9999." }

Smart Contracts (Ethereum Mainnet)

ContractAddressDescription
Normies0x9Eb6E2025B64f340691e424b7fe7022fFDE12438Core ERC721C token with ERC-2981 royalties
NormiesStorage0x1B976bAf51cF51F0e369C070d47FBc47A706e602SSTORE2 bitmap and trait storage with XOR encryption
NormiesRenderer0xBe57fC4D0c729b8e8d33b638Dd441F57365e4c25V1 renderer: animated noise pre-reveal, static SVG post-reveal
NormiesRendererV20x7818f24d3239c945510e0a1a523dd9971812c6c0V2 renderer: static noise pre-reveal
NormiesRendererV30x1af01b902256d77cf9499a14ef4e494897380b05V3 renderer: RLE-optimized SVG, Pixel Count trait, canvas animation URL
NormiesMinter0xC74994dD70FFb621CC514cE18a4F6F52124e296dV1 EIP-191 signature-verified minting
NormiesMinterV20xc513272597d3022D77b3d7EEBA92cea5D7fb2808V2 minting with delegate.xyz v1/v2 cold wallet delegation
NormiesCanvas0x64951d92e345C50381267380e2975f66810E869cBurn-to-edit orchestrator: commit-reveal burns, action points, and pixel transforms
NormiesCanvasStorage0xC255BE0983776BAB027a156681b6925cde47B2D1SSTORE2 storage for transform layer bitmaps
NormiesRendererV40x8eC46Cc1f306652868a4dfbAAae87CBa2715A0eBV4 Canvas-aware renderer with composited SVG and extra traits
NormiesZombie0x18533ad55a54c3847Da06A48b51aD7DcB2551202Merkle-gated commit-reveal converter that turns eligible Normies into bespoke Zombies
NormiesZombieStorage0xA331bD22C90D1DA096934Db8bc6b69F0e1491E26SSTORE2 storage for zombie pool assets and conversion records
NormiesLegendaryCanvas0xfA55f6592522dA74224a67c7D3Fd1DF759c628e8Owner-managed registry of selected Legendary Canvas artist traits
NormiesRendererV50x7c726f02C5e840e1656b522A5C22caaf87C1C35CV5 renderer: V4-compatible renderer with zombie metadata and art branches