Base URL: https://api.cito.fim.ai
Authentication
Optional for search. Pass an API key with either header; create keys at Account → API keys. Endpoints under /me always require one.
Authorization: Bearer sk_...
X-API-Key: sk_...Rate limits
- Anonymous (no key): 15 requests/min per IP.
- With an API key: the key's own per-minute limit; keys created without an explicit limit follow the server default (currently 100/min). The enforced limit for each of your keys is shown at Account → API keys.
- Over the limit:
429with{"detail": "Rate limit exceeded."}
MCP server
The API doubles as an MCP server (streamable HTTP) at https://api.cito.fim.ai/mcp, exposing search_papers and get_paper as tools. One command in Claude Code:
claude mcp add --transport http cito https://api.cito.fim.ai/mcpOptionally pass an API key to use the per-key tier instead of the anonymous per-IP limit:
claude mcp add --transport http cito https://api.cito.fim.ai/mcp \
--header "Authorization: Bearer sk_..."Any MCP client that speaks streamable HTTP works the same way (Claude Desktop, Cursor, …). MCP calls share the rate tiers and metering of /search.
GET /search
qstring, requiredNatural-language or keyword query.modestringhybrid(default) ·semantic·keywordlimitintMax results. Default 20, max 100.enrichboolAttach title/abstract/authors from the local metadata store. Default true.published_beforestring, YYYY-MM-DDLeak-safe date gate: only papers published strictly before this date, filtered before the pool is cut to limit. Year-only papers are kept iff the year is strictly earlier; same-year and undated papers are excluded.include_impreciseboolWith published_before: also keep papers whose date is too coarse to prove precedence (same-year year-granularity, undated). Default false.
curl "https://api.cito.fim.ai/search?q=contrastive+learning&limit=5"Response:
{
"query": "attention is all you need",
"mode": "hybrid",
"took_ms": 257,
"hits": [
{
"id": "13756489",
"title": "Attention is All you Need",
"abstract": "...",
"authors": ["Ashish Vaswani", "..."],
"year": 2017,
"publication_date": "2017-06-12",
"date_granularity": "day",
"venue": "NeurIPS",
"doi": "...",
"url": "https://www.semanticscholar.org/p/13756489",
"pdf_url": "...",
"cites": 100000,
"score": 0.97
}
],
"corpus_release": "2026-06-24",
"attribution": "Data from Semantic Scholar"
}id is a Semantic Scholar CorpusID. doi, pdf_url, cites and publication_date may be null; date_granularity is day, year or null. Ordering is deterministic: the same query on the same snapshot replays identically (ties broken by CorpusID). Errors: 401 (invalid key), 422 (malformed published_before), 429 (rate limit), 503 (backend temporarily down).
GET /paper/{corpusid}
One paper's metadata by CorpusID: the same fields as a search hit minus score. 404 if unknown.
curl "https://api.cito.fim.ai/paper/13756489"GET /status
Index and feature status: auth_required, rerank_enabled, corpus_release (snapshot date) and index counts.
GET /me · GET /me/usage
Your account, keys and recent usage. Both require an API key.
Python
import requests
r = requests.get(
"https://api.cito.fim.ai/search",
params={"q": "attention is all you need", "limit": 5},
headers={"Authorization": "Bearer sk_..."}, # optional
timeout=30,
)
for hit in r.json()["hits"]:
print(hit["id"], hit["title"])Data & attribution
Data from Semantic Scholar and OpenAlex; see Licensing. Responses carry an attribution field; keep it when you republish results.