Developer API

Programmatic access to the same data every ANTESIGNA page shows β€” nothing more, nothing less. All data endpoints are read-only GET, return JSON (or CSV where noted) and require an account: authenticate with an X-API-Key token or your browser session cookie. The specification itself is the one public route β€” it describes the endpoints, it does not serve data. Every number comes from the same engine queries that feed the interface.

OpenAPI 3.1 specification (JSON) β†’ β€” machine-readable, public (no auth needed for the spec itself), ready for codegen and API clients.

Quickstart

You need an ANTESIGNA account (request access). Tokens are generated in Settings β†’ API tokens inside the client area, shown once at creation (only the SHA-256 hash is stored), inherit exactly your account’s data scope, and can be revoked at any time β€” revocation takes effect on the very next request. A request with an invalid or revoked key gets 401 immediately, with no silent fallback.

# 1) In the app: Settings β†’ API tokens β†’ "Generate token".
#    The token (ansg_…) is shown ONCE β€” we store only its SHA-256 hash.
# 2) Keep it in your secret store, never in code:
export ANTESIGNA_API_KEY=ansg_...
BASE=https://www.antesigna.com

# 3) Every call is a plain GET with one header:
curl -s -H "X-API-Key: $ANTESIGNA_API_KEY" "$BASE/api/v1/health"

Endpoint reference

GET /api/v1/health β€” System health

Live counters of what the engine ingested and produced in the last 24 hours (themes, articles, integrity alerts) plus total claims. Real database counts β€” the quickest way to check the pipeline is breathing.

curl -s -H "X-API-Key: $ANTESIGNA_API_KEY" "$BASE/api/v1/health"

GET /api/v1/indices β€” Indices per theme

Latest scalar value of a named index for each theme (7-day window, most recent value per theme).

  • name β€” one of echo_heterogeneity_index, agenda_density_index, contamination_score, echo_origin_index, r0_narrativo, silence_ratio, hawkes_branching_ratio, narrative_attractor, contrarian_cluster, contradiction_graph (default: echo_heterogeneity_index). Every name on this list is one the engine actually writes, and you will find it on a theme page β€” but not the other way round: a theme page also shows families this endpoint does not serve (lead-lag links, robust changepoints, narrative regime, narrative mutations, persistent loops, weak-signal growth), because they are not single scalars per theme. Three retired names (agenda_drift_index, evidence_overshoot_index, contrarian_index) are still accepted for backward compatibility and return an empty set; anything else is rejected with 400.
  • limit β€” 1–50, default 10 (out-of-range values are clamped)
curl -s -H "X-API-Key: $ANTESIGNA_API_KEY" "$BASE/api/v1/indices?name=echo_heterogeneity_index&limit=10"

GET /api/v1/alerts β€” Integrity alerts

Integrity alerts from the last 30 days, ordered by confidence (highest first), not by date β€” a small limit therefore returns the strongest alerts of the window, not the newest; the bulk export orders by date instead. Each carries risk_domain alongside the category β€” passive single-source pickup, possible coordinated amplification, error cascades β€” with confidence, contamination score and rationale.

  • limit β€” 1–100, default 20
curl -s -H "X-API-Key: $ANTESIGNA_API_KEY" "$BASE/api/v1/alerts?limit=50"

GET /api/v1/predictions β€” Forecasts

Active forecasts with probability, horizon and status. Queued forecasts return probability = null β€” we never serialize a filler value as an estimate.

  • limit β€” 1–100, default 20
  • resolved β€” resolved=1 also includes resolved forecasts
curl -s -H "X-API-Key: $ANTESIGNA_API_KEY" "$BASE/api/v1/predictions?resolved=1&limit=50"

GET /api/v1/timeseries β€” Historical time series

Full history of a named index as the engine cycle persisted it β€” one row per (theme, timestamp), chronological, never interpolated. Keyset cursor pagination (meta.next_cursor). CSV output is tidy (date,series,topic_id,topic_label,value). The country filter selects themes with at least one backing article from a source registered in that country β€” the SOURCE’s country, not the theme’s subject (stated in meta, because it is the only real country anchor in our schema).

  • series β€” required; one of the numeric series the engine actually writes, e.g. echo_heterogeneity_index, agenda_density_index, contamination_score, silence_ratio, hawkes_branching_ratio… (full whitelist in the OpenAPI spec; anything else β†’ 400)
  • topic | country β€” optional, mutually exclusive: one theme id, or an ISO-2 source-country code
  • from / to β€” ISO-8601 bounds on produced_at (inclusive)
  • format β€” json (default) or csv (tidy, formula-injection hardened)
  • limit β€” 1–1000, default 500
  • cursor β€” opaque keyset cursor from meta.next_cursor; null next_cursor = last page
