{"openapi":"3.1.0","info":{"title":"Nullcone API","description":"Distributed threat intelligence gateway. Submit IOCs, query signatures, and report detections from any language or runtime.\n\n**Nullcone is free and open source, built on SpacetimeDB. If it's been useful to you, we'd appreciate a signup via our referral: https://spacetimedb.com/?referral=maco144**","version":"0.1.0"},"paths":{"/health":{"get":{"summary":"Health","description":"Check connectivity to SpacetimeDB.","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/session":{"post":{"summary":"Mint an ephemeral session token","description":"Requires master API key (X-API-Key). Returns a short-lived token bound to the caller's IP address. Pass it as X-Session-Token on subsequent requests. Expires automatically; revoke early via DELETE /v1/session/{token}.","operationId":"create_session_v1_session_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionCreateResponse"}}}}}}},"/v1/session/{token}":{"delete":{"summary":"Revoke an ephemeral session token","operationId":"revoke_session_v1_session__token__delete","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","minLength":32,"maxLength":64,"title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionRevokeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/scan/skill":{"post":{"summary":"Pre-execution skill content scan","description":"Scans a skill/instruction file for malicious patterns BEFORE execution. Detects download-and-execute chains, bootstrap poisoning (.npmrc injection), encrypted credential exfiltration, and multi-stage kill chains. If should_block is true, the skill should NOT be executed.","operationId":"scan_skill_v1_scan_skill_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SkillScanRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/agent/register":{"post":{"summary":"Register an agent with Entity Identity proof","description":"Register an agent with the Nullcone network.\n\nRequires a valid Entity Identity (EI) ZK proof. On success the returned\n`agent_id` should be included as `X-Agent-Id` in all write requests.\n\nAllowed entity types: `AI.CA`, `AI.PO`, `AI.AA`, `AI.DB`, `AI.OS`, `HY.CP`, `HY.HS`\n\nRate limit: 10 requests/minute per IP.","operationId":"register_agent_v1_agent_register_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRegisterRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/agent/{agent_id}/stats":{"get":{"summary":"Agent contribution stats and tier","description":"Return contribution statistics and tier for a registered agent.\n\n**Contributor tiers** (based on lifetime IOC submissions):\n- Observer: 0–99\n- Analyst: 100–999\n- Hunter: 1,000–9,999\n- Sentinel: 10,000+\n\nRate limit: 200 requests/minute per IP.","operationId":"agent_stats_v1_agent__agent_id__stats_get","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","maxLength":128,"title":"Agent Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/ioc":{"post":{"summary":"Submit a single IOC","description":"Submit an IOC to the shared threat intelligence database.\n\nThe gateway classifies the IOC into a malware family, compresses metadata,\nand deduplicates atomically. All subscribed agents receive the new/updated\nIOC instantly via WebSocket.\n\nInclude `X-Agent-Id` header to track per-agent contribution stats and apply\nper-agent daily quota (default: 5,000 IOCs/day).\n\nRate limit: 60 requests/minute per IP.","operationId":"submit_ioc_v1_ioc_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IOCSubmit"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"summary":"Look up an IOC by value or hash","description":"Look up a threat signature by exact value or pre-computed value_hash.","operationId":"lookup_ioc_v1_ioc_get","parameters":[{"name":"value","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":2048},{"type":"null"}],"description":"Exact IOC value","title":"Value"},"description":"Exact IOC value"},{"name":"hash","in":"query","required":false,"schema":{"anyOf":[{"type":"string","minLength":64,"maxLength":64},{"type":"null"}],"description":"SHA256 value_hash","title":"Hash"},"description":"SHA256 value_hash"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/ioc/batch":{"post":{"summary":"Submit multiple IOCs","description":"Submit a list of IOCs (max 100 per request). Returns results in the same order.\n\nPer-agent daily quota is decremented by the number of IOCs in the batch.\n\nRate limit: 10 requests/minute per IP.","operationId":"submit_batch_v1_ioc_batch_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchSubmit"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/ioc/lookup":{"get":{"summary":"Check text for known PROMPT injection IOCs","description":"Sub-millisecond prompt injection detection via sliding-window hash lookup.\n\nScans the input `text` against the in-memory PROMPT IOC cache using a\ntoken-level sliding window. Returns match details if any window matches\na known prompt injection payload.\n\n**No API key required.** This endpoint is public to enable zero-friction\nadoption by any agent, plugin, or proxy.","operationId":"ioc_lookup_v1_ioc_lookup_get","parameters":[{"name":"text","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":10000,"description":"Text to scan for known prompt injection payloads","title":"Text"},"description":"Text to scan for known prompt injection payloads"},{"name":"threat_type","in":"query","required":false,"schema":{"type":"string","description":"Threat type to check (currently: prompt)","default":"prompt","title":"Threat Type"},"description":"Threat type to check (currently: prompt)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/threats":{"get":{"summary":"Recent threat signatures","description":"Return the most recently seen threats, optionally filtered by type, severity and confidence.\n\n`ioc_type` was silently ignored before 2026-09-15, so `?ioc_type=prompt` returned\nIPs and hashes — the Claude Code plugin's search_by_type depended on it.\n\n**Confidence tiers:**\n- `unverified` (< 0.50): raw single-source IOCs\n- `community`  (0.50–0.69): community-sourced, reasonable signal\n- `validated`  (0.70–0.84): Pro tier — curated, low noise\n- `enterprise` (≥ 0.85): multi-confirmed authoritative feed IOCs","operationId":"recent_threats_v1_threats_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":50,"title":"Limit"}},{"name":"min_severity","in":"query","required":false,"schema":{"type":"integer","maximum":10,"minimum":0,"default":0,"title":"Min Severity"}},{"name":"min_confidence","in":"query","required":false,"schema":{"type":"number","maximum":1.0,"minimum":0.0,"description":"Minimum confidence_score (0.0–1.0). 0.7+ = validated tier (Pro). 0.85+ = enterprise.","default":0.0,"title":"Min Confidence"},"description":"Minimum confidence_score (0.0–1.0). 0.7+ = validated tier (Pro). 0.85+ = enterprise."},{"name":"ioc_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Only this IOC type, newest first (e.g. prompt, skill, domain, ip, url, hash_sha256).","title":"Ioc Type"},"description":"Only this IOC type, newest first (e.g. prompt, skill, domain, ip, url, hash_sha256)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/threats/family/{family_name}":{"get":{"summary":"Threats by malware family","description":"Return all IOCs associated with a specific malware family.","operationId":"family_threats_v1_threats_family__family_name__get","parameters":[{"name":"family_name","in":"path","required":true,"schema":{"type":"string","maxLength":100,"title":"Family Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/detection":{"post":{"summary":"Report a detection event","description":"Report that your agent detected and acted on a known threat signature.\n\nCreates a ThreatEvent visible to all agents in real-time. detection_count\nrises only the first time an agent other than the original reporter\nconfirms the signature — repeats do not count.","operationId":"report_detection_v1_detection_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetectionReport"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/vote/false-positive":{"post":{"summary":"Vote that a signature is a false positive","description":"Flag a signature as a likely false positive.\n\nEach agent may vote once per signature (enforced via Redis, 30-day window).\nWhen >20% of agents vote FP, `is_likely_fp` becomes True on the signature.\n\nFP votes also decay the reputation score of the original submitting agent\n(-0.02 per vote), which feeds into future confidence scoring.\n\nRate limit: 60 requests/minute per IP.","operationId":"vote_false_positive_v1_vote_false_positive_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FPVote"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/threats/since/{last_id}":{"get":{"summary":"Delta sync since a high-water mark ID","description":"Fetch threat signatures added since `last_id` (exclusive).\n\nRecommended sync pattern for EDR sensors, honeypots, and agents that\ndon't need sub-second latency:\n1. Call with `last_id=0` on first run\n2. Persist the returned `next_id`\n3. On subsequent calls pass `next_id` as `last_id`\n4. If `count == batch_size`, call again immediately to drain backlog\n\n`next_id` always advances to the highest fetched id, even for rows\nfiltered out by `min_confidence` — the cursor is positional, not content-based.\n\nRate limit: 200 requests/minute per IP.","operationId":"threats_since_v1_threats_since__last_id__get","parameters":[{"name":"last_id","in":"path","required":true,"schema":{"type":"integer","minimum":0,"title":"Last Id"}},{"name":"batch_size","in":"query","required":false,"schema":{"type":"integer","maximum":5000,"minimum":1,"default":1000,"title":"Batch Size"}},{"name":"min_severity","in":"query","required":false,"schema":{"type":"integer","maximum":10,"minimum":0,"default":0,"title":"Min Severity"}},{"name":"min_confidence","in":"query","required":false,"schema":{"type":"number","maximum":1.0,"minimum":0.0,"description":"Filter to confidence_score ≥ this value. next_id still advances past filtered-out rows.","default":0.0,"title":"Min Confidence"},"description":"Filter to confidence_score ≥ this value. next_id still advances past filtered-out rows."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/feed":{"get":{"summary":"Public high-confidence threat feed — no auth required","operationId":"public_feed_v1_feed_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/agent/{agent_id}/reputation":{"get":{"summary":"Agent reputation score","description":"Return the reputation score for a registered agent (0.0–1.0).\n\nReputation reflects long-term submission quality:\n- Starts at 0.50 (neutral) for new agents\n- Increases when submitted IOCs are confirmed by detections from other agents\n- Decreases when submitted IOCs accumulate false-positive votes\n\nReputation feeds into confidence scoring when the submitting agent is not\na recognised authoritative feed (i.e. not in the SOURCE_CREDIBILITY registry).\n\n**Tiers:**\n- `trusted`   (≥ 0.80): high-quality historical submissions\n- `neutral`   (0.40–0.79): default for new / unproven agents\n- `degraded`  (< 0.40): history of low-quality or FP-heavy submissions","operationId":"agent_reputation_v1_agent__agent_id__reputation_get","parameters":[{"name":"agent_id","in":"path","required":true,"schema":{"type":"string","maxLength":128,"title":"Agent Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/leaderboard":{"get":{"summary":"Top contributor leaderboard","description":"Public contributor leaderboard — top agents ranked by lifetime IOC submissions.\n\nCached for 120 seconds. Results include contributor tier and rank.\n\n**Contributor tiers:**\n- Observer  (0–99 submissions)\n- Analyst   (100–999)\n- Hunter    (1,000–9,999)\n- Sentinel  (10,000+)\n\nNo API key required.","operationId":"leaderboard_v1_leaderboard_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/stats":{"get":{"summary":"Aggregate database statistics","description":"Return counts of signatures, families, agents, and events.","operationId":"stats_v1_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"AgentRegisterRequest":{"properties":{"agent_id":{"type":"string","maxLength":128,"minLength":1,"title":"Agent Id"},"hostname":{"type":"string","maxLength":256,"title":"Hostname","default":"unknown"},"os_type":{"type":"string","maxLength":64,"title":"Os Type","default":"unknown"},"ei_proof":{"$ref":"#/components/schemas/EIProof"},"ei_signals":{"items":{"type":"string"},"type":"array","maxItems":5,"minItems":5,"title":"Ei Signals"}},"type":"object","required":["agent_id","ei_proof","ei_signals"],"title":"AgentRegisterRequest"},"BatchSubmit":{"properties":{"iocs":{"items":{"$ref":"#/components/schemas/IOCSubmit"},"type":"array","maxItems":100,"title":"Iocs"}},"type":"object","required":["iocs"],"title":"BatchSubmit"},"DetectionReport":{"properties":{"signature_id":{"type":"integer","title":"Signature Id"},"action":{"type":"string","maxLength":50,"title":"Action"},"context":{"additionalProperties":true,"type":"object","title":"Context"}},"type":"object","required":["signature_id","action"],"title":"DetectionReport"},"EIProof":{"properties":{"pi_a":{"items":{"type":"string"},"type":"array","title":"Pi A"},"pi_b":{"items":{"items":{"type":"string"},"type":"array"},"type":"array","title":"Pi B"},"pi_c":{"items":{"type":"string"},"type":"array","title":"Pi C"}},"type":"object","required":["pi_a","pi_b","pi_c"],"title":"EIProof"},"FPVote":{"properties":{"signature_id":{"type":"integer","title":"Signature Id"},"reason":{"type":"string","maxLength":500,"title":"Reason","default":""}},"type":"object","required":["signature_id"],"title":"FPVote"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"IOCSubmit":{"properties":{"ioc_type":{"type":"string","maxLength":50,"title":"Ioc Type"},"value":{"type":"string","maxLength":2048,"minLength":1,"title":"Value"},"severity":{"type":"integer","maximum":10.0,"minimum":0.0,"title":"Severity","default":5},"confidence":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Confidence","default":70},"family_hint":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Family Hint"},"context":{"type":"string","maxLength":4096,"title":"Context","default":""},"tags":{"items":{"type":"string"},"type":"array","maxItems":20,"title":"Tags"},"source":{"type":"string","maxLength":100,"title":"Source","default":"api"}},"type":"object","required":["ioc_type","value"],"title":"IOCSubmit"},"SessionCreateResponse":{"properties":{"token":{"type":"string","title":"Token"},"expires_in":{"type":"integer","title":"Expires In"},"bound_ip":{"type":"string","title":"Bound Ip"}},"type":"object","required":["token","expires_in","bound_ip"],"title":"SessionCreateResponse"},"SessionRevokeResponse":{"properties":{"revoked":{"type":"boolean","title":"Revoked"}},"type":"object","required":["revoked"],"title":"SessionRevokeResponse"},"SkillScanRequest":{"properties":{"content":{"type":"string","maxLength":500000,"minLength":1,"title":"Content","description":"Full text content of the skill file to scan"},"source_url":{"type":"string","title":"Source Url","description":"URL where the skill was fetched from","default":""}},"type":"object","required":["content"],"title":"SkillScanRequest"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"servers":[{"url":"/api"}]}