sciscape Publications

Sciscape API

Sciscape implements the SCI protocol 0.1 index interface plus a read-only catalog. Use the sci CLI for publishing, submission, and verification. Policy: /api/policy.

Shared behavior

Routes

GET /.well-known/sci/index.json

Index descriptor (SCI protocol §8.1) with Sciscape extensions.

Fields from api_schema onward are Sciscape extensions. Templates use the protocol’s {id} expansion.

GET /api/policy

Admission policy, quotas, source restrictions, proof limits, and timestamp trust policy (HTML).

GET /api/protocol

SCI protocol used by this Sciscape release.

Rendered HTML of the protocol bundled at the same commit as Sciscape’s vendored SCI library, with a link to that revision on GitHub. The document updates when the library pin changes.

GET /api/publications/{id}/sources

Publication lookup (SCI protocol §8.1.1), including registered publications outside the catalog.

GET https://sciscape.io/api/publications/<id>/sources
200 {"descriptors":["https://archive.example/.well-known/sci/archive.json"]}

{"descriptors":[]} means no known permitted source (unknown, blocked, or no working location). 400 invalid_id for malformed IDs; 503 if the database is unavailable.

GET /api/keys/{x}/revocation/{file}

Revocation lookup (SCI protocol §8.1.2). Not affected by moderation blocks.

file is revocation.json (served as application/json), revocation.json.sig, or revocation.json.sig.tsr (application/octet-stream). 404 proves nothing about revocation.

GET /api/publications/{id}/timestamps

Retained timestamp proofs (SCI protocol §8.1.3) as one timestamp file, application/octet-stream.

404 when no proof is retained or the publication is not a public catalog entry. Verify proofs under SCI protocol §6.8.

POST /api/submit/publication

Publication submission (SCI protocol §8.1.4). No account login.

POST https://sciscape.io/api/submit/publication
Content-Type: application/json

{"id":"<id>","descriptors":["https://raw.githubusercontent.com/OWNER/REPO/main/sci/archive.json"],
 "account":{"type":"domain","id":"lab.example"}}

Success: 201 (new catalog admission) or 200 with id, status (accepted or locations_recorded), publication_url, accepted_at (null outside the catalog), and for locations_recorded a reason (no_qualifying_association, revoked_key) and message.

Errors: 403 policy_refused (with reason), 403 not_baseline, 409, 413, 422 (failed checks; unsupported_schema distinct), 429 with Retry-After (rate limit or busy verifier), 503 (retryable).

POST /api/submit/key_revocation

Key revocation (multipart parts revocation.json, revocation.json.sig, optional revocation.json.sig.tsr).

Verified under SCI protocol §6.7, including for unknown or blocked keys. 200 with x and status: "revoked"; repeats return the same state. Timestamp results are reported separately.

POST /api/submit/timestamp

Timestamp proof submission (multipart parts id and manifest.json.sig.tsr) for admitted publications.

200 with id, retained_count, and per-value results; 404 if the publication is not admitted.

POST /api/submit/report

Mirror-failure or content report (JSON).

{"id":"<id>","kind":"mirror_failure","descriptor":"https://archive.example/.well-known/sci/archive.json","reason":"fetch_failed"}
{"id":"<id>","kind":"content","reason":"Free-text reason, at most 2,000 characters"}

202 with report_id. Mirror reasons match ^[a-z][a-z0-9_]{0,63}$ and the descriptor must be registered for the ID.

GET /api/catalog/{publications|citations|citation_counts|totals}

Read-only PostgREST views of schema sciscape_catalog_v1 (GET, HEAD, and CORS preflight only).

The gateway forces Accept-Profile: sciscape_catalog_v1 and needs no key. PostgREST query syntax, Content-Range, and native errors are preserved; other methods return 405.

GET /api/catalog/publications?id=eq.<id>&select=id,title,abstract,public_key
GET /api/catalog/publications?search_text=plfts(simple).neural%20decoding&order=accepted_at.desc,id.desc&limit=20
GET /api/catalog/publications?admission_accounts=cs.[{"type":"domain","id":"lab.example"}]&order=accepted_at.desc,id.desc&limit=20
GET /api/catalog/publications?categories=cs.[{"scheme":"arxiv","code":"cs.LG"}]&limit=20
GET /api/catalog/publications?public_key->>x=eq.<x>&limit=20
GET /api/catalog/publications?or=(accepted_at.lt.<time>,and(accepted_at.eq.<time>,id.lt.<id>))&order=accepted_at.desc,id.desc&limit=20
GET /api/catalog/citations?source_id=eq.<id>&order=position.asc&limit=100
GET /api/catalog/citations?target_key=eq.sci:sha256:<id>&order=source_id.asc,position.asc&limit=100
GET /api/catalog/citation_counts?target_key=eq.sci:sha256:<id>
GET /api/catalog/totals

publications fields: id, public_key, title, abstract, categories, keywords, display, accepted_at, admission_accounts, current_accounts, publisher_names, association_checked_at, revoked, descriptors, source_status, search_text, citing_publications, citing_publications_24h, citing_publications_48h, citing_publications_7d. Sort by citations with order=citing_publications.desc,accepted_at.desc,id.desc. citations: source_id, position, target, relations, reason, target_key. citation_counts: target_key, count, refreshed_at. totals: publications, citations, updated_at.

GET /p/{id} · /p/{prefix} · /reader?sha={id}[&archive={url}…]

Publication pages, prefix resolution, and the browser reader.

/p/{id}: 200 catalog page, 302 to the reader for registered publications outside the catalog, 404 unknown, 410 blocked, 503 unavailable. /p/{prefix} takes 12–63 lowercase hex characters. /reader accepts only sha and repeated HTTPS archive parameters.