Developer API
Koalr Public API
Integrate engineering metrics into your own tools, dashboards, and workflows. RESTful API with API key authentication and a stable versioned base URL.
Quick start
Fetch your DORA metrics in one curl command. Replace YOUR_API_KEY with a key from Settings → API Keys.
curl -s \
-H "X-Koalr-Key: YOUR_API_KEY" \
"https://api.koalr.com/api/v1/metrics/dora?days=30"Base URL: https://api.koalr.com
Authentication
All requests must include your API key in the X-Koalr-Key header. API keys are scoped to your organisation and inherit your seat permissions.
curl -s \
-H "X-Koalr-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
"https://api.koalr.com/api/v1/teams"Endpoints
All endpoints are versioned under /api/v1/. Responses are JSON. Timestamps use ISO 8601 UTC.
Metrics
/api/v1/metrics/doraDORA metrics summary for your organisation.
| days | number | Rolling window in days (default 30) |
{
"deployFrequency": 4.2,
"leadTime": 18.5,
"changeFailureRate": 0.04,
"mttr": 42,
"tier": "elite"
}/api/v1/flowFlow metrics: cycle time, throughput, WIP, and flow efficiency.
| days | number | Rolling window in days (default 30) |
| teamId | string | Filter by team ID |
{
"cycleTime": 2.4,
"throughput": 18,
"wipCount": 6,
"flowEfficiency": 0.61
}/api/v1/review-metricsCode review metrics including average cycle time and first response time.
| days | number | Rolling window in days (default 30) |
| teamId | string | Filter by team ID |
{
"avgReviewCycleTime": 6.1,
"avgFirstResponseTime": 1.8,
"totalReviewed": 94
}/api/v1/copilotGitHub Copilot usage metrics: adoption rate, acceptance rate, and estimated hours saved.
| days | number | Rolling window in days (default 30) |
{
"adoptionRate": 0.74,
"acceptanceRate": 0.38,
"estimatedHoursSaved": 312
}/api/v1/value-streamEnd-to-end value stream metrics across the software delivery lifecycle.
| days | number | Rolling window in days (default 30) |
{
"ideaToCommit": 3.2,
"commitToMerge": 1.1,
"mergeToDeploy": 0.4,
"totalLeadTime": 4.7
}/api/v1/custom-metrics/:slug/queryRun a saved custom metric by its slug. Returns the computed result for the current period.
| slugrequired | string | Custom metric slug (path parameter) |
| days | number | Rolling window in days (default 30) |
{
"slug": "p95-cycle-time",
"label": "P95 Cycle Time",
"value": 8.4,
"unit": "hours",
"period": "last_30_days"
}Deployments & Pull Requests
/api/v1/deploymentsList deployments within a rolling window, optionally filtered by team.
| days | number | Rolling window in days (default 30) |
| teamId | string | Filter by team ID |
{
"data": [
{
"id": "dep_01j8x",
"repo": "acme/api",
"env": "production",
"status": "success",
"deployedAt": "2026-03-14T18:22:00Z",
"leadTimeSecs": 67200
}
],
"total": 42,
"page": 1
}/api/v1/pull-requestsList pull requests within a rolling window with pagination support.
| days | number | Rolling window in days (default 30) |
| teamId | string | Filter by team ID |
| page | number | Page number (default 1) |
| pageSize | number | Results per page (default 25, max 100) |
{
"data": [
{
"id": "pr_a1b2c3",
"number": 1847,
"title": "feat: add retries to webhook processor",
"repo": "acme/api",
"author": "jsmith",
"mergedAt": "2026-03-14T14:11:00Z",
"cycleTimeSecs": 86400,
"riskScore": 42
}
],
"total": 184,
"page": 1,
"pageSize": 25
}/api/v1/incidentsList incidents sourced from PagerDuty, Opsgenie, or incident webhooks.
| days | number | Rolling window in days (default 30) |
{
"data": [
{
"id": "inc_9z2k",
"title": "API p99 latency spike",
"severity": "sev2",
"status": "resolved",
"startedAt": "2026-03-10T03:14:00Z",
"resolvedAt": "2026-03-10T04:02:00Z",
"mttrSecs": 2880
}
],
"total": 7
}Teams
/api/v1/teamsList all teams in your organisation.
{
"data": [
{
"id": "team_abc123",
"name": "Platform",
"memberCount": 8,
"createdAt": "2025-11-01T00:00:00Z"
},
{
"id": "team_def456",
"name": "Growth",
"memberCount": 5,
"createdAt": "2025-11-01T00:00:00Z"
}
],
"total": 2
}Forecasting
/api/v1/forecast/deliveryMonte Carlo delivery forecast. Given a number of items, returns P50/P85/P95 completion dates.
| itemsrequired | number | Number of backlog items to forecast |
| teamId | string | Scope forecast to a specific team |
{
"items": 20,
"teamId": "team_abc123",
"p50": "2026-04-11",
"p85": "2026-04-25",
"p95": "2026-05-09",
"simulations": 10000
}/api/v1/forecast/backlogBacklog throughput forecast using historical velocity.
| teamId | string | Filter by team ID |
{
"weeklyThroughputP50": 7,
"weeklyThroughputP85": 12,
"backlogSize": 68,
"weeksToEmpty": {
"p50": 10,
"p85": 16
}
}AI & Risk
/api/v1/pr-risk/scoreScore a pull request for deployment risk using Koalr's 32-signal model. Returns a risk score 0–100 with a breakdown by signal category.
| prNumberrequired | number | Pull request number |
| reporequired | string | Repository name (e.g. "api") |
| ownerrequired | string | GitHub organisation or user (e.g. "acme") |
{
"prNumber": 1847,
"repo": "acme/api",
"riskScore": 71,
"tier": "high",
"signals": {
"changeEntropy": 0.82,
"coverageDelta": -0.06,
"authorFileExpertise": 0.44,
"codeownersCompliance": true,
"aiAuthoredRatio": 0.31
},
"recommendation": "Review carefully — high change entropy and coverage regression detected."
}POST requests
POST endpoints accept a JSON body. Set Content-Type: application/json.
curl -s -X POST \
-H "X-Koalr-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"prNumber": 1847, "repo": "api", "owner": "acme"}' \
"https://api.koalr.com/api/v1/pr-risk/score"Rate limits
| Plan | Requests / minute | Notes |
|---|---|---|
| All plans | 60 | Per API key, sliding window |
| Burst | Up to 120 | 30-second burst allowance |
Rate limit headers are included in every response: X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset. A 429 response means you have exceeded the limit — retry after the reset timestamp.
Error codes
| Status | Meaning |
|---|---|
| 200 | Success |
| 400 | Bad request — invalid parameters |
| 401 | Missing or invalid X-Koalr-Key header |
| 403 | Valid key but insufficient permissions |
| 404 | Resource not found |
| 429 | Rate limit exceeded |
| 500 | Internal server error — contact support |
SDKs & examples
Official SDKs are coming soon. In the meantime, the REST API works with any HTTP client.
Want to contribute an SDK or see a language prioritised? Let us know.
Ready to integrate?
Generate an API key in Settings and start pulling live engineering metrics into your own workflows in minutes.