curl -s -H "X-API-Key: $ANTESIGNA_API_KEY" \
  "$BASE/api/v1/timeseries?series=echo_heterogeneity_index&from=2026-06-01&limit=500"
# next page: pass meta.next_cursor back
curl -s -H "X-API-Key: $ANTESIGNA_API_KEY" \
  "$BASE/api/v1/timeseries?series=contamination_score&country=US&format=csv" -o series.csv

GET /api/v1/asof β€” Point-in-time: what did we know on date X

Bitemporal as-of view over the claim corpus: the claims about an entity whose ingestion time (transaction time) is on or before the date β€” exactly what was in our corpus that day, with both time axes per claim (valid_time = published_at, transaction_time = fetched_at) and full provenance. Later corrections never rewrite this view. meta.known_later_count quantifies the hindsight gap: claims about events on/before the date that we only learned afterwards. Empty results say why (no_data_for_entity / nothing_known_at_date) β€” never padded.

  • entity β€” required; an actor name as extracted by the engine (exact case-insensitive match β€” no fuzzy matching, an invented match would be a fabrication)
  • date β€” required; ISO-8601 (a bare date means end of that day, inclusive)
  • limit β€” 1–500, default 100
  • cursor β€” keyset cursor on (transaction_time, claim_id)
curl -s -H "X-API-Key: $ANTESIGNA_API_KEY" \
  "$BASE/api/v1/asof?entity=Gazprom&date=2026-06-15"

GET /api/v1/claims β€” Claim-level access with provenance

Engine-extracted claims, each with the article that backs it (title, source, verifiable url, published_at) β€” only fields already in the database, no synthesis, meta-claims excluded. Filter by entity, theme, or created_at window; keyset cursor pagination, newest first.

  • entity β€” optional; actor name, exact case-insensitive match
  • topic β€” optional; theme id β€” returns that theme’s own claim set
  • event_type β€” optional; lowercase snake_case slug (e.g. leadership_change) β€” malformed values are rejected with 400, not ignored
  • from / to β€” ISO-8601 bounds on the claim’s created_at (same column the cursor uses)
  • limit β€” 1–500, default 100
  • cursor β€” opaque keyset cursor from meta.next_cursor
curl -s -H "X-API-Key: $ANTESIGNA_API_KEY" \
  "$BASE/api/v1/claims?entity=DRDO&from=2026-07-01&limit=100"

GET /api/v1/screening β€” Registry & sanctions screening (honest perimeter)

Screens an organization name against the primary public lists our daily registry refresh ingests β€” OFAC SDN (US, public domain), the EU consolidated financial sanctions list and the UK OFSI consolidated list β€” plus GLEIF LEI open data (CC0) for legal identity and who-owns-whom links. Organizations only: natural persons are filtered out at ingestion. Matching is exact on normalized names and official aliases; 'possible' matches (suffix-insensitive name equality) are returned separately with confidence below 1 and are never presented as confirmed. Every response carries meta.disclaimer, which names the lists actually searched and the date of each list’s last refresh: an empty result means Β«not found in the lists we ingest, as of those datesΒ» β€” never a statement that an entity is not sanctioned anywhere. If the registry refresh has not run yet, the response says so instead of returning an all-clear. Not a comprehensive KYC/compliance screening service.

  • entity β€” required; an organization name (matched exactly after normalization β€” lowercase, no diacritics, punctuation stripped)
curl -s -H "X-API-Key: $ANTESIGNA_API_KEY" \
  "$BASE/api/v1/screening?entity=Gazprombank"

GET /api/v1/export β€” Bulk export (CSV / JSON)

