SiftingSignal v1 API
Programmatic access to consensus maps, signals, and topic feeds. Built for researchers and journalists. JSON over HTTPS, Bearer-token authentication, CC-BY-4.0 with required attribution on the Starter tier.
On this page
Authentication
All /v1/* endpoints require a Authorization: Bearer <api_key> header. Keys start with ss_ followed by 48 hex chars. The cleartext key is shown once at creation time and SHA256-hashed for storage — there is no key recovery path. Rotate by revoking and creating a new key.
Authorization: Bearer ss_a1b2c3d4e5f6...
Optional IP allowlists are configurable per key (defense in depth for headless deployments).
Response envelope
Every /v1/* response wraps the payload with a meta block carrying source, license, attribution flags, and the request id:
{
"meta": {
"source": "SiftingSignal",
"source_url": "siftingsignal.com",
"license": "CC-BY-4.0 with required attribution: \"Source: SiftingSignal (siftingsignal.com)\"",
"attribution_required": true,
"attribution_text": "Source: SiftingSignal (siftingsignal.com)",
"request_id": "req_a1b2c3d4e5f60718",
"rate_limit_remaining": 9994,
"rate_limit_reset_at": 1748272800,
"plan_tier": "api_starter",
"api_version": "v1",
"generated_at": "2026-05-25T18:42:01.123Z"
},
"data": {... }
}
Rate limits
| Tier | RPS | Monthly reads |
|---|---|---|
| API Starter | 5 | 10,000 |
| API Pro | 20 | 100,000 |
| Sandbox (demo key) | 1 | 100 / day |
Every response includes the headers X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset. On exceed: HTTP 429 with structured JSON error and reset epoch.
Errors
All errors return a structured JSON body with HTTP-aligned status codes:
{ "error": { "code": "quota_exceeded", "message": "...", "status": 403 } }
| Status | Code | Meaning |
|---|---|---|
| 401 | no_api_key | Missing Bearer header |
| 401 | key_not_found | Unknown key |
| 401 | key_revoked | Key has been revoked |
| 403 | ip_not_allowed | Request IP not on the key's allowlist |
| 403 | quota_exceeded | Monthly read quota saturated |
| 403 | tier_required | Endpoint requires api_pro (bulk export, search) |
| 429 | rate_limited | RPS limit exceeded; back off |
Attribution & license
All data is licensed under Creative Commons Attribution 4.0 (CC-BY-4.0).
- API Starter: required attribution. Any public-facing derivative must include "Source: SiftingSignal (siftingsignal.com)" visibly.
- API Pro: commercial use permitted; attribution still encouraged but not contractually required.
The meta.attribution_text field in every response gives you the exact attribution string to render. Bots, journalists, and academic citations: see our open datasets with DOIs for canonical citations.
Endpoints
List published consensus maps with paginated filtering.
Query parameters
| niche | media | ai | money | health | sports |
| since | unix epoch seconds; only maps refreshed since this time |
| status | default published |
| limit | default 25, max 100 |
| offset | default 0 |
Full consensus map for a topic — synthesis claim, tier_positions, contested sub-questions, cited signals, verifier metadata.
List signals (raw outlet articles) with filters: niche, source_tier, since, contains (text).
Single signal by id, with its mapped topics.
Topic listing with niche filter and resonance scores.
Latest published consensus maps + signals for one niche; ideal for niche-watchers + cross-tier reporting.
Cross-corpus text search across signals + consensus maps. Returns the union, kind-tagged.
Paginated bulk export of consensus maps (up to 1,000 per page). Use offset to walk the full archive.
Paginated bulk export of signals (up to 10,000 per page).
Try it (sandbox)
Use the demo sandbox key ss_sandbox_demo_KEY to test the wire format. The sandbox has a 100 reads/day cap and is rate-limited at 1 RPS. Replace with your real key before going to production.
// response will appear here
Snippets
curl
curl -H "Authorization: Bearer ss_sandbox_demo_KEY" \
"https://siftingsignal.com/v1/consensus-maps?niche=ai&limit=5"
Python
import httpx
resp = httpx.get(
"https://siftingsignal.com/v1/consensus-maps",
params={"niche": "ai", "limit": 5},
headers={"Authorization": "Bearer ss_sandbox_demo_KEY"},
timeout=30.0,
)
resp.raise_for_status
body = resp.json
for row in body["data"]["items"]:
print(row["topic_display"], row["disagreement_index"])
print(body["meta"]["attribution_text"]) # surface this if attribution_required
JavaScript
const resp = await fetch(
"https://siftingsignal.com/v1/consensus-maps?niche=ai&limit=5",
{ headers: { "Authorization": "Bearer ss_sandbox_demo_KEY" } },
);
const body = await resp.json;
console.log(body.meta.attribution_text);
for (const row of body.data.items) {
console.log(row.topic_display, row.disagreement_index);
}
Questions about academic comp accounts or enterprise volume? Email [email protected].