Skip to main content
Manage projects for multi-tenant data isolation. All scan data (HTTP records, findings, scopes, scans) is scoped to a project via project_uuid.
Note: These endpoints manage project records themselves. To scope API operations to a specific project, use the X-Project-UUID request header on other endpoints.

GET /api/projects — List Projects

Returns all projects with aggregated statistics. Optionally filter by owner UUID. Query parameters:
ParameterTypeDefaultDescription
ownerstringFilter by owner UUID
# List all projects
curl -s http://localhost:9002/api/projects | jq .

# Filter by owner
curl -s 'http://localhost:9002/api/projects?owner=00000000-0000-0000-0000-000000000001' | jq .
[
  {
    "uuid": "00000000-0000-0000-0000-000000000001",
    "name": "default",
    "description": "Default project",
    "owner_uuid": "00000000-0000-0000-0000-000000000001",
    "created_at": "2026-02-19T10:00:00Z",
    "updated_at": "2026-02-19T10:00:00Z",
    "stats": {
      "http_records": {
        "total": 1234,
        "success": 980,
        "redirect": 54,
        "client_err": 180,
        "server_err": 20
      },
      "findings": {
        "total": 42,
        "critical": 2,
        "high": 10,
        "medium": 15,
        "low": 10,
        "info": 5
      },
      "scans": 3,
      "agent_runs": 7,
      "source_repos": 2,
      "oast_interactions": 12
    }
  }
]
Stats fields:
FieldTypeDescription
stats.http_records.totalintTotal HTTP records in the project
stats.http_records.successint2xx status code count
stats.http_records.redirectint3xx status code count
stats.http_records.client_errint4xx status code count
stats.http_records.server_errint5xx status code count
stats.findings.totalintTotal findings
stats.findings.criticalintCritical severity count
stats.findings.highintHigh severity count
stats.findings.mediumintMedium severity count
stats.findings.lowintLow severity count
stats.findings.infointInfo severity count
stats.scansintTotal scan sessions
stats.agent_runsintTotal agent runs
stats.source_reposintTotal linked source repositories
stats.oast_interactionsintTotal OAST (out-of-band) interactions
Errors:
CodeCondition
503Database not connected

POST /api/projects — Create Project

Request body:
FieldTypeRequiredDescription
namestringYesProject name
descriptionstringNoProject description
owner_uuidstringNoUUID of the owning user
curl -s -X POST http://localhost:9002/api/projects \
  -H 'Content-Type: application/json' \
  -d '{"name": "my-project", "description": "Web app audit"}' | jq .
{
  "uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "name": "my-project",
  "description": "Web app audit",
  "created_at": "2026-03-06T12:00:00Z",
  "updated_at": "2026-03-06T12:00:00Z"
}
Errors:
CodeCondition
400Missing name field
400Invalid request body
503Database not connected

GET /api/projects/:uuid — Get Project

Retrieve a single project by UUID with aggregated statistics.
curl -s http://localhost:9002/api/projects/a1b2c3d4-e5f6-7890-abcd-ef1234567890 | jq .
{
  "uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "name": "my-project",
  "description": "Web app audit",
  "owner_uuid": "00000000-0000-0000-0000-000000000001",
  "created_at": "2026-03-06T12:00:00Z",
  "updated_at": "2026-03-06T12:00:00Z",
  "stats": {
    "http_records": {
      "total": 567,
      "success": 450,
      "redirect": 30,
      "client_err": 72,
      "server_err": 15
    },
    "findings": {
      "total": 18,
      "critical": 1,
      "high": 4,
      "medium": 6,
      "low": 5,
      "info": 2
    },
    "scans": 2,
    "agent_runs": 3,
    "source_repos": 1,
    "oast_interactions": 5
  }
}
Errors:
CodeCondition
404Project not found
503Database not connected

PUT /api/projects/:uuid — Update Project

Update fields on an existing project. Only non-empty fields are applied. Request body:
FieldTypeRequiredDescription
namestringNoNew project name
descriptionstringNoNew description
owner_uuidstringNoNew owner UUID
curl -s -X PUT http://localhost:9002/api/projects/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
  -H 'Content-Type: application/json' \
  -d '{"description": "Updated description"}' | jq .
{
  "uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "name": "my-project",
  "description": "Updated description",
  "owner_uuid": "00000000-0000-0000-0000-000000000001",
  "created_at": "2026-03-06T12:00:00Z",
  "updated_at": "2026-03-06T12:30:00Z"
}
Errors:
CodeCondition
400Invalid request body
404Project not found
503Database not connected

DELETE /api/projects/:uuid — Delete Project

Delete a project by UUID. The default project (00000000-0000-0000-0000-000000000001) cannot be deleted. All data (scans, HTTP records, findings, scopes, source repos, OAST interactions, scan logs) belonging to the deleted project is automatically reassigned to the default project.
curl -s -X DELETE http://localhost:9002/api/projects/a1b2c3d4-e5f6-7890-abcd-ef1234567890 | jq .
{
  "message": "project deleted",
  "uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
Errors:
CodeCondition
400Attempting to delete default project
500Database deletion failed
503Database not connected