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 query
  • mode"structural" (default), "text", or "regex"
  • limit — max results (default: 50, max: 200)
  • cursor — pagination cursor from previous response
  • package_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 string
  • cursor — pagination cursor

GET /api/packages

List indexed packages sorted by fragment count.

curl http://localhost:4200/api/packages

GET /api/stats

Index statistics.

curl http://localhost:4200/api/stats

Rate 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.