Quickstart

First successful query in under a minute, on any of the three surfaces.

Step 0Sign up — free plan, instant, no card. 2,500 credits a month, and every dataset a paid plan sees.get started
$ claude mcp add --transport http scientia-basis https://scientia-api-go.fly.dev/mcp \
    --header "Authorization: Bearer $SCIENTIA_API_KEY"
# tools: search_entities · get_entity · screen_name ·
#        get_country_profile · get_country_factbook · list_datasets

Core concepts

Entities & statements

An entity is a real-world thing: a country, a port, an airline, a sanctioned person. Entities don't store values directly — they are assembled from statements. A statement is one fact: a property, a value, the dataset that asserted it, the origin URL, the ingest run that produced it, and first-seen/last-seen timestamps. Nothing is hand-edited; nothing is silently merged.

Corpus releases

Ingest runs accumulate into an immutable release (labels look like 2026.08.7 — year, month, and a counter over every build attempted that month). Every response is stamped with the release that answered it, and an unpinned read returns what a read pinned to that current label returns. ?release= currently accepts only the served label. Older-artifact reads, historical time selectors and detailed historical diffs fail closed rather than mixing current identity with old statements. Precomputed totals remain available at /releases/diff?from=&to= as release bookkeeping, not reconstructed historical answers.

Current-release pinning works on: /entities/{id}, /countries/{code}, /countries/{code}/factbook, /datasets and /stats. /search and /screen refuse it with a 400: the full-text index holds current state only, so a pinned search would be right about which entities exist and wrong about their names. Answering plausibly and incompletely is the failure this machinery exists to remove, so those routes say no instead.

Entity ID conventions

ID pattern
Entity
country:US
Country
subdivision:US-CA
Subdivision (ISO 3166-2)
locode:USNYC
UN/LOCODE trade location
airport:KLAX
Airport (ICAO ident)
airline:icao:UAE
Airline
airline:wikidata:<QID>
Airline identified by Wikidata QID
gpc:166
Product category (Google taxonomy)
hs:8542
Tariff code (US HTS)
eccn:0A504
Export-control code (CCL)
uktt:commodity:8517110000-80
UK tariff commodity
cross:H048721
CBP CROSS classification ruling
csl:SDN:36
Sanctioned party (US lists — CSL, OFAC SDN)
uksl:AFG0001
Sanctioned party (UK Sanctions List)
eusl:EU.27.28
Sanctioned party (EU consolidated list)

Schemas

CountrySubdivisionLocationAirportAirlinePostalOperatorProductCategoryTariffCodeExportControlPersonCompanyOrganizationVesselAirplaneSanction

REST API reference

All endpoints return JSON. Every data route requires Authorization: Bearer <key>; GET /livez and GET /readyz stay open as health endpoints. Data routes are versioned under /v1. Keys are per-caller — hashed at rest, carrying scopes, a plan and its ceilings, and revocable individually. Every payload carries corpus_release. API and MCP references are published on this page; the hosted Go service does not expose a public OpenAPI or Swagger endpoint.

Endpoint
Params & behavior
GET /me
Your plan, your ceilings and what the account has spent this period — with a per-key and per-op breakdown. Costs nothing and stays readable when you are out of credits.
GET /search
q, optional schema, country, limit — full-text search across all entities.
GET /entities/{id}
Full entity: every property as a statement, provenance included.
GET /countries/{code}
Country profile — reference + risk.* fields. factbook=true adds the release's available Factbook fields.
GET /countries/{code}/factbook
q filters that country's Factbook fields by keyword.
GET /screen
name, optional threshold (default 0.7), schema — scored watchlist candidates, each response naming the engine that produced them.
GET /datasets
Every dataset with contents, SPDX license, license note, required attribution, redistribution term, counts and last ingest — machine-readable. release= pins the counts.
GET /runs
Ingest audit trail: run id, dataset, source content hash where the run had a file input, counts, status.
GET /releases
Release history with the gate verdicts each build recorded.
GET /releases/diff
from, to — added, changed and newly-stale statements between two corpus releases.

MCP server

Remote MCP over streamable HTTP, behind the same bearer token as the API.

$ claude mcp add --transport http scientia-basis https://scientia-api-go.fly.dev/mcp \
    --header "Authorization: Bearer $SCIENTIA_API_KEY"

Tools

