API Documentation
Authentication
All write endpoints require an API key in the request header:
X-API-Key: your-api-key
If the key is missing or invalid, the API returns 401 Unauthorized.
POST /api/iocs
Submit a single IOC (Indicator of Compromise). Send one JSON object per request. IOCs are upserted by indicator + type + source (your API key): repeated submissions update the same row (last seen, hit count). Comments are stored in a history table (at most one per day per source).
Required fields:
indicator— the IOC value (e.g. IP, URL, hash, hostname)type— one of:ip,url,hash,hosttag— tag/category
Optional:
comment— string, max 255 characters (stored in comment history; at most one per calendar day per source)timestamp— client-submitted datetime; stored for reference only. Server uses its own time for first_seen/last_seen.
Response:
status,inserted(0 or 1),updated(0 or 1)
Example:
{
"indicator": "192.0.2.1",
"type": "ip",
"tag": "malware",
"comment": "Observed in campaign XYZ"
}
curl:
curl -X POST "https://ctidao.com/api/iocs" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"indicator":"192.0.2.1","type":"ip","tag":"malware","comment":"Observed in campaign XYZ"}'
GET /api/blocklist
Export IOCs as a blocklist (plain text, one indicator per line, or JSON). No API key required. Only IOCs with last_seen within the given time window are included (TTL-style).
Query parameters (all optional):
type— filter by IOC type (e.g.ip)tag— filter by taghoursorttl— time window in hours (default: 24); only rows with last_seen ≥ now − hoursformat—text(default) orjson
Examples:
curl "https://ctidao.com/api/blocklist?type=ip&hours=24" curl "https://ctidao.com/api/blocklist?type=ip&tag=malware&hours=48&format=json"
POST /api/pdns/batches
Whale-tier account holders (1M+ CTIDAO held) submit bounded JSON or NDJSON batches asynchronously. The endpoint always returns 202 Accepted; aggregates are written by the queue worker. Each request uses your account API key and an idempotency key. The former direct POST /api/pdns firehose endpoint is retired.
Required fields:
host— hostnameip— IP address
Optional (with defaults):
record— record type (default:A; onlyAis supported for now)timestamp— datetime string (default: current server time)
Example:
{
"host": "sub.example.com",
"ip": "203.0.113.10",
"record": "A",
"timestamp": "2026-02-22 12:00:00"
}
curl:
curl -X POST "https://ctidao.com/api/pdns/batches" \
-H "X-API-Key: YOUR_ACCOUNT_API_KEY" \
-H "Idempotency-Key: source-window-20260711-0001" \
-H "Content-Type: application/json" \
-d '{"host":"sub.example.com","ip":"203.0.113.10","record":"A","timestamp":"2026-02-22 12:00:00"}'