aadhar.sh/developers
Address
aadhar.shaadhar.sh/developers

Developers

Everything on aadhar.sh can be read from code. The endpoints are read-only, need no key or signup, and production is the sandbox: there is nothing to break.

OpenAPI 3.1
/openapi.json
MCP server
https://aadhar.sh/mcp (card: server-card.json)
API catalog
/.well-known/api-catalog (RFC 9727)
Site map for agents
/llms.txt
Authentication
none

Quickstart

Search the site, then read the page you found as Markdown:

curl 'https://aadhar.sh/search.json?q=fhe&limit=3'
curl -H 'Accept: text/markdown' https://aadhar.sh/lwe/fhe

Ask a question in plain language (NLWeb), as one JSON body:

curl 'https://aadhar.sh/ask?query=how+does+the+site+sign+requests&streaming=0'

See how a machine reads any public URL:

curl 'https://aadhar.sh/lens/fetch?url=example.com'

Find a Fuji film recipe in the photo archive:

curl 'https://aadhar.sh/photos/query.json?recipe=DR400&limit=5'

Endpoints

Every operation in /openapi.json has an operationId, typed parameters and a response schema, so a client can turn it into function-calling tools directly. The MCP server exposes the same capabilities as tools.

Limits

The endpoints share a read budget of 120 requests a minute per caller, named on each answer as RateLimit-Policy: "read";q=120;w=60. The Lens doors have tighter budgets of their own instead: inspections are limited to 30 a minute per caller, shared with the MCP server, and comparisons to 4 a minute. Each answer names its quota in a RateLimit-Policy header ("inspect";q=30;w=60). Over any limit, an endpoint answers 429 with Retry-After: 60 and a RateLimit header showing nothing left, the fields the IETF RateLimit draft defines. /ask ranks 20 questions a minute per caller with its model, then falls back to lexical ranking and says so in _meta.ranking instead of refusing. Please cache what you read; most endpoints send a Cache-Control that says for how long.

Errors

Errors are JSON with at least an error sentence, and most add a code token. A path that does not exist answers 404 in the format you ask for: JSON for Accept: application/json, Markdown for Accept: text/markdown, with the closest real pages. A path that looks like an API call (ending in .json, or under /api/ or /v1/) answers JSON unless you ask for HTML. A method an endpoint does not serve answers 405 in the same shape, with an Allow header. This is the body the site sends for /no-such-endpoint.json:

{
  "ok": false,
  "error": "/no-such-endpoint.json is not a page or endpoint on aadhar.sh.",
  "code": "not_found",
  "status": 404,
  "hint": "Every page is listed in /sitemap.xml, and every JSON endpoint in /openapi.json.",
  "docs": "https://aadhar.sh/developers"
}

What this API leaves out

A public API usually carries the machinery below. This one skips each piece on purpose, for the reason beside it, so a readiness audit that marks one missing is reading a decision this site already made.

Keys, accounts and OAuth
Every endpoint is public and read-only, so a credential would unlock nothing. The site once issued anonymous OAuth tokens that no endpoint checked, and dropped them.
Version headers and pinning
One person maintains the API, and it has one live shape: the one /openapi.json describes. New endpoints, parameters and fields arrive without notice, so ignore fields you don't know.
Deprecation and Sunset headers
A notice period protects clients that depend on an exact shape, and none is known here. A breaking change lands in /openapi.json the day it ships.

Pages as Markdown

Most pages answer Accept: text/markdown at their own URL, and static documents also have a .md twin (/garage/encoding becomes /garage/encoding.md). /llms.txt maps the site, and /llms-full.txt inlines it.

Questions

Write to coffee@aadhar.sh. How the site treats what you send is on /privacy.