Docs/API Reference

API Reference

The Upshot API lets you programmatically access reports, metrics, activity data, and more.

Base URL

https://api-upshot.wellcode.ai/v1

Authentication

All API requests require a Bearer token. You can use either:

  • API Key — generated in Settings → API Keys (recommended for server-to-server)
  • JWT — obtained via the login endpoint (for user-scoped access)
curl -H "Authorization: Bearer YOUR_API_KEY" \
  https://api-upshot.wellcode.ai/v1/metrics/dora

Rate limits

PlanRequests/minRequests/day
Free301,000
Pro12010,000
Enterprise600100,000

Rate limit headers are included in every response: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.

Endpoints

GET /metrics/dora

Retrieve DORA metrics for your organization.

GET /v1/metrics/dora?period=last_30_days&team=backend

{
  "deployment_frequency": {
    "value": 4.2,
    "unit": "deploys_per_week",
    "rating": "high",
    "trend": "+12%"
  },
  "lead_time": {
    "value": 18.5,
    "unit": "hours",
    "rating": "high",
    "trend": "-8%"
  },
  "change_failure_rate": {
    "value": 4.1,
    "unit": "percent",
    "rating": "elite",
    "trend": "-2%"
  },
  "mttr": {
    "value": 2.3,
    "unit": "hours",
    "rating": "high",
    "trend": "-15%"
  }
}

GET /activity

Fetch the activity feed with optional filters.

GET /v1/activity?from=2025-02-01&to=2025-02-15&source=github&limit=50

{
  "items": [
    {
      "id": "act_abc123",
      "type": "pr_merged",
      "source": "github",
      "title": "Add CSV export to reports",
      "author": "[email protected]",
      "timestamp": "2025-02-14T15:30:00Z",
      "metadata": {
        "repo": "acme/webapp",
        "pr_number": 847,
        "additions": 342,
        "deletions": 58
      }
    }
  ],
  "cursor": "eyJpZCI6ImFjdF94..."
}

POST /reports/generate

Trigger report generation.

POST /v1/reports/generate
Content-Type: application/json

{
  "audience": "team",
  "period": {
    "from": "2025-02-01",
    "to": "2025-02-15"
  },
  "format": "slack"
}

// Response
{
  "report_id": "rpt_xyz789",
  "status": "generating",
  "estimated_seconds": 45
}

GET /reports/:id

Retrieve a generated report.

GET /v1/reports/rpt_xyz789

{
  "id": "rpt_xyz789",
  "status": "ready",
  "audience": "team",
  "format": "slack",
  "content": "## Engineering Update — Feb 1–15\n\n...",
  "created_at": "2025-02-15T10:00:00Z",
  "word_count": 487
}

GET /changelog

List published changelog entries.

GET /v1/changelog?limit=10

{
  "entries": [
    {
      "id": "cl_abc",
      "title": "Week of Feb 10",
      "published_at": "2025-02-14T12:00:00Z",
      "categories": {
        "features": 3,
        "improvements": 5,
        "fixes": 2
      },
      "url": "/changelog/week-of-feb-10"
    }
  ]
}

GET /contributors/:id/summary

Activity summary for a specific contributor.

GET /v1/contributors/usr_jane/summary?period=last_7_days

{
  "contributor": "[email protected]",
  "period": "last_7_days",
  "prs_merged": 4,
  "prs_reviewed": 7,
  "commits": 23,
  "issues_closed": 3,
  "lines_added": 1247,
  "lines_removed": 389,
  "deploy_contributions": 2
}

Errors

The API returns standard HTTP status codes with a consistent error body:

{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "You have exceeded 30 requests per minute. Please retry after 45 seconds.",
    "retry_after": 45
  }
}

SDKs & libraries

Official SDKs are coming soon. In the meantime, the REST API works with any HTTP client. See the MCP integration for AI-native access.