# CryptoPunks API Documentation This file provides API specifications for cryptopunks.app, a website for exploring CryptoPunks NFT data, traits, bids, images, and market information. ## Base URL https://cryptopunks.app ## API Endpoints ### Punk Data #### Get Individual Punk GET /api/punks/{punkIndex} - Description: Get basic information about a specific punk by index (0-9999) - Parameters: - punkIndex (path): Integer between 0 and 9999 - Response: JSON object with punk data including owner, assigned status, sale/bid information - Example Response: ```json { "success": true, "data": { "id": "1234", "index": 1234, "ownerAddress": "0x2c81cee7050c9d03295560851ffde123bdf9696a", "isForSale": false, "hasBid": false, "attributes": [], "attributeCount": 0, "type": "MALE", "wrapped": false, "typeName": "Male", "isHuman": true, "typeCount": 6039, "attributeCountTotal": 8, "isForSaleToAnyone": false, "isWrappedLegacy": false, "isWrappedNewContract": false, "wrappedBackgroundColor": "#00FF00", "openSeaUrl": null, "createdAt": "2026-01-20T15:33:20.268Z", "updatedAt": "2026-01-20T15:33:20.268Z" } } ``` #### Get Punk Details GET /api/punks/{punkIndex}/details - Description: Get detailed information about a specific punk including transaction history - Parameters: - punkIndex (path): Integer between 0 and 9999 - includeHistory (query, optional): Boolean, set to "true" to include transaction history - Response: JSON object with comprehensive punk data including metadata, owner, offers, bids, and optional transaction history - Example Response: ```json { "success": true, "data": { "id": "1234", "index": 1234, "ownerAddress": "0x2c81cee7050c9d03295560851ffde123bdf9696a", "assigned": true, "isForSale": true, "sellerAddress": "0x1111111111111111111111111111111111111111", "offerValue": "150000000000000000", "onlySellToAddress": null, "hasBid": true, "bidderAddress": "0x2222222222222222222222222222222222222222", "bidValue": "140000000000000000", "attributes": ["Beanie", "Small Shades"], "attributeCount": 2, "type": "MALE", "wrapped": false, "transactionHistory": [ { "type": "Sale", "from": { "address": "0x3333333333333333333333333333333333333333", "ens": "seller.eth" }, "to": { "address": "0x2c81cee7050c9d03295560851ffde123bdf9696a", "ens": "buyer.eth" }, "amount": "100000000000000000", "amountUsd": 350000, "timestamp": 1700000000, "transactionHash": "0xaaaa...", "blockPosition": 1 } ], "createdAt": "2021-01-01T00:00:00.000Z", "updatedAt": "2026-01-20T15:33:20.268Z" } } ``` #### Get Punk Metadata GET /api/punks/{punkIndex}/metadata - Description: Get metadata for a specific punk including type and attributes - Parameters: - punkIndex (path): Integer between 0 and 9999 - Response: JSON object with type (Male/Female/Alien/Ape/Zombie), attributes array, and attribute counts - Example Response: ```json { "success": true, "data": { "id": "1234", "index": 1234, "type": "MALE", "typeName": "Male", "isHuman": true, "attributes": ["Beanie", "Small Shades"], "attributeCount": 2, "typeCount": 6039, "attributeCountTotal": 8, "createdAt": "2021-01-01T00:00:00.000Z", "updatedAt": "2026-01-20T15:33:20.268Z" } } ``` #### Get Punk Image GET /api/punks/{punkIndex}/image - Description: Get an upscaled PNG image of a specific punk - Parameters: - punkIndex (path): Integer between 0 and 9999 - transparent (query, optional): Boolean, set to "true" for transparent background - bg (query, optional): Hex color code for background color (default: black) - forSale (query, optional): Boolean, adds for-sale indicator overlay - hasBid (query, optional): Boolean, adds bid indicator overlay - transfer (query, optional): Boolean, adds transfer indicator overlay - Response: PNG image (1024x1024 pixels) - Example Response: ```text Binary PNG image data (1024x1024) Content-Type: image/png ``` ### Traits #### Get Punk Traits GET /api/traits/{punkId} - Description: Get traits (attributes) for a specific punk - Parameters: - punkId (path): Integer between 0 and 9999 - Response: JSON object with punkId, type, and attributes array - Example Response: ```json { "success": true, "data": { "punkId": 1234, "type": "MALE", "typeName": "Male", "attributes": ["Beanie", "Small Shades"], "attributeCount": 2 } } ``` ### Market Data #### Get Punks List (Multiple Actions) GET /api/punks?action={action} - Description: Get various market data and punk lists based on action parameter - Parameters: - action (query): One of the following: - "index": Get homepage data (offered punks, bids, recent sales, top sales, wrapped punks, stats) - "floor": Get current floor price - "floor-punk": Get the punk with the lowest offer price - "offered": Get all punks currently for sale with full details - "offered-ids": Get array of punk IDs that are currently for sale - "bids": Get all punks with active bids - "all-bids": Get all active bids - "wrapped": Get wrapped punks - "wrapped-transfers": Get wrapped punk transfers (requires punkId query param) - "new-wrapped": Get newly wrapped punks - "leaderboard": Get top holders leaderboard - "attributes": Get attribute statistics - "recent-sales": Get recent sales (optional count query param, default 20, max 50) - "top-sales": Get top sales by value - "batch-recent-history": Get recent history for multiple punks (requires punkIds query param as comma-separated or JSON array) - Response: JSON object with success flag and data array/object - Example Response (`action=index`): ```json { "success": true, "data": { "offered": [ { "index": 1234, "offerValue": "150000000000000000", "sellerAddress": "0x1111111111111111111111111111111111111111", "isForSaleToAnyone": true } ], "bids": [ { "index": 4321, "bidValue": "120000000000000000", "bidderAddress": "0x2222222222222222222222222222222222222222" } ], "recentSales": [ { "punkIndex": 5678, "seller": "0x3333333333333333333333333333333333333333", "buyer": "0x4444444444444444444444444444444444444444", "value": "100000000000000000", "timestamp": 1700000000, "transactionHash": "0xbbbb..." } ], "topSales": [], "wrapped": [], "stats": { "floorPriceWei": "50000000000000000", "totalPunks": 10000 } } } ``` #### Get Recent Sales (JSON Format) GET /api/jsonRecentSales?count={count} - Description: Get recent sales in JSON format with current punk status - Parameters: - count (query, optional): Integer, maximum number of sales to return (default: 20, max: 50) - Response: JSON array of sale objects with seller, buyer, value, timestamp, transaction hash, and current punk status - Example Response: ```json [ { "punkIndex": 5678, "seller": "0x3333333333333333333333333333333333333333", "buyer": "0x4444444444444444444444444444444444444444", "value": "100000000000000000", "timestamp": 1700000000, "transactionHash": "0xbbbb...", "currentOwner": "0x4444444444444444444444444444444444444444", "isForSale": false, "hasBid": false } ] ``` #### Get Recent Transactions GET /api/recents - Description: Get recent transactions including sales, bids, offers, and transfers - Authentication: Requires Authorization header (RECENTS_AUTH_HEADER) - Response: JSON object with transactions array and lastUpdate timestamp - Note: Returns up to 5000 most recent transactions - Example Response: ```json { "success": true, "data": { "lastUpdate": "2026-01-20T15:33:20.268Z", "transactions": [ { "type": "Sale", "punkIndex": 5678, "from": "0x3333333333333333333333333333333333333333", "to": "0x4444444444444444444444444444444444444444", "amount": "100000000000000000", "amountUsd": 350000, "timestamp": 1700000000, "transactionHash": "0xbbbb..." } ] } } ``` ### Account Data #### Get Account Information GET /api/account/{address} - Description: Get comprehensive account information including owned punks, sales, purchases, bids, offers, and transfers - Parameters: - address (path): Ethereum address or ENS name - owned (query, optional): Boolean, if true only returns owned punks - salesLimit (query, optional): Integer, max sales to fetch (default: 10000, max: 10000) - purchasesLimit (query, optional): Integer, max purchases to fetch (default: 10000, max: 10000) - offersLimit (query, optional): Integer, max offers to fetch (default: 10000, max: 10000) - bidsLimit (query, optional): Integer, max bids to fetch (default: 10000, max: 10000) - transfersLimit (query, optional): Integer, max transfers to fetch (default: 10000, max: 10000) - wrappedTransfersLimit (query, optional): Integer, max wrapped transfers to fetch (default: 10000, max: 10000) - pageSize (query, optional): Integer, items per page for pagination (default: 100, max: 500) - Response: JSON object with account data including: - ethAddress: Address information with ENS resolution - owned: Array of owned punks with metadata - forSale: Array of punks currently for sale by this account - privateOffers: Array of private offers made to this account - bids: Array of bids placed by this account - bidsForAccount: Array of bids against owned punks - punksBoughtByAddress: Array of purchase history - punksSoldByAddress: Array of sale history - totalValueBoughtByAddress: Total value of purchases - totalValueSoldByAddress: Total value of sales - totalValueOfBidsAgainstThisAccount: Total value of bids on owned punks - totalValueOfBidsPlacedByThisAccount: Total value of bids placed - transactionHistory: Combined transaction history - Example Response: ```json { "success": true, "data": { "ethAddress": { "address": "0x2c81cee7050c9d03295560851ffde123bdf9696a", "ens": "collector.eth" }, "owned": [ { "index": 1234, "type": "MALE", "attributes": ["Beanie", "Small Shades"], "isForSale": false } ], "forSale": [], "privateOffers": [], "bids": [], "bidsForAccount": [], "punksBoughtByAddress": [ { "punkIndex": 1234, "value": "100000000000000000", "timestamp": 1700000000, "transactionHash": "0xbbbb..." } ], "punksSoldByAddress": [], "totalValueBoughtByAddress": "100000000000000000", "totalValueSoldByAddress": "0", "totalValueOfBidsAgainstThisAccount": "0", "totalValueOfBidsPlacedByThisAccount": "0", "transactionHistory": [ { "type": "Sale", "punkIndex": 1234, "from": "0x3333333333333333333333333333333333333333", "to": "0x2c81cee7050c9d03295560851ffde123bdf9696a", "amount": "100000000000000000", "timestamp": 1700000000, "transactionHash": "0xbbbb..." } ] } } ``` ### Transaction History #### Get Punk Transaction History POST /api/punks/{punkIndex}/details - Description: Get full transaction history for a specific punk - Parameters: - punkIndex (path): Integer between 0 and 9999 - Request Body: None (POST method used for longer timeout) - Response: JSON object with transactionHistory array containing: - type: One of "Transfer", "Sale", "Claimed", "Offered", "Offer Withdrawn", "Bid", "Bid Withdrawn", "Wrapped Transfer" - from: Sender address with ENS name - to: Receiver address with ENS name - amount: Transaction amount in wei (for sales/bids/offers) - amountUsd: USD value (for sales/bids/offers) - timestamp: Unix timestamp - transactionHash: Ethereum transaction hash - blockPosition: Block position for sorting - Additional fields vary by transaction type - Example Response: ```json { "success": true, "data": { "punkIndex": 1234, "transactionHistory": [ { "type": "Claimed", "from": null, "to": { "address": "0x1111111111111111111111111111111111111111", "ens": "minter.eth" }, "amount": null, "amountUsd": null, "timestamp": 1500000000, "transactionHash": "0xcccc...", "blockPosition": 0 }, { "type": "Sale", "from": { "address": "0x1111111111111111111111111111111111111111", "ens": "minter.eth" }, "to": { "address": "0x2c81cee7050c9d03295560851ffde123bdf9696a", "ens": "collector.eth" }, "amount": "100000000000000000", "amountUsd": 350000, "timestamp": 1700000000, "transactionHash": "0xbbbb...", "blockPosition": 1 } ] } } ``` ## Collection Bids API The Collection Bids API (bids.cryptopunks.app) manages EIP-712 signed bids on sets of CryptoPunks, Merkle tree operations, and proof generation/verification. It is separate from the main cryptopunks.app API. **Base URL:** https://bids.cryptopunks.app **Docs:** https://bids.cryptopunks.app/docs (interactive Swagger UI) ยท **OpenAPI JSON:** https://bids.cryptopunks.app/docs/json ### Bids #### Store a signed bid POST /api/v1/bids - Description: Store a complete EIP-712 bid with signature. Uses cached Merkle proofs if available; otherwise proofs are generated asynchronously. - Request Body (JSON): - punkIndices (required): Array of integers 0-9999 - bidAmount (required): String, bid amount in ETH (e.g. "1.0") - address (required): Ethereum address of the bidder (0x + 40 hex) - signature (required): EIP-712 signature (0x + 130 hex chars) - bidNonce (required): Integer, unique bid nonce (minimum 1) - chainId (optional): Integer, default 1 - auctionContract (optional): CryptoPunks contract address - stashContract (optional): Stash contract address - expiresAt (optional): Unix timestamp (string or number) - tag (optional): String 1-255 chars, label for the bid on the frontend - Response 201: success, data with id (uuid), bidder_address, punk_indices, bid_amount_wei, bid_amount_eth, status, created_at, tag, proofs_from_cache (boolean) #### Get bids GET /api/v1/bids - Parameters: - bidder (query): Filter by bidder address - status (query): One of "pending", "accepted", "rejected", "expired", "cancelled" - limit (query): 1-100, default 50 - chainId (query): e.g. 1 for Ethereum mainnet - Response: success, data array of bids (id, bidder_address, punk_indices, bid_amount_wei, bid_amount_eth, merkle_root, account_nonce, bid_nonce, status, created_at, expires_at, tag, proofs when available) #### Get highest bids GET /api/v1/bids/top - Parameters: limit (1-100, default 10), status, chainId - Response: Bids ordered by bid amount descending #### Get all bids GET /api/v1/bids/all - Parameters: limit (1-1000, default 100), status, chainId - Response: Most recent bids by creation date descending #### Get bid by ID GET /api/v1/bids/{id} - Parameters: id (path) โ€” UUID of the bid - Response: Single bid with signature, status, created_at #### Get bids for a punk GET /api/v1/bids/punk/{id} - Parameters: id (path) โ€” Punk index 0-9999; status, limit (1-100, default 50), chainId (query) - Response: Bids that include this punk ID, with proofs when available #### Get proofs for a bid GET /api/v1/bids/{id}/proofs - Parameters: id (path) โ€” Bid UUID - Response: Merkle proofs for each punk index in the bid (object mapping punk index to array of proof hashes) #### Refresh bids for a bidder POST /api/v1/bids/refresh - Description: Checks on-chain nonces for pending bids from a bidder and updates status (account_nonce, bid_nonce vs on-chain). - Request Body: bidder (required, Ethereum address), chainId (optional, default 1) - Response: bidder, chainId, totalBids, updated, results (bidId, status, reason, accountNonceValid, bidNonceUsed) ### Merkle Tree #### Generate Merkle root POST /api/v1/merkle/root - Request: punkIndices (required, array 0-9999), expectedRoot (optional) - Response: success, data with root, punkIndices, count #### Generate EIP-712 bid structure POST /api/v1/merkle/bid - Request: punkIndices (required), bidAmount (required, ETH string), address (required), chainId, auctionContract, stashContract, expectedRoot (optional) - Response: success, data with bid (order, accountNonce, bidNonce, expiration, root), domain, types for EIP-712 signing #### Generate Merkle proof for one punk POST /api/v1/merkle/proof - Request: punkIndices (required), targetPunkIndex (required), expectedRoot (optional) - Response: success, data with proof (array of hashes), root, targetPunkIndex, punkIndices #### Verify Merkle proof POST /api/v1/merkle/verify - Request: punkIndex (required), proof (required, array of strings), root (required) - Response: success, data with isValid, punkIndex, root #### Generate batch Merkle proofs POST /api/v1/merkle/batch-proofs - Request: punkIndices (required), targetPunkIndices (required), showProgress (optional), expectedRoot (optional) - Response: success, data with proofs (object mapping punk index to proof array), root, punkIndices, targetPunkIndices, count #### Generate proofs for all punks in range POST /api/v1/merkle/all-punk-proofs - Request: startIndex (required, 0-9999), endIndex (required, 0-9999), showProgress, expectedRoot (optional) - Response: success, data with proofs, root, startIndex, endIndex, count, generatedAt #### Verify batch Merkle proofs POST /api/v1/merkle/verify-batch - Request: proofs (required, object mapping punk index to proof array), root (required) - Response: success, data with results (punk index to boolean), root, totalVerified, validCount ### Bids API error responses - 400: Validation error or duplicate nonce (ValidationError: success, message, errors array with code, path, message) - 404: Bid not found (e.g. GET by id or GET proofs) - 500: Internal server error (Error: success, message, error) ## Data Formats ### Punk Object - id: String (punk index as string) - index: Integer (0-9999) - owner: String (Ethereum address) - ownerAddress: String (Ethereum address) - assigned: Boolean - wrappedOwnerAddress: String (optional, for wrapped punks) - isForSale: Boolean - sellerAddress: String (optional) - offerValue: String (optional, in wei) - onlySellToAddress: String (optional, for private offers) - hasBid: Boolean - bidderAddress: String (optional) - bidValue: String (optional, in wei) - attributes: Array of strings (normalized attribute names) - attributeCount: Integer - type: String ("MALE", "FEMALE", "ALIEN", "APE", "ZOMBIE") - wrapped: Boolean - createdAt: ISO timestamp - updatedAt: ISO timestamp ### Attribute Format Attributes are normalized (e.g., "fem_" prefix removed) and formatted with underscores replaced by spaces for display (e.g., "Red_Mohawk" becomes "Red Mohawk"). ### Value Format - All ETH values are returned in wei (as strings to preserve precision) - USD values are included where available - Timestamps are Unix timestamps (seconds) or ISO 8601 strings depending on endpoint ## Rate Limiting - Most endpoints have reasonable rate limits - Some endpoints may have caching (5 minutes for /api/recents) ## Error Responses All endpoints return JSON error responses in the format: ```json { "error": "Error message", "success": false } ``` Common HTTP status codes: - 400: Bad Request (invalid parameters) - 401: Unauthorized (missing or invalid auth) - 404: Not Found (punk not found, etc.) - 500: Internal Server Error ## Notes - Punk indices range from 0 to 9999 (10,000 total punks) - All Ethereum addresses should be lowercase for consistency - ENS names are automatically resolved where applicable - Wrapped punks are ERC-721 tokens representing CryptoPunks - Some endpoints support pagination via cursor-based pagination - Transaction history is sorted by timestamp (most recent first) - Attribute counts and statistics are available for filtering and analysis