When running mix exograph.web, a JSON API is available alongside the web UI.
Endpoints
POST /api/search
Structural or text search.
curl -X POST http://localhost:4200/api/search \
-H "Content-Type: application/json" \
-d '{"pattern": "Repo.get!(_, _)", "limit": 10}'Parameters:
pattern(required) — search pattern or text querymode—"structural"(default),"text", or"regex"limit— max results (default: 50, max: 200)cursor— pagination cursor from previous responsepackage_id— scope to a specific package
Response:
{
"results": [{"type": "def", "file": "lib/repo.ex", "package": "ecto", ...}],
"count": 10,
"elapsed_ms": 23.4,
"next_cursor": "MTA"
}POST /api/query
Execute a DSL query.
curl -X POST http://localhost:4200/api/query \
-H "Content-Type: application/json" \
-d '{"query": "from(d in Definition, where: d.kind == :def, where: prefix_search(d.name, \"handle\"))"}'Parameters:
query(required) — DSL query stringcursor— pagination cursor
GET /api/packages
List indexed packages sorted by fragment count.
curl http://localhost:4200/api/packagesGET /api/stats
Index statistics.
curl http://localhost:4200/api/statsRate Limiting
The API is rate limited to 60 requests per minute per IP.
Headers x-ratelimit-limit and x-ratelimit-remaining are included in responses.
Exceeding the limit returns HTTP 429.
Security
Query execution uses a safe AST interpreter — no Code.eval_string.
Dangerous operations (System.cmd, File.read!, etc.) are rejected at parse time.
Value expressions in predicates are evaluated through the Dune sandbox.