Skip to content

Authentication

All API requests require an API key passed via the X-API-Key header.

That key is one of three independent auth systems. This page covers the first — the X-API-Key header used by the public REST API. Developer endpoints (/api/v2/developer/*) instead take a Bearer credential (session JWT or API key), and platform ↔ runner traffic is HMAC-signed (Security & Auth):

Diagram of the three authentication systems: the X-API-Key header authenticates the public REST API; the developer API accepts a session JWT or a cd_live_ API key on the Authorization Bearer header; the platform and app runners sign requests to each other with HMAC in the X-App-Signature headerDiagram of the three authentication systems: the X-API-Key header authenticates the public REST API; the developer API accepts a session JWT or a cd_live_ API key on the Authorization Bearer header; the platform and app runners sign requests to each other with HMAC in the X-App-Signature header

Getting an API Key

  1. Connect your wallet at chaindaddy.io
  2. Open the API dashboard at chaindaddy.io/_api
  3. Click Generate Key
  4. Copy your key immediately, it won't be shown again

Store Your Key Securely

API keys grant access to your account's API quota. Never commit keys to source control or expose them in client-side code.

Key Format

Keys follow the format cd_live_ followed by 64 hexadecimal characters:

cd_live_a1b2c3d4e5f6...  (64 hex chars)

Making Authenticated Requests

Include your key in the X-API-Key header on every request:

bash
curl -H "X-API-Key: cd_live_YOUR_KEY_HERE" \
  https://api.chaindaddy.io/api/v2/search?symbol=PEPE
javascript
const response = await fetch(
  'https://api.chaindaddy.io/api/v2/search?symbol=PEPE',
  {
    headers: {
      'X-API-Key': 'cd_live_YOUR_KEY_HERE'
    }
  }
);
const data = await response.json();
python
import requests

response = requests.get(
    'https://api.chaindaddy.io/api/v2/search',
    params={'symbol': 'PEPE'},
    headers={'X-API-Key': 'cd_live_YOUR_KEY_HERE'}
)
data = response.json()

Rate Limiting

Each API tier has daily request limits and per-second rate limits:

TierPriceRequests/DayRate Limit
Free$01001 req/sec
PRO$5/mo5,0005 req/sec
PRO+$12/mo15,00010 req/sec
Developer$22/mo50,00015 req/sec
Partner$49/mo250,00050 req/sec

Free, PRO, and PRO+ limits are included with their respective plan tiers. Developer and Partner are standalone API plans.

API Feature Matrix

Endpoint access by tier:

FeatureFreePROPRO+DeveloperPartner
SearchYesYesYesYesYes
Token dataYesYesYesYesYes
Registration statusYesYesYesYesYes
Listing exportYesYesYesYes
WebhooksYesYes
Bulk endpointsYesYes
SLA guarantee99.9%

Partner

For custom rate limits, dedicated infrastructure, priority support, or SLA requirements, contact the team via the dashboard.

Rate Limit Headers

Every response includes rate limit headers:

HeaderDescription
X-RateLimit-LimitDaily request limit
X-RateLimit-RemainingRemaining requests today
X-RateLimit-ResetUnix timestamp when limit resets
Retry-AfterSeconds to wait (only on 429 responses)

Handling 429 Responses

When you exceed your rate limit, the API returns a 429 Too Many Requests response:

json
{
  "error": "rate_limit_exceeded",
  "message": "Too many requests per second",
  "retry_after": 1
}

Retry Strategy

Read the Retry-After header and wait that many seconds before retrying. Implement exponential backoff for repeated 429 responses.

javascript
async function fetchWithRetry(url, options, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const response = await fetch(url, options);

    if (response.status === 429) {
      const retryAfter = parseInt(response.headers.get('Retry-After') || '1');
      await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
      continue;
    }

    return response;
  }
  throw new Error('Max retries exceeded');
}
python
import time
import requests

def fetch_with_retry(url, headers, max_retries=3):
    for attempt in range(max_retries):
        response = requests.get(url, headers=headers)

        if response.status_code == 429:
            retry_after = int(response.headers.get('Retry-After', '1'))
            time.sleep(retry_after)
            continue

        return response
    raise Exception('Max retries exceeded')

Error Response Format

All error responses follow a consistent JSON format:

json
{
  "error": "error_type",
  "message": "Human-readable description of what went wrong",
  "code": "MACHINE_READABLE_CODE"
}
FieldTypeDescription
errorstringError type identifier
messagestringHuman-readable description
codestringMachine-readable error code (optional)

Common Error Codes

HTTP StatusErrorDescription
400bad_requestMissing or invalid parameters
403forbiddenInvalid API key or insufficient tier
404not_foundResource does not exist
409conflictSymbol already claimed on this chain
429rate_limit_exceededToo many requests

Base URL

All endpoints in this reference are served from the production API:

https://api.chaindaddy.io

There is no separate sandbox environment. For development and testing, use a Free-tier API key — read endpoints (search, token data, registration status) are safe to call, and write endpoints only return unsigned transaction data (nothing happens on-chain until you sign and submit). See the API Explorer to try endpoints interactively.