API Overview
The CICosts API allows you to programmatically access your CI/CD cost data. Use it to build custom dashboards, automate reporting, and integrate with your existing tools.
Base URL
https://api.cicosts.dev/api/v1
For development:
https://dev-api.cicosts.dev/api/v1
API Availability
| Plan | Access Level |
|---|---|
| Free | Dashboard API (read-only), 3 repos |
| Pro | Full API access, unlimited repos |
| Team | Full access + higher rate limits |
Authentication
The API uses JWT tokens obtained through GitHub OAuth. All requests require a valid access token:
curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
https://api.cicosts.dev/api/v1/auth/me
See Authentication for details on obtaining tokens.
Response Format
All responses are JSON:
{
"total_cost": 247.50,
"trend_percent": -5.2,
"total_runs": 1247,
"avg_cost_per_run": 0.198
}
Error Responses
Errors include a detail message:
{
"detail": "Organization not found"
}
HTTP status codes:
400- Bad Request (invalid parameters)401- Unauthorized (missing/invalid token)403- Forbidden (insufficient permissions)404- Not Found429- Rate Limited500- Server Error
Rate Limits
Rate limits are applied per user per minute:
| Plan | Requests/Minute |
|---|---|
| Free | 60 |
| Pro | 300 |
| Team | 600 |
Rate limit headers are included in responses:
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 299
X-RateLimit-Reset: 1705320060
Available Endpoints
Authentication
| Endpoint | Method | Description |
|---|---|---|
/auth/login | GET | Initiate GitHub OAuth |
/auth/callback | GET | OAuth callback handler |
/auth/me | GET | Get current user |
/auth/refresh | POST | Refresh access token |
/auth/logout | POST | Invalidate token |
Dashboard
| Endpoint | Method | Description |
|---|---|---|
/dashboard/summary | GET | Cost summary for org |
/dashboard/trends | GET | Cost trends over time |
/dashboard/top-workflows | GET | Most expensive workflows |
/dashboard/recent-runs | GET | Recent workflow runs |
/dashboard/workflows | GET | List all workflows |
/dashboard/workflows/summary | GET | Workflow statistics |
Alerts
| Endpoint | Method | Description |
|---|---|---|
/alerts | GET | List all alerts |
/alerts | POST | Create new alert |
/alerts/{id} | GET | Get alert details |
/alerts/{id} | PUT | Update alert |
/alerts/{id} | DELETE | Delete alert |
/alerts/{id}/triggers | GET | Get trigger history |
/alerts/{id}/check | POST | Manually check alert |
Settings
| Endpoint | Method | Description |
|---|---|---|
/settings/user | GET | Get user settings |
/settings/user | PATCH | Update user settings |
/settings/notifications | GET | Get notification prefs |
/settings/notifications | PATCH | Update notification prefs |
/settings/organizations | GET | List organizations |
/settings/organizations/{id}/leave | POST | Leave organization |
/settings/account | DELETE | Delete account |
Billing
| Endpoint | Method | Description |
|---|---|---|
/billing/subscription | GET | Get subscription status |
/billing/checkout | POST | Create checkout session |
/billing/portal | POST | Create billing portal |
Limits
| Endpoint | Method | Description |
|---|---|---|
/limits/usage | GET | Current usage vs limits |
/limits/plan | GET | Plan limits |
/limits/upgrade-suggestion | GET | Upgrade recommendations |
Query Parameters
Most GET endpoints accept common query parameters:
| Parameter | Type | Description |
|---|---|---|
org_id | UUID | Organization ID (required for most endpoints) |
days | int | Time range in days (default: 30, max based on plan) |
limit | int | Results per page (default: 10) |
Example:
curl -H "Authorization: Bearer $TOKEN" \
"https://api.cicosts.dev/api/v1/dashboard/summary?org_id=uuid&days=30"
Quick Start
1. Authenticate
Login via GitHub to get your access token:
# Opens browser for GitHub OAuth
open https://app.cicosts.dev/login
2. Get Your Organization ID
curl -H "Authorization: Bearer $TOKEN" \
https://api.cicosts.dev/api/v1/auth/me
Response:
{
"id": "user-uuid",
"email": "you@example.com",
"organizations": [
{
"id": "org-uuid",
"github_org_slug": "your-org",
"role": "owner"
}
]
}
3. Fetch Cost Data
curl -H "Authorization: Bearer $TOKEN" \
"https://api.cicosts.dev/api/v1/dashboard/summary?org_id=org-uuid"
Response:
{
"total_cost": 247.50,
"trend_percent": -5.2,
"total_runs": 1247,
"avg_cost_per_run": 0.198,
"period_days": 30
}
Runner Pricing Reference
CICosts uses these rates for cost calculation:
| Runner | OS | Price/Minute |
|---|---|---|
ubuntu-latest | Linux (2-core) | $0.008 |
ubuntu-latest-4-cores | Linux (4-core) | $0.016 |
ubuntu-latest-8-cores | Linux (8-core) | $0.032 |
ubuntu-latest-16-cores | Linux (16-core) | $0.064 |
ubuntu-latest-arm | Linux ARM (2-core) | $0.005 |
windows-latest | Windows (2-core) | $0.016 |
macos-latest | macOS (3/4-core) | $0.080 |
macos-latest-large | macOS (12-core) | $0.120 |
Plan Limits
Data history is limited by plan:
| Plan | History Days | Max Repos |
|---|---|---|
| Free | 30 | 3 |
| Pro | 365 | Unlimited |
| Team | 365 | Unlimited |
Requests for data beyond your plan's limit will be capped automatically.
Best Practices
Cache Responses
Cost data is updated in near real-time as workflows complete:
- Cache summary data for 1-5 minutes
- Cache historical data for longer periods
Handle Rate Limits
async function fetchWithRetry(url, options, retries = 3) {
const response = await fetch(url, options);
if (response.status === 429 && retries > 0) {
const resetTime = response.headers.get('X-RateLimit-Reset');
const waitMs = (resetTime * 1000) - Date.now() + 1000;
await new Promise(r => setTimeout(r, waitMs));
return fetchWithRetry(url, options, retries - 1);
}
return response;
}
Next: Authentication