Tool
Docstring
search_entities
Full-text search across the corpus; optionally filter by schema or country.
get_entity
Fetch one entity by ID with all statements and provenance.
screen_name
Match a person/company/vessel name against sanctions watchlists; returns candidates with scores.
get_country_profile
Reference profile for a country: codes, currency, postal format, quantitative risk fields.
get_country_factbook
Query a country's CIA World Factbook fields by keyword.
list_datasets
Catalog of ingested datasets: SPDX license id, license note, required attribution text and redistribution terms, plus origin, entity/statement counts and last successful ingest time.
Note

Tool docstrings are written for the model — they are part of the product surface, not internal documentation.

Worked example — clearing a Vietnam-bound consignment

→ get_country_profile("VN")
{ "corpus_release": "2026.08.7", "id": "country:VN",
  "schema": "Country", "caption": "Vietnam",
  "properties": {
    "currency": ["Dong"], "currency_code": ["VND"],
    "iso_3166_1_alpha3": ["VNM"], "risk.cpi_score": ["41"],
    "risk.fatf_list": ["increased_monitoring"],
    "risk.wgi_rule_of_law": ["-0.314"], … },
  "provenance": {
    "risk.cpi_score": [{ "dataset": "cpi", "run": 4,
      "source": "https://images.transparencycdn.org/images/CPI2025_Results.zip",
      "first_seen": "2026-08-08T16:26:02Z",
      "valid_from": "2025-01-01", "valid_to": "2026-01-01" }], … },
  "notices": [{ "dataset": "cpi", "license": "CC-BY-ND-4.0",
      "attribution": "Source: Transparency International, Corruption Perceptions Index 2025 …" }], …,
  "factbook_fields_available": 307,
  "related_entity_counts": { "Location": 241, "Airport": 71, … } }

→ screen_name("Viktor Bout", threshold=0.7)
{ "corpus_release": "2026.08.7", "query": "Viktor Bout",
  "threshold": 0.7, "engine": "yente", "match_count": 1,
  "matches": [{ "id": "csl:SDN:8279", "schema": "Person",
    "caption": "BOUT, Viktor Anatolijevitch", "score": 0.909,
    "explanations": { "name_match": 0.909, "dob_year_disjoint": 0.0 } }] }

CLI reference

Point the CLI at the hosted corpus with SCIENTIA_API_URL=https://scientia-api-go.fly.dev + SCIENTIA_API_KEY (or SCIENTIA_API_TOKEN). Output is JSON by default — pipe it straight into agent tools; add --pretty for humans.

Command
Does
scientia search <q>
Full-text search; --schema to filter.
scientia entity <id>
One entity with statements and provenance.
scientia country <code>
Reference + risk.fatf_list · risk.cpi_score · risk.wgi_*.
scientia factbook <code> <q>
Country Factbook fields, keyword-filtered.
scientia screen <name>
Watchlist candidates; --threshold (default 0.7).
scientia datasets
License, redistribution term and freshness for every source.
scientia runs
Ingest audit trail with source content hashes.
scientia releases
Immutable release history and serving boundaries.
scientia diff <from> <to>
Dataset and statement changes between releases.
scientia stats
Corpus counts by schema, as of the release that answers.

Screening semantics

The contract

Screening returns candidates, not verdicts. Scores are specific to the engine that produced them; the default threshold (0.7) is caller-tunable. Every response names its engine and corpus release. Yente is used only when its verified export generation matches the serving corpus. An unavailable or different-generation index uses the current corpus's lexical fallback with an explicit degradation reason, never an older index labelled as current.

Initial launch is pinned to snapshot 2026.10.2. Its matching index is not yet aligned, so screening currently uses lexical-v0. This fallback does not provide Yente's transliteration-aware matching. Clients that require that capability must reject degraded responses rather than interpret an empty result as clearance. Source timestamps, not the snapshot label, establish the age of individual records.

Plans & limits

One usage-based model. Plans differ in volume alone — how many credits they carry and how fast you may spend them. Not in which data they can see, and not in which matcher answers them. Every plan clears the same datasets and reaches the same screening engine, and tests in the repository exist to keep both true.

The paid tier used to withhold the stronger matcher. That is gone: the engine is a fixed cost whether or not a free key queries it, credits already separate the plans, and shipping a knowingly weaker matcher for sanctions screening — where a miss has consequences — was not a boundary worth defending. A free key screens with exactly what a paying one screens with.

Plan
Credits / month
Rate limit
Free
2,500
30 / min
Developer
75,000
120 / min
Scale
500,000
600 / min

What a credit is

A credit is one unit of the weight each operation declares. It is not a separate currency and there is no conversion table — the weights below are the ones the API meters with, published so you can price a workload before you run it.

