Skip to content

perf-results-db API

Base URL: http://your-host:4000 (default port)

Interactive docs: GET /api/docs (Swagger/OpenAPI)

Health check: GET /api/health{"status":"ok","version":"1.0.0"}

All endpoints (when AUTH_ENABLED=true) require an API key:

X-API-Key: prdb_your_key_here

Create keys in the dashboard: Settings → API Keys → New Key.


GET /api/projects

Response:

[
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "my-api",
"description": "API load tests",
"createdAt": "2026-01-15T09:00:00Z"
}
]
POST /api/projects
Content-Type: application/json
{
"name": "my-api",
"description": "API load tests"
}
GET /api/projects/{projectId}
DELETE /api/projects/{projectId}

GET /api/test-runs?projectId={uuid}&limit=20&offset=0

Query parameters:

ParamTypeDescription
projectIdUUIDFilter by project (required)
toolstringFilter by tool: jmeter, k6, gatling
fromISO 8601Start date
toISO 8601End date
limitintDefault 20, max 100
offsetintPagination offset
GET /api/test-runs/{runId}

Response:

{
"id": "run-uuid",
"projectId": "project-uuid",
"tool": "k6",
"startedAt": "2026-03-01T14:00:00Z",
"duration": 300,
"metrics": {
"p50": 142, "p75": 210, "p90": 320, "p95": 387, "p99": 612,
"avg": 158, "min": 12, "max": 2341,
"errorRate": 0.002,
"throughput": 312.4,
"totalRequests": 93720
},
"tags": {"branch": "main", "env": "staging"},
"metadata": {}
}
POST /api/test-runs
Content-Type: application/json
{
"projectId": "project-uuid",
"tool": "k6",
"startedAt": "2026-03-01T14:00:00Z",
"duration": 300,
"metrics": {
"p50": 142, "p95": 387, "p99": 612,
"avg": 158, "min": 12, "max": 2341,
"errorRate": 0.002,
"throughput": 312.4,
"totalRequests": 93720
},
"tags": {"branch": "main"},
"metadata": {}
}
DELETE /api/test-runs/{runId}

GET /api/trends/project/{projectId}?metric=p95&limit=30

Parameters:

ParamDefaultDescription
metricp95p50, p75, p90, p95, p99, avg, errorRate, throughput
limit30Number of recent runs
from / toDate range filter
GET /api/trends/project/{projectId}/regression?threshold=10&metric=p95

Parameters:

ParamDefaultDescription
threshold10% degradation that constitutes a regression
metricp95Metric to evaluate
lookback10Number of recent runs to compare

Response:

{
"regression": true,
"metric": "p95",
"baselineValue": 387,
"currentValue": 431,
"deltaPercent": 11.4,
"threshold": 10
}
GET /api/trends/project/{projectId}/compare
?currentStart=2026-03-01&currentEnd=2026-03-15
&baselineStart=2026-02-01&baselineEnd=2026-02-15

POST /api/test-runs/{runId}/baseline
Content-Type: application/json
{
"name": "v2.1.0 post-optimisation"
}
GET /api/baselines?projectId={uuid}
POST /api/baselines/{baselineId}/compare
Content-Type: application/json
{
"runId": "run-uuid"
}

Response:

{
"baselineId": "baseline-uuid",
"runId": "run-uuid",
"metrics": {
"p95": {"baseline": 387, "current": 431, "delta": 44, "deltaPercent": 11.4},
"errorRate": {"baseline": 0.002, "current": 0.002, "delta": 0, "deltaPercent": 0}
}
}

POST /api/projects/{projectId}/sla
Content-Type: application/json
{
"p95MaxMs": 1500,
"p99MaxMs": 3000,
"errorRateMaxPercent": 1.0,
"apdexMinScore": 0.85,
"avgMaxMs": 500
}
GET /api/sla/summary?projectId={uuid}&days=30

Response:

{
"projectId": "uuid",
"period": "30 days",
"totalRuns": 42,
"passing": 38,
"failing": 4,
"violations": [
{
"runId": "uuid",
"date": "2026-03-10T02:00:00Z",
"breaches": [{"metric": "p95", "threshold": 1500, "actual": 1847}]
}
]
}

POST /api/webhooks
Content-Type: application/json
{
"url": "https://hooks.slack.com/services/...",
"events": ["test_run_completed", "sla_breached", "regression_detected"],
"projectId": "uuid" // omit for all projects
}
GET /api/webhooks
DELETE /api/webhooks/{webhookId}
{
"event": "test_run_completed",
"timestamp": "2026-03-15T14:30:00Z",
"data": {
"runId": "uuid",
"projectId": "uuid",
"projectName": "my-api",
"tool": "k6",
"metrics": { "p95": 387, "errorRate": 0.002 },
"slaStatus": "pass"
}
}

StatusMeaning
400Bad request — check request body
401Missing or invalid API key
403Insufficient permissions
404Resource not found
409Conflict (e.g., duplicate project name)
422Validation error
429Rate limit exceeded
500Internal server error

Error body:

{
"error": "PROJECT_NOT_FOUND",
"message": "No project with id 550e8400-..."
}