Indexer API
The ARIADNE indexer reads the contract’s events from the Algorand blockchain, fetches and checks the content from IPFS, and serves what it knows as a read-only JSON API. The web app is built on it, and anyone can use it. It is a cache: everything it returns can be rebuilt from the chain and IPFS (see Verify without trusting ariadne.press and Run an indexer).
The routes below come from projects/indexer/src/api.ts, the code that answers them. Terms such as CID, round and
address are explained in the Glossary.
Base URLs
Section titled “Base URLs”One indexer runs per network, each with its own database and its own base URL, the indexerApi of the network in
spec/networks.json. Data of different networks is never mixed.
| Network | Base URL |
|---|---|
| TestNet | https://api.ariadne.press/testnet |
| MainNet | not open yet; its base URL will be the indexerApi of the mainnet entry once it opens |
| LocalNet (your machine) | http://localhost:3000 |
curl https://api.ariadne.press/testnet/statusConventions
Section titled “Conventions”-
Methods:
GETandHEAD.OPTIONSanswers 204 for browsers; any other method answers 405. -
Responses are JSON (
application/json; charset=utf-8), withAccess-Control-Allow-Origin: *andCache-Control: no-store. -
Envelope. Every response, errors included, starts with
networkandappId. Check them: they tell you which network and which application the data belongs to.{ "network": "testnet", "appId": 772983107, "...": "the route's own fields" } -
Addresses are 58-character Algorand addresses. CIDs are base32 text (
bafybei...for articles,bafkrei...for reviews and comments). Times are Unix seconds (block time). -
Field ids are numbers (
771); some lists addhex(0x0303). Parameters calledfieldaccept either form. -
typeandstatusaccept names or numbers. Types:article,notes,amendment,dataset,replication. Statuses:preprint,under_review,final,disputed,retracted(status 3,final, is shown in the app as “closed version”). -
Boolean parameters accept
1,true,yes,onand0,false,no,off. -
List parameters of the search routes may be repeated or comma-separated:
field=0x0303&field=0x0501orfield=0x0303,0x0501.
Errors and status codes
Section titled “Errors and status codes”| Code | When | Body |
|---|---|---|
| 200 | success | the route’s fields |
| 400 | a parameter is invalid (the message names it); an ORCID iD with a wrong check character; a wildcard or regular expression that takes too long | {"network", "appId", "error"} |
| 404 | unknown route; article or list not found | same |
| 405 | a method other than GET, HEAD or OPTIONS | same |
| 500 | an unexpected failure ("internal error"; the indexer logs it) |
same |
| 503 | /health when ingestion has stalled; searches with wildcards or regular expressions when their shared time budget is used up |
same |
curl -i "https://api.ariadne.press/testnet/articles?sort=top"# HTTP/1.1 400 ...# {"network":"testnet","appId":772983107,"error":"sort must be score or new"}Limits and pagination
Section titled “Limits and pagination”The indexer applies no per-client rate limit. Lists are paged with limit and offset, or with a cursor where noted:
| Route | Paging | Default | Range |
|---|---|---|---|
/articles |
limit, offset |
20, 0 | limit 1 to 100, offset up to 1 000 000 |
/search/articles, /search/posts, /search/people |
limit, offset |
20, 0 | limit 1 to 100, offset up to 100 000 |
/search/suggest |
limit |
5 | 1 to 10 |
/articles/:id/citations, /users/:address/citations, /users/:address/lists/:id |
limit, offset |
50, 0 | limit 1 to 100 |
/users/:address/following, /followers |
limit, offset |
100, 0 | limit 1 to 1 000 |
/users/:address/notifications |
limit |
50 | 1 to 100 |
/users/:address/feed, /activity |
limit, before (Unix seconds: items older than it) |
50 | limit 1 to 100 |
/notifications |
after (a notification id), limit |
0, 200 | limit 1 to 500 |
/cite |
ids |
1 to 1 000 ids |
Search text (q) is cut to 500 characters. Wildcards and regular expressions run on the indexer’s only thread, so they
have their own limits: at most 5 per query and 200 characters each; each search may spend 2 seconds on them (then 400,
“make it more specific”), and all searches together 20 seconds per minute (then 503, “busy”).
Health and status
Section titled “Health and status”GET /health
Section titled “GET /health”What an uptime monitor reads. 200 while ingestion works:
{ "network": "testnet", "appId": 772983107, "ok": true, "last_ingest_seconds_ago": 2 }503 when no ingestion poll has succeeded for ARIADNE_STALL_SECONDS (300 by default): the Algorand node is
unreachable, or a round contradicts the protocol rules. The error says how long and why.
GET /status
Section titled “GET /status”The state of the database:
| Field | Meaning |
|---|---|
genesis_id, genesis_hash |
the chain the database was built from |
schema_version |
the database schema (10) |
watermark |
the last round ingested |
governance |
the current governance address, from the events |
counts |
rows: events, articles, reviews, comments, fields, content, pinned, pin_failures, identities, orcid_verified, dois, dois_verified, follows, search_articles, search_posts, post_texts, sealed_articles, qualified_reviews, coauthor_checks |
Articles
Section titled “Articles”GET /articles
Section titled “GET /articles”The ranked feed.
| Parameter | Meaning |
|---|---|
field |
articles whose primary or secondary field is this one |
type |
name or number |
status |
name or number; without it, retracted articles are left out |
sort |
score (default) or new |
limit, offset |
paging |
Returns { total, articles: [...] }. Each article in a list has these fields:
| Field | Meaning |
|---|---|
article_id, asa_id |
the article number and its Algorand asset |
author |
the submitting wallet |
primary_field, secondary_field |
field ids (0 = none) |
article_type, type |
the type as a number and as a name |
parent_article |
the amended article, or 0 |
status, status_name, status_before_dispute |
the status as a number and as a name |
version, cid, prev_cid |
the current version and its CID; prev_cid is null for version 1 |
created_at, updated_at |
Unix seconds |
vote_total, vote_count |
the sum of vote weights and the number of votes |
author_count, invited_count |
accepted authors; declared co-authors |
claimed |
the author claimed the asset |
dispute_round, round_flag_weight |
the flag round and its weight so far |
score |
the ranking score, vote_total / (age_days + 2) ^ 0.8, computed at query time |
seal |
sealed, in_review, changes_requested, suspended or none (see below) |
warnings |
disputed, retracted, and content:<status> when the content is not valid |
content |
validation_status, title, abstract, keywords |
curl "https://api.ariadne.press/testnet/articles?field=0x0303&sort=new&limit=5"GET /articles/:id
Section titled “GET /articles/:id”One article: { article: {...} } with every list field above, plus:
| Field | Content |
|---|---|
authors[] |
submitter first, then co-authors by address: address, role (submitter or coauthor), accepted, invited_at, accepted_at, claimed_total, entitled, claimable (null until the co-author confirms), orcid (only a verified iD: id, given_names, family_name, name) |
dois[] |
version (0 = every version), doi, url, status (verified, unlinked, missing, invalid, declared or pending), declared_by, declared_at, checked_at, verified_at |
citations |
cited_by, cites, and thread (the article’s Thread Score: percentile, external_citations, cohort, cohort_size; null for amendments and retracted articles) |
seal_detail |
the Peer-reviewed seal in detail (see below) |
versions[] |
version, cid, prev_cid, ts |
reviews[] |
article_id, review_seq, reviewer, cid, recommendation (1 to 4), created_at, useful_total |
comments[] |
the comment tree: article_id, comment_seq, author, cid, reply_to, root_seq, depth, created_at, vote_total, reply_count, resolved, resolved_at, mentions[], replies[] |
flags |
threshold (30), dispute_round, round_flag_weight, current_round[] (flagger, reason, weight, ts), total_flags |
disputes[] |
dispute_round, outcome, new_status, ts |
content_record |
cid, available, validation_status, fetched_at, last_checked_at, size_bytes, notice |
curl https://api.ariadne.press/testnet/articles/1GET /articles/:id/comments?root=
Section titled “GET /articles/:id/comments?root=”One thread: the comment root (required) and every reply under it, ordered by depth, then by creation time. Returns
{ article_id, root, comments: [...] }.
GET /articles/:id/citations
Section titled “GET /articles/:id/citations”| Parameter | Meaning |
|---|---|
direction |
cited_by (default): the ARIADNE articles that cite it, newest first, retracted ones left out; cites: those it cites |
limit, offset |
paging |
Returns { article_id, direction, total, articles }; each article has the list fields plus citation_kind: amends,
link, doi or cid.
GET /articles/:id/viewer/:address
Section titled “GET /articles/:id/viewer/:address”What one address has done on one article, so that an interface offers only the actions still possible: voted_article,
review_votes[] and comment_votes[] (the numbers voted), reviewed, flagged (in the current round) and
reputation (in the article’s primary field).
The Peer-reviewed seal in the API
Section titled “The Peer-reviewed seal in the API”The seal is computed by the indexer from the chain, IPFS, ORCID and OpenAlex (D-131). See The Peer-reviewed seal for the rules.
| Where | Field | Values |
|---|---|---|
| every article in a list | seal |
sealed (at least 2 favourable reviews that count, more than the unfavourable ones), changes_requested (at least 2 unfavourable, at least as many as the favourable), in_review (some review counts), suspended (sealed but disputed), none (no review counts, or retracted) |
GET /articles/:id |
seal_detail |
null when the article has no review; otherwise state, rule (the rule version, 1), required (2), favourable, unfavourable, sealed_since, reviewed_version (the version current at the latest review that counts), reviews[] |
seal_detail.reviews[] |
review_seq, reviewer, recommendation, counted, reason (the first rule the review fails: author, expertise, conflict-orcid, conflict-coauthor, conflict-openalex, conflict-institution, text-unread, short, reciprocal; null when it counts), detail, via (reputation or openalex: how the reviewer showed expertise) |
|
GET /users/:address |
seals |
sealed_articles, qualified_reviews |
GET /users/:address, each of reviews[] |
counted, not_counted_reason |
whether that review counts toward a seal, and why not; counted is null while it has not been judged |
GET /search/articles |
sealed filter, sealed facet |
articles that hold the seal |
People
Section titled “People”GET /users/:address
Section titled “GET /users/:address”{ user: {...} }, the profile derived from the chain:
| Field | Content |
|---|---|
identity.orcid |
null, or id, status, declared_at, checked_at, verified_at, retrying, and only while verified: given_names, family_name, name, public (what the record shows to everyone), citations (OpenAlex counts) |
follows |
followers, following |
list_count |
public lists |
ariadne_citations |
received, self, cited_articles, thread (score, articles; the person’s Thread Score) |
seals |
sealed_articles, qualified_reviews |
publications[] |
as submitter and as co-author: article_id, role, accepted, status, status_name, fields, article_type, title, validation_status, cid, published_at, vote_total, seal, entitled, claimed_total, claimable, claim_allowed |
claimable_total |
reputation the address can claim now, over all its articles |
reviews[], comments[] |
with the article’s title; reviews also carry counted and not_counted_reason |
reputation[] |
per field: field_id, hex, name, rep, updated_at, cap_day, cap_today |
timeline[] |
the address’s own events, newest first, at most 200 |
curl https://api.ariadne.press/testnet/users/YOUR_ADDRESSGET /users/:address/notifications
Section titled “GET /users/:address/notifications”| Parameter | Meaning |
|---|---|
unread |
1 or true: unread only |
limit |
1 to 100, default 50 |
Returns { address, unread, notifications: [...] }, newest first; each has id, kind, article_id,
comment_seq, actor, ts, read and the article’s title. Kinds: reply, mention, comment_on_my_article,
review_on_my_article, comment_resolved, coauthor_invite, followed. The API is read-only: the web app keeps
read marks in the browser.
GET /users/:address/following and /followers
Section titled “GET /users/:address/following and /followers”Active on-chain follows, newest first: { address, total, following: [...] } or { address, total, followers: [...] }.
GET /users/:address/feed
Section titled “GET /users/:address/feed”Publications, confirmed co-authorships, reviews and comments of everyone the address follows, newest first:
{ address, activity: [...] }, each item with kind (published, coauthored, reviewed, commented), actor,
article_id, seq, reply_to, ts, title. Page backwards with before.
GET /activity?address=
Section titled “GET /activity?address=”The same activity for up to 50 addresses given as repeated parameters (address=A&address=B): { activity: [...] }.
GET /users/:address/citations
Section titled “GET /users/:address/citations”The citations the address’s articles received from ARIADNE articles, newest citing article first:
{ address, total, citations: [...] }, each with citing (article_id, title, author, created_at, type),
cited (article_id, title), kind and self (the address also wrote the citing article).
GET /orcid/:id
Section titled “GET /orcid/:id”The addresses whose declaration of this ORCID iD is verified: { orcid, addresses: [...] }. 400 when the check
character is wrong.
Lists and bibliographies
Section titled “Lists and bibliographies”GET /users/:address/lists
Section titled “GET /users/:address/lists”Public lists, newest change first: { address, lists: [...] }, each with list_id, name, about, created_at,
updated_at, count and preview (the last three articles added). With article=<id>, each list also says whether it
holds that article (contains).
GET /users/:address/lists/:id
Section titled “GET /users/:address/lists/:id”One public list (list: owner, list_id, name, about, created_at, updated_at, count) and its articles, last
added first, each with the list fields and added_at. 404 when the address has no such list.
GET /cite
Section titled “GET /cite”What a bibliography needs of each article: ?ids=1,2,3 (1 to 1 000 ids) or ?owner=<address>&list=<id> (a whole
public list). Returns { articles: [...] } in the order asked, unknown ids left out; each with article_id, title,
type, status_name, version, published, cid, authors[] (address, orcid) and dois[] (version, doi,
status).
Search
Section titled “Search”Full-text search over articles, reviews and comments, and people (D-120, D-121). See Search for the query syntax as readers use it.
Query syntax: words (all required), "a phrase", -word, OR, prefix*, the parts title:, abstract:, keyword:,
body:, author: (a name or an address) and field:, and exact lookups doi: (or a bare DOI), cid: and #12.
Wildcards inside a word (wom?n, *ology) and regular expressions between slashes (/memor(y|ies)/, title:/^sleep/,
-/x/) are tested on the texts without accents, case ignored. Highlighted words come between the characters U+0002 and
U+0003, never as HTML.
GET /search/articles
Section titled “GET /search/articles”| Parameter | Meaning |
|---|---|
q |
the query |
field |
fields (primary or secondary, unless primary_only=true) |
primary_only |
match field against the primary field only |
area |
areas (the high byte of a field id, 1 to 6), matched against the primary or secondary field |
type |
types |
status |
statuses; retracted articles are left out unless chosen; all for every status |
author |
an address (submitter or accepted co-author) |
submitter_only |
author must be the submitter |
reviewer, commenter |
an address that reviewed or commented on the article |
followed_by |
articles by people this address follows |
orcid |
an author’s verified ORCID iD |
published_from, published_to |
publication date (YYYY, YYYY-MM or YYYY-MM-DD, UTC; _to inclusive) |
updated_from, updated_to |
the article’s updated_at, same format: the last call that changed its on-chain record (a version, a status change, an article vote, a review, a comment, a flag…) |
min_votes, min_voters |
minimum vote weight, minimum number of votes |
min_reviews, max_reviews |
number of reviews |
recommendation |
recommendations received (names or 1 to 4) |
min_comments |
number of comments |
has_doi, doi_verified |
a DOI that is verified, cannot be checked (declared) or is not checked yet (never one whose record does not point back); a verified DOI |
orcid_verified |
at least one author with a verified ORCID iD |
sealed |
holds the Peer-reviewed seal |
language, license |
from the front-matter |
valid_only |
content checked as valid |
revised |
has more than one version |
amends |
amendments of this article number |
has_amendments |
has been amended |
keyword |
keywords |
sort |
relevance (default with a query), score (default without), new, old, votes, reviews, comments, updated, cited (most cited on ARIADNE) |
limit, offset |
paging |
Returns query (how the query was read: terms, doi, cid, article_id, authors, notes, sort), total,
articles (the list fields plus review_count, comment_count, cited_by, authors, doi and match, the
highlighted passages) and facets. Each facet counts its options under every other filter in use: fields, areas,
types, statuses, years, languages, licenses, recommendations, has_doi, doi_verified, orcid_verified,
revised, sealed, unreviewed, reviewed, valid, has_amendments.
curl "https://api.ariadne.press/testnet/search/articles?q=sleep&field=0x0303&sealed=true&sort=new"GET /search/posts
Section titled “GET /search/posts”Reviews and comments by their text.
| Parameter | Meaning |
|---|---|
q |
the query |
kind |
review, comment |
recommendation |
for reviews (names or 1 to 4) |
field |
the article’s primary or secondary field |
author |
an address |
article |
an article number |
from, to |
dates, same format as above |
sort |
relevance (default with a query), new (default without), old, votes |
Returns query, total, posts (kind, article_id, seq, author, author_name, reply_to_review,
recommendation, created_at, votes, reply_to, article_title, article_status, primary_field,
text_available, excerpt) and facets.
GET /search/people
Section titled “GET /search/people”| Parameter | Meaning |
|---|---|
q |
a verified ORCID name, an ORCID iD or the start of an address |
role |
author, reviewer, commenter |
field |
reputation in this field |
orcid_verified |
only people with a verified ORCID iD |
address |
specific addresses |
sort |
relevance (default with a query), reputation (default without), publications, reviews, recent |
Returns { total, people, notes }.
GET /search/suggest
Section titled “GET /search/suggest”Suggestions while typing: { articles, keywords, fields, people } for q, at most limit (1 to 10, default 5) of
each.
Fields
Section titled “Fields”GET /fields
Section titled “GET /fields”The registered fields, { fields: [...] }, each with field_id, name, hex and articles (articles that are not
retracted, under this field as primary or secondary). See Fields.
Notifications for push senders
Section titled “Notifications for push senders”GET /notifications?after=
Section titled “GET /notifications?after=”Every address’s notifications created after the id after, oldest first, with latest (the highest id so far). The
web server’s Web Push sender polls this route, one request per network. Notifications are public data already.
curl "https://api.ariadne.press/testnet/notifications?after=0&limit=10"