Operation
Cost
Entity fetch, country profile, dataset/run/release listings
1 credit
Search
2 credits
Screen
2 credits
Release diff (precomputed)
1 credit
Release diff (recomputed, or with row detail)
50 credits

The weight is declared per operation and never derived from what came back. A search that matches nothing costs the same as one that matches fifty — which is a deliberate privacy property, not an accounting shortcut: your bill does not disclose your results. Nothing about which names you screened is recoverable from what you were charged.

Reading your balance

Every response carries its own accounting, so you never have to open a dashboard to find out where you stand.

For the full picture — plan, ceilings, spend this period, and a breakdown by key and by operation — call GET /me. It costs no credits, and it keeps answering when you are out of them: a 429 you cannot explain is worse than the refusal itself. It is still rate limited.

Credits and ceilings belong to the account, not to each key. Several keys — production, staging, a colleague's — draw on one allowance and appear on one bill, and /me attributes spend per key so you can see which of them is consuming it.

Header
Meaning
X-Credits-Limit
Credits this plan carries per month
X-Credits-Remaining
Credits left in the current month
X-RateLimit-Remaining
Calls left in the current minute
GET /me
The same figures, plus per-key and per-op spend

Exhausting a limit returns 429 with Retry-After where a retry can succeed. A daily ceiling also applies — roughly a third of the month's credits — so a runaway loop cannot spend a month of allowance in an afternoon.

The free plan's honest limit

2,500 credits is roughly 1,250 screens or 2,500 entity fetches per month: enough to build against and evaluate properly, not enough to run a business on. That is the whole of the limit — the data and the matcher are the same ones a paid plan gets.

What every plan shares is the engine's own limits, which are a property of the matcher rather than of the plan. Every screening response names the engine that answered it, so a degraded answer is labelled rather than assumed — see Screening semantics.

Datasets & licensing

license is an SPDX identifier — never prose, never a legal conclusion — and redistributable is the obligation that binds us when we serve it: public, attribution, share-alike, no-derivatives, non-commercial, proprietary, unknown. The two are independent, and unknown fails closed. Both, plus the prose note and the exact attribution line a licence requires, are machine-readable via GET /datasets.

Dataset
Contents
Upstream license
Redistributable
iso_countries
ISO 3166-1 country spine, plus flagged user-assigned Kosovo code
LGPL-2.1-only
share-alike
cia_factbook
January 2026 CIA World Factbook text (frozen; corrected releases)
CC0-1.0
public
wikidata_airlines
Airline QIDs, name/code claims, callsigns and country links (not membership or live status)
CC0-1.0
public
wikidata_countries
Independent country currency, capital, area and TLD claims
CC0-1.0
public
address_formats
Country address-format and postcode validation rules; not postal operators
Apache-2.0
attribution
ourairports
~72K airports with IATA/ICAO idents and coordinates
public-domain
public
unlocode
~121K UN/LOCODE locations + subdivisions
unknown
unknown
google_product_taxonomy
~5.6K product categories
unknown
unknown
opensanctions_sanctions
288K sanctions / watchlist entities (FollowTheMoney)
CC-BY-NC-4.0
non-commercial
usitc_hts
~30K US tariff codes with duty rates + hierarchy
public-domain
public
eccn_ccl
553 export-control codes (ECCN, 15 CFR 774)
public-domain
public
fatf
FATF black/grey list membership → risk.* on countries
proprietary
public
wgi
World Bank governance indicators → risk.*
CC-BY-4.0
attribution
cpi
TI Corruption Perceptions Index → risk.*
CC-BY-ND-4.0
no-derivatives
iso_scripts · iso_languages · iso_currencies · iso_subdivisions · iso_country_names · iso_historic_countries
ISO code tables from the Debian iso-codes bundle
LGPL-2.1-only
share-alike
unsd_m49 · unsd_m49_regions
M49 codes, region hierarchy, LDC/LLDC/SIDS flags
PDDL-1.0
public
cldr_names
Unicode CLDR colloquial and short country names
Unicode-3.0
attribution
Licensing

Sanctions screening runs against primary sources: us_csl and ofac_sdn are US government works in the public domain, uk_sanctions is OGL v3.0, and eu_sanctions is CC-BY-4.0. The latter three require attribution wherever their values surface, so every response that carries one of their hits also carries a notices entry naming the source and its licence. Per-key entitlements enforce every dataset's terms at the query layer — a key cannot reach a dataset it does not clear by any route, including as a count.