API Reference
The REST API behind the CLI, the dashboard and Aevrin MCP.
Base URL: https://api.mcp.aevrin.net. Every endpoint here is what the CLI, the
dashboard's own frontend, and Aevrin MCP actually call. Nothing is hidden behind a separate
"internal" API.
Authentication
Two schemes, depending on the caller:
A long-lived key from aevrin login, or minted manually from
Settings → API Keys on the dashboard. Sent as a header:
curl -H "X-API-Key: aevrin_xxxxx" https://api.mcp.aevrin.net/cli/precheckA Supabase session token, sent as a standard bearer token. This is what the web dashboard uses after you sign in, not something you would typically construct by hand.
curl -H "Authorization: Bearer <supabase-access-token>" https://api.mcp.aevrin.net/scansA few endpoints, such as finding triage, accept either an API key or a JWT, since both the
dashboard and aevrin findings triage need to call them.
Scans
| Method & path | Auth | Description |
|---|---|---|
POST /scans | JWT | Start a scan (dashboard-initiated). Runs async; poll stages/status. |
GET /scans | JWT | List your 25 most recent scans, newest first. |
GET /scans/{id} | JWT | Get one scan's status, score, and reliability info. On a scan that did not finish, fallback_report may hold a public report from an earlier scan of the same server: someone else's result, never this scan's. |
GET /scans/{id}/stages | JWT | Per-stage status (resolving, launching, enumerating, analyzing, grading). |
GET /scans/{id}/findings | JWT | Full findings list for a scan. A finding an AI review looked at carries ai_review (verdict: likely-real, likely-false-positive or unsure, with explanation, provider, model). |
GET /scans/{id}/engine-report | JWT or API key | The scan engine's full JSON report for this scan, exactly as stored. 404 with the reason when there is none (still running, stopped before the engine answered, an older scan or CLI, or larger than 1 MB). |
POST /scans/{id}/ai-review | JWT or API key | An AI second opinion on each finding, from your own AI provider, saved with the scan. Never changes a finding or the grade. At most 10 an hour. 409 when there is nothing to review; 200 with available: false and a reason when no provider could answer. |
GET /scans/{id}/export | JWT | OWASP MCP-mapped HTML report with Print / Save as PDF (Pro only). |
DELETE /scans/{id} | JWT | Delete one owned scan with its stages and findings. |
DELETE /scans | JWT | Clear all scan history owned by the current account. |
CLI upload
| Method & path | Auth | Description |
|---|---|---|
GET /cli/precheck | API key | Read-only credit check the CLI calls before running a local scan, so an account without the scan's 50 credits fails fast instead of scanning first. |
POST /cli/upload | API key | Persists a CLI-run scan's result. The grade is the one the CLI reported; it is not recomputed. An upload that contradicts itself (a grade with no enumerated tools, or an A or B beside a critical or high finding) is refused with 422. It may carry the engine's JSON report (engine_report, at most 1,000,000 bytes, else 422) and each finding's engine id as raw: {"id": ...}. See Concepts → Self-reported results. |
Findings
| Method & path | Auth | Description |
|---|---|---|
GET /findings/{id} | JWT | One finding's full detail, with ai_review when an AI review of its scan looked at it. |
PATCH /findings/{id} | JWT or API key | Update triage status (open, fixed, false_positive); false positives require a stored reason. |
Account
| Method & path | Auth | Description |
|---|---|---|
GET /account/usage | JWT | Current-period credits (allowance, used, remaining, top-up balance), the per-action costs, activity counts, and the latest 50 attributed scans with report IDs. |
Billing
| Method & path | Auth | Description |
|---|---|---|
GET /billing/pricing | None | Pro's monthly and annual prices and the credit top-up's one-time price in the caller's currency (USD, or INR from India), in cents or paise. |
GET /billing/subscription | JWT | Stored tier, the tier actually enforced (free or pro; free once the paid cycle has lapsed), and paid-through time. |
POST /billing/checkout | JWT | Create a Razorpay order for Pro (tier: "pro", one monthly or annual cycle) or a credit top-up (tier: "credit_topup", cycle: "one_time"), in USD or INR by the caller's location. |
POST /billing/verify | JWT | Verify checkout signature and activate the paid period, or grant the top-up's 5,000 credits. |
POST /billing/webhook | Razorpay signature | Recover a captured payment when the browser verification callback did not complete. |
GET /billing/payments | JWT | Your checkouts, most recent first, including ones that did not complete. |
Capabilities
The routes behind Aevrin MCP. The hosted MCP server calls them with the key your agent
sent; you would not normally call them yourself. GET /capabilities/search returns published capabilities only; GET /capabilities/{slug} and the
run route also reach an unlisted one by its exact slug, which is obscurity rather than access
control. Searching is free; a retrieval spends 1 credit and a run 10 more. A
retrieval may be answered from a five-minute cached copy, and it costs the same. The three
/capabilities/scans routes are the scan tools: they work like POST /scans and GET /scans/{id}
for the key's owner, spend a scan's 50 credits per scan started, and work whether or not capability
execution is on.
| Method & path | Auth | Description |
|---|---|---|
GET /capabilities/session | API key | Confirms the key is valid and the account is active. |
POST /capabilities/scans | API key | Start a scan of a public GitHub repository (github_repo) or a live https MCP server (live_mcp_server) for the key's owner. Body {target_type, target}; a pasted config is 422. Spends a scan's 50 credits. |
GET /capabilities/scans/{id} | API key | One of the key owner's scans, as GET /scans/{id} returns it. 404 for anyone else's. Not counted. |
GET /capabilities/scans/{id}/findings | API key | Its findings, most severe first, as GET /scans/{id}/findings returns them. Not counted. |
GET /capabilities/search | API key | Published capabilities matching a query, with the fields an administrator wrote for each. |
GET /capabilities/{slug} | API key | One capability by slug, with the instructions an administrator wrote and the tools Aevrin can run for it. Published, or unlisted by its exact slug. Spends 1 credit. |
POST /capabilities/{slug}/run | API key | Runs one tool of a capability. Body {tool, input, max_age_s}; max_age_s says how old an answer the caller accepts and 0 runs it fresh. The response carries cached, and untrusted: true on every result. Returns 503 not_enabled while capability execution is off, which is the case today. |
These routes refuse rather than allow when the account check cannot complete: a database error
returns 503, never a result.
Agent posture
What aevrin agent scan --upload sends, and what the dashboard's AI security views read back.
Every route here takes either a JWT or an API key, because the CLI uploads and the dashboard reads.
| Method & path | Auth | Description |
|---|---|---|
POST /agents/snapshots | JWT or API key | Store one machine's agent-configuration snapshot. Replaces that machine's previous record, carries no credential value, and is metered as one agent posture scan however many agents it reports. |
GET /agents | JWT or API key | Every device that has reported, with its score. |
GET /agents/{id} | JWT or API key | One device in full: capabilities with their evidence, MCP servers, skills, permission rules, and the files that were read. |
DELETE /agents/{id} | JWT or API key | Forget a device. Aevrin's copy goes; the machine's own configuration is untouched. |
GET /agents/mcp-servers | JWT or API key | Every MCP server across every reported device, correlated: one entry per server, not per configuration file. |
GET /agents/skills | JWT or API key | Every skill installed on every reported device. |
GET /agents/permissions | JWT or API key | Every permission rule across every device, exactly as written. |
GET /agents/attack-paths | JWT or API key | Paths with evidence behind every step. Speculative chains are absent. |
Device authorization
The CLI uses an RFC 8628-style browser approval flow. POST /device/code issues the
one-time user code and polling secret; POST /device/token returns only pending/slow-down/error
states until the signed-in browser approves that code. These endpoints are used by aevrin login;
applications should prefer manually created API keys for automation.
API keys
| Method & path | Auth | Description |
|---|---|---|
GET /api-keys | JWT | List your API keys (never returns plaintext after creation). |
POST /api-keys | JWT | Mint a new API key. The plaintext is shown exactly once. |
DELETE /api-keys/{id} | JWT | Revoke a key. |
Errors
Standard HTTP status codes. 402 Payment Required means your credits for the current billing
period are not enough for what the action costs, or a plan limit was reached (the monitored-device
count, or Aevrin MCP's compute time). The response body always includes bucket, resets_at, and
upgrade_url so a caller can build a real message instead of a bare refusal, and the shape is the
same whichever limit refused.
{
"detail": "Not enough credits for an MCP scan: it costs 50, 20 left. The monthly allowance resets on 2026-09-01; upgrading or topping up adds credits now.",
"bucket": "credits",
"resets_at": "2026-09-01T00:00:00Z",
"upgrade_url": "https://varq.aevrin.ai/settings/billing"
}