Normies API

On-Chain Normies Data for Builders

The Normies API provides programmatic access to on-chain Normies NFT data. Retrieve pixel data, traits, images, and metadata for any minted Normie.

All data is sourced directly from the Ethereum mainnet smart contracts. Token IDs range from 0 to 9999. See also: /llms.txt for LLM-friendly documentation.

Endpoints

Canvas Support: The /normie/:id/pixels, /normie/:id/image.svg, /normie/:id/image.png, and /normie/:id/metadata endpoints now return composited (customized) data when a Normie has been edited via NormiesCanvas. Use the /normie/:id/original/* endpoints to access pre-transform data.
GET /normie/:id/pixels text/plain

Returns the 40x40 monochrome bitmap as a 1600-character binary string of 0s and 1s. Row-major order, top-left to bottom-right. 1 = pixel on (#48494b), 0 = pixel off (#e3e5e4 background). If the Normie has been customized, returns the composited (original XOR transform) bitmap.

curl https://your-api-domain.com/normie/0/pixels

# Response: 1600 characters
# 0000000000000000000000000000000000000000
# 0000000001111111111111100000000000000000
# ...
GET /normie/:id/traits/binary text/plain

Returns the raw bytes8 trait data as a hex string. Each byte is an index into a trait category (8 categories total).

curl https://your-api-domain.com/normie/0/traits/binary

# Response: 0x0001000305010200
GET /normie/:id/traits application/json

Returns decoded traits as a JSON object with human-readable labels.

curl https://your-api-domain.com/normie/0/traits

# Response:
{
  "raw": "0x0001000305010200",
  "attributes": [
    { "trait_type": "Type", "value": "Human" },
    { "trait_type": "Gender", "value": "Female" },
    { "trait_type": "Age", "value": "Young" },
    { "trait_type": "Hair Style", "value": "Straight Hair" },
    { "trait_type": "Facial Feature", "value": "Shadow Beard" },
    { "trait_type": "Eyes", "value": "Big Shades" },
    { "trait_type": "Expression", "value": "Serious" },
    { "trait_type": "Accessory", "value": "Top Hat" }
  ]
}
GET /normie/:id/image.svg image/svg+xml

Returns the Normie image as an SVG. 1000x1000 output with a 40x40 viewBox. Matches the on-chain renderer output exactly (RLE row-scan optimization). If customized, returns the composited image.

curl https://your-api-domain.com/normie/0/image.svg -o normie.svg

# Or use directly in HTML:
# <img src="https://your-api-domain.com/normie/0/image.svg" />
GET /normie/:id/image.png image/png

Returns the Normie image as a 1000x1000 PNG. Rasterized from the SVG with pixel-perfect rendering. If customized, returns the composited image.

curl https://your-api-domain.com/normie/0/image.png -o normie.png
GET /normie/:id/metadata application/json

Returns the full NFT metadata JSON, matching the on-chain tokenURI() output (V4 renderer). Includes name, attributes (with canvas-aware Level, Action Points, Customized), SVG image, and animation URL. If customized, uses the composited image.

curl https://your-api-domain.com/normie/0/metadata

# Response:
{
  "name": "Normie #0",
  "attributes": [
    { "trait_type": "Type", "value": "Human" },
    ...
    { "display_type": "number", "trait_type": "Level", "value": 1 },
    { "display_type": "number", "trait_type": "Pixel Count", "value": 527 },
    { "display_type": "number", "trait_type": "Action Points", "value": 0 },
    { "trait_type": "Customized", "value": "No" }
  ],
  "image": "data:image/svg+xml;base64,...",
  "animation_url": "data:text/html;base64,..."
}

Original Endpoints (Pre-Transform)

These endpoints always return the original Normie data, ignoring any Canvas customizations.

GET /normie/:id/original/pixels text/plain

Returns the original 40x40 bitmap as a 1600-character binary string, before any Canvas edits.

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

Returns the original Normie SVG image, before any Canvas edits.

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

Returns the original Normie PNG image, before any Canvas edits.

Canvas Endpoints

These endpoints expose NormiesCanvas data: transform layers, pixel diffs, action points, delegations, and contract status.

GET /normie/:id/canvas/pixels text/plain

Returns the transform layer (XOR overlay) as a 1600-character binary string. Each 1 represents a pixel that was flipped by the Canvas edit. Returns all 0s if the Normie has not been customized.

GET /normie/:id/canvas/diff application/json

Returns a pixel-level diff between the original and the Canvas edits. Lists which pixels were added (turned on) and removed (turned off).

curl https://your-api-domain.com/normie/42/canvas/diff

# Response:
{
  "added": [{ "x": 10, "y": 5 }, { "x": 11, "y": 5 }],
  "removed": [{ "x": 20, "y": 15 }],
  "addedCount": 2,
  "removedCount": 1,
  "netChange": 1
}
GET /normie/:id/canvas/info application/json

Returns Canvas metadata for a Normie: action points, level, customization status, and delegate info.

curl https://your-api-domain.com/normie/42/canvas/info

# Response:
{
  "actionPoints": 25,
  "level": 3,
  "customized": true,
  "delegate": "0x0000000000000000000000000000000000000000",
  "delegateSetBy": "0x0000000000000000000000000000000000000000"
}
GET /canvas/status application/json

Returns the global NormiesCanvas contract status: paused state and burn tier configuration.

curl https://your-api-domain.com/canvas/status

# Response:
{
  "paused": false,
  "maxBurnPercent": 4,
  "tierThresholds": [490, 890],
  "tierMinPercents": [1, 2, 3]
}

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 = 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
WindowSliding 60 seconds

Rate limit headers are included in every response:

Errors

StatusMeaning
400Invalid token ID (must be integer 0-9999)
404Token not found or data not set on-chain
429Rate limit exceeded
500Internal server error

Error responses are JSON:

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

Smart Contracts (Ethereum Mainnet)

ContractAddressDescription
Normies 0x9Eb6E2025B64f340691e424b7fe7022fFDE12438 Core ERC721C token with ERC-2981 royalties
NormiesStorage 0x1B976bAf51cF51F0e369C070d47FBc47A706e602 SSTORE2 bitmap & trait storage with XOR encryption
NormiesRenderer 0xBe57fC4D0c729b8e8d33b638Dd441F57365e4c25 V1 — Animated noise pre-reveal, static SVG post-reveal
NormiesRendererV2 0x7818f24d3239c945510e0a1a523dd9971812c6c0 V2 — Static noise pre-reveal
NormiesRendererV3 0x1af01b902256d77cf9499a14ef4e494897380b05 V3 — RLE-optimized SVG, Pixel Count trait, canvas animation_url
NormiesMinter 0xC74994dD70FFb621CC514cE18a4F6F52124e296d V1 — EIP-191 signature-verified minting
NormiesMinterV2 0xc513272597d3022D77b3d7EEBA92cea5D7fb2808 V2 — Adds delegate.xyz v1/v2 cold wallet delegation
NormiesCanvas 0x64951d92e345C50381267380e2975f66810E869c Burn-to-edit orchestrator: commit-reveal burns, action points, pixel transforms
NormiesCanvasStorage 0xC255BE0983776BAB027a156681b6925cde47B2D1 SSTORE2 storage for transform layer bitmaps (plaintext, no XOR)
NormiesRendererV4 0x8eC46Cc1f306652868a4dfbAAae87CBa2715A0eB V4 — Canvas-aware renderer with composited SVG & extra traits