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"}
Authentication
Section titled “Authentication”All endpoints (when AUTH_ENABLED=true) require an API key:
X-API-Key: prdb_your_key_hereCreate keys in the dashboard: Settings → API Keys → New Key.
Projects
Section titled “Projects”List projects
Section titled “List projects”GET /api/projectsResponse:
[ { "id": "550e8400-e29b-41d4-a716-446655440000", "name": "my-api", "description": "API load tests", "createdAt": "2026-01-15T09:00:00Z" }]Create project
Section titled “Create project”POST /api/projectsContent-Type: application/json
{ "name": "my-api", "description": "API load tests"}Get project
Section titled “Get project”GET /api/projects/{projectId}Delete project
Section titled “Delete project”DELETE /api/projects/{projectId}Test Runs
Section titled “Test Runs”List runs
Section titled “List runs”GET /api/test-runs?projectId={uuid}&limit=20&offset=0Query parameters:
| Param | Type | Description |
|---|---|---|
projectId | UUID | Filter by project (required) |
tool | string | Filter by tool: jmeter, k6, gatling |
from | ISO 8601 | Start date |
to | ISO 8601 | End date |
limit | int | Default 20, max 100 |
offset | int | Pagination offset |
Get run
Section titled “Get run”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": {}}Create run (direct API upload)
Section titled “Create run (direct API upload)”POST /api/test-runsContent-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 run
Section titled “Delete run”DELETE /api/test-runs/{runId}Trends
Section titled “Trends”Get trend data
Section titled “Get trend data”GET /api/trends/project/{projectId}?metric=p95&limit=30Parameters:
| Param | Default | Description |
|---|---|---|
metric | p95 | p50, p75, p90, p95, p99, avg, errorRate, throughput |
limit | 30 | Number of recent runs |
from / to | — | Date range filter |
Regression detection
Section titled “Regression detection”GET /api/trends/project/{projectId}/regression?threshold=10&metric=p95Parameters:
| Param | Default | Description |
|---|---|---|
threshold | 10 | % degradation that constitutes a regression |
metric | p95 | Metric to evaluate |
lookback | 10 | Number of recent runs to compare |
Response:
{ "regression": true, "metric": "p95", "baselineValue": 387, "currentValue": 431, "deltaPercent": 11.4, "threshold": 10}Period comparison
Section titled “Period comparison”GET /api/trends/project/{projectId}/compare ?currentStart=2026-03-01¤tEnd=2026-03-15 &baselineStart=2026-02-01&baselineEnd=2026-02-15Baselines
Section titled “Baselines”Tag run as baseline
Section titled “Tag run as baseline”POST /api/test-runs/{runId}/baselineContent-Type: application/json
{ "name": "v2.1.0 post-optimisation"}List baselines
Section titled “List baselines”GET /api/baselines?projectId={uuid}Compare run against baseline
Section titled “Compare run against baseline”POST /api/baselines/{baselineId}/compareContent-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} }}Set SLA thresholds
Section titled “Set SLA thresholds”POST /api/projects/{projectId}/slaContent-Type: application/json
{ "p95MaxMs": 1500, "p99MaxMs": 3000, "errorRateMaxPercent": 1.0, "apdexMinScore": 0.85, "avgMaxMs": 500}Get SLA summary
Section titled “Get SLA summary”GET /api/sla/summary?projectId={uuid}&days=30Response:
{ "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}] } ]}Webhooks
Section titled “Webhooks”Create webhook
Section titled “Create webhook”POST /api/webhooksContent-Type: application/json
{ "url": "https://hooks.slack.com/services/...", "events": ["test_run_completed", "sla_breached", "regression_detected"], "projectId": "uuid" // omit for all projects}List webhooks
Section titled “List webhooks”GET /api/webhooksDelete webhook
Section titled “Delete webhook”DELETE /api/webhooks/{webhookId}Webhook payload
Section titled “Webhook payload”{ "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" }}Error Responses
Section titled “Error Responses”| Status | Meaning |
|---|---|
400 | Bad request — check request body |
401 | Missing or invalid API key |
403 | Insufficient permissions |
404 | Resource not found |
409 | Conflict (e.g., duplicate project name) |
422 | Validation error |
429 | Rate limit exceeded |
500 | Internal server error |
Error body:
{ "error": "PROJECT_NOT_FOUND", "message": "No project with id 550e8400-..."}