Skip to content

REST API Reference

Base URL: http://localhost:8080/api/v1

All protected endpoints require Authorization: Bearer <token>.

JWT access tokens and API keys use the same header format:

Authorization: Bearer <access_token_or_easm_api_key>

Auth

Method Path Description
POST /auth/register Create account
POST /auth/login Login, returns token pair
POST /auth/refresh Refresh access token
GET /me/me Current user
GET /me/users List users (admin)
GET /me/api-keys List own API keys
POST /me/api-keys Create API key
DELETE /me/api-keys/{id} Revoke API key

POST /auth/login

{ "email": "user@example.com", "password": "secret" }
→ { "tokens": { "access_token": "…", "refresh_token": "…" }, "user": { … } }

POST /me/api-keys

Create an API key:

{
  "name": "Assets read key",
  "permissions": ["read:assets"]
}

Response:

{
  "key": "easm_...",
  "api_key": {
    "id": "...",
    "name": "Assets read key",
    "key_prefix": "easm_...",
    "permissions": ["read:assets"]
  }
}

The raw key is only returned once when created.

Organizations

Method Path Description
GET /organizations List orgs (admin: all; others: assigned)
POST /organizations Create org
GET /organizations/{id} Get org
PATCH /organizations/{id} Update org
DELETE /organizations/{id} Delete org
GET /organizations/{id}/members List members
POST /organizations/{id}/members Add member

Scopes

Method Path Description
GET /organizations/{id}/scopes List scopes
POST /organizations/{id}/scopes Create scope (→ pending)
PATCH /scopes/{scope_id} Update scope
POST /scopes/{scope_id}/approve Approve (admin)
POST /scopes/{scope_id}/reject Reject (admin)

POST /organizations/{id}/scopes

{ "type": "domain", "value": "example.com", "description": "Main domain" }

Scans

Method Path Description
GET /organizations/{id}/scans List scans
POST /organizations/{id}/scans Create & queue scan
GET /scans/{scan_id} Get scan
POST /scans/{scan_id}/cancel Cancel scan
GET /scans/{scan_id}/jobs List scan jobs

POST /organizations/{id}/scans

{ "profile": "default", "scope_ids": ["<scope-uuid>"] }

Profiles are returned by GET /api/v1/scan-profiles and are defined in backend/configs/config.yaml.

Assets

Method Path Description
GET /organizations/{id}/assets List assets (paginated)
GET /organizations/{id}/assets/graph Get asset graph
GET /organizations/{id}/assets/stats Count by type
GET /assets/{asset_id} Get single asset

Query params for list: type, page, page_size

API key example: read:assets

Use an API key as a Bearer token. For example, with:

easm_b3d070d84cf7c121927d0bcbed23fcc287aaa29575f8d5dffe54919588458e0b

List assets for an organization:

curl "http://localhost:8080/api/v1/organizations/<organization_id>/assets?page=1&page_size=20" \
  -H "Authorization: Bearer easm_b3d070d84cf7c121927d0bcbed23fcc287aaa29575f8d5dffe54919588458e0b"

Filter by asset type:

curl "http://localhost:8080/api/v1/organizations/<organization_id>/assets?type=domain&page=1&page_size=20" \
  -H "Authorization: Bearer easm_b3d070d84cf7c121927d0bcbed23fcc287aaa29575f8d5dffe54919588458e0b"

Get the asset graph:

curl "http://localhost:8080/api/v1/organizations/<organization_id>/assets/graph" \
  -H "Authorization: Bearer easm_b3d070d84cf7c121927d0bcbed23fcc287aaa29575f8d5dffe54919588458e0b"

Replace <organization_id> with the UUID of the organization to query.

Vulnerabilities

Method Path Description
GET /organizations/{id}/vulnerabilities List vulns (paginated)
GET /organizations/{id}/vulnerabilities/stats Count by severity
GET /vulnerabilities/{id} Get single vuln
PATCH /vulnerabilities/{id}/status Update status
POST /vulnerabilities/{id}/retest Request retest

PATCH /vulnerabilities/{id}/status

{ "status": "confirmed", "note": "Verified manually" }

Valid status transitions: - new → confirmed | false_positive - confirmed → fixed | accepted_risk | retest_required - fixed → reopened | retest_required - false_positive / accepted_risk → reopened

Health check

GET /health
→ { "status": "ok", "time": "2026-04-29T…" }

Error format

All errors return JSON:

{ "error": "description" }

Exposure Changes

Method Path Description
GET /organizations/{id}/changes List exposure change timeline events
GET /organizations/{id}/changes/summary Summary counters for recent changes
GET /assets/{asset_id}/changes History for a single asset

List query params: change_type, entity_type, severity, asset_id, vulnerability_id, scan_id, date_from, date_to, limit, offset.

Summary query params: days defaults to 7.

Example summary response:

{
  "days": 7,
  "total": 21,
  "asset_discovered": 10,
  "service_discovered": 4,
  "url_discovered": 5,
  "path_discovered": 0,
  "certificate_discovered": 0,
  "vulnerability_discovered": 2,
  "file_collected": 0,
  "critical": 1,
  "high": 3
}

Exposure changes are read-only through the public API. They are generated internally when new assets, vulnerabilities, vulnerability status transitions, and file artifacts are persisted.