The same data the pages show, in bulk, for your spreadsheets and models. Predictions include the credal band (the same interval the pages show, exported as credal_lo/credal_hi) and the resolution rule fixed in advance; forecast_history is the real daily trajectory, never interpolated, as far as your limit reaches.

  • type β€” alerts Β· predictions Β· indices Β· forecast_history Β· analyses (the interpretive analyses selected for the caller’s own client type) Β· theme_articles (needs id=<topic_id>) Β· contagion β€” strict whitelist of seven, required; anything else answers 400 listing the accepted values
  • id β€” required for type=theme_articles: the topic id whose primary sources you want
  • format β€” csv (default, downloads a file) or json
  • limit β€” 1–1000, default 200. Counts ROWS, not forecasts: forecast_history rows come ordered by prediction_id then day, so a limit that runs out cuts a trajectory in half
  • name β€” for type=indices only: same whitelist as /api/v1/indices
curl -s -H "X-API-Key: $ANTESIGNA_API_KEY" -o forecasts.csv \
  "$BASE/api/v1/export?type=predictions&format=csv"
curl -s -H "X-API-Key: $ANTESIGNA_API_KEY" \
  "$BASE/api/v1/export?type=forecast_history&format=json&limit=1000"

Export format details

CSV downloads carry a UTF-8 BOM (Excel-friendly), RFC-4180 quoting, and spreadsheet formula-injection hardening: any cell starting with = + - @ or a tab/CR is prefixed with an apostrophe so it can never execute on open. JSON exports wrap rows in { data, meta } where meta states the dataset type, row count, the fixed query window in days, and deduplicated: false. Nested structures (evidence chains, resolution rules) are serialized as compact JSON inside the cell.

MCP server (Claude Desktop / Claude Code)

A read-only Model Context Protocol server is available for Claude Desktop and Claude Code: it exposes get_health, get_alerts, get_predictions, get_indices, get_timeseries and get_asof as MCP tools, each calling this same API v1 with your ANTESIGNA_API_KEY. Plain Python standard library, stdio transport, no extra dependencies. The command below is the whole setup; our source repository is not public at this time, so ask support@antesigna.com for the package itself.

# Claude Code:
claude mcp add antesigna \
  --env ANTESIGNA_API_KEY=ansg_... \
  --env ANTESIGNA_BASE_URL=https://www.antesigna.com \
  -- python3 mcp-server/server.py

Honest limits

What the API does not do yet. We would rather state it than let you discover it.

  • Rate limit: 120 requests / minute per token, per-instance. Authenticated requests are limited to 120 per 60-second sliding window per API token (session traffic counts per user). Under load the effective ceiling can be higher than 120, never lower: design against 120. The limit in force is declared in meta.rate_limit of every JSON response and in the X-RateLimit-Limit and X-RateLimit-Remaining headers; a rate-limited 429 carries Retry-After in seconds. Invalid-key attempts are limited separately (20 failures / 15 minutes / IP) and answer 429 without a Retry-After.
  • Real usage metering. Every authenticated request is logged (route, status, latency, token) to a usage table β€” asynchronously, never delaying the response. Your own last-7-days counter per token is visible in Settings β†’ API tokens. We meter what we serve; nothing is estimated.
  • Cursor pagination on the new endpoints only. timeseries, asof and claims paginate with an opaque keyset cursor (meta.next_cursor; null = last page), stable under concurrent engine writes. The older endpoints (alerts, predictions, indices, export) still take a single limit parameter (1000 max on export, 100 on alerts/predictions, 50 on indices) with no pagination.
  • Read-only, polling-based. All endpoints are GET. There are no write operations and no push channels on the public API: webhook subscriptions cannot be created through it, and polling is the integration model today. Signed scheduled delivery exists as a product feature and is configured with us, not self-served through the API.
  • Fixed query windows on the older endpoints. Alerts cover the last 30 days, indices the last 7 days, health counters 24 hours β€” fixed server-side, stated in the OpenAPI spec. timeseries, asof and claims accept real date parameters (from/to, date) instead.
  • Exports are raw rows. Export rows are NOT deduplicated (the JSON meta says deduplicated: false explicitly), so counts can legitimately exceed the deduplicated badges shown on the pages. Same queries, different aggregation β€” declared, not hidden.

Thematic intelligence for informational purposes: probabilities and indices are estimates with a published calibration record, never financial advice or recommendations on instruments. Questions: support@antesigna.com.