API Reference
The PodCost API allows you to programmatically access your Kubernetes cost data, recommendations, and alerts. Integrate cost visibility into your own tools, dashboards, and automation workflows.
API access requires a Pro or Enterprise subscription. Upgrade your plan to get started.
Introduction
The PodCost API is a RESTful API that returns JSON responses. All endpoints are accessed via https://podcost.io/api/v1/.
The API uses standard HTTP methods (GET, POST, DELETE) and returns appropriate HTTP status codes. All timestamps are in ISO 8601 format.
Authentication
All API requests require authentication using an API key. Include your API key in the Authorization header as a Bearer token:
Authorization: Bearer pc_api_your_api_key_here
You can create and manage API keys in your Settings page. API keys are shown only once when created, so make sure to copy and store them securely.
Creating an API Key
- Go to Settings
- Scroll to the "API Keys" section
- Click "Create API Key"
- Enter a descriptive name (e.g., "Production Dashboard")
- Copy the generated key immediately - it won't be shown again
Rate Limits
API requests are rate limited to ensure fair usage:
| Plan | Rate Limit |
|---|---|
| Pro | 1,000 requests/hour |
| Enterprise | 10,000 requests/hour |
Rate limit information is included in response headers:
X-RateLimit-Limit: 1000 X-RateLimit-Remaining: 999 X-RateLimit-Reset: 1705320000
List Clusters
Returns a list of all clusters accessible to your account.
{
"data": [
{
"id": "123",
"name": "production-us-east",
"displayName": "Production US East",
"cloudProvider": "aws-eks",
"region": "us-east-1",
"status": "active",
"lastSeenAt": "2024-01-15T10:30:00Z",
"createdAt": "2024-01-01T00:00:00Z"
}
],
"meta": {
"total": 1
}
}
Get Costs
Returns cost summary and time series data for a specific cluster.
| Parameter | Type | Description |
|---|---|---|
range |
string | Time range: 24h, 7d, 30d. Default: 7d |
granularity |
string | Data granularity: hourly, daily. Default: daily |
{
"data": {
"summary": {
"totalCost": 1234.56,
"computeCost": 1000.00,
"gpuCost": 234.56,
"potentialSavings": 150.00,
"efficiency": 72.5
},
"timeSeries": [
{
"timestamp": "2024-01-14T00:00:00Z",
"cost": 41.23,
"computeCost": 35.00,
"gpuCost": 6.23
}
]
},
"meta": {
"clusterId": "123",
"clusterName": "production-us-east",
"range": "7d",
"currency": "USD"
}
}
Cost Breakdown
Returns cost breakdown grouped by namespace, workload, or node.
| Parameter | Type | Description |
|---|---|---|
range |
string | Time range: 24h, 7d, 30d. Default: 7d |
groupBy |
string | Group by: namespace, workload, node. Default: namespace |
{
"data": {
"breakdown": [
{
"name": "production",
"cost": 500.00,
"percentage": 40.5,
"cpuCost": 400.00,
"memoryCost": 80.00,
"gpuCost": 20.00
}
],
"totalCost": 1234.56
},
"meta": {
"clusterId": "123",
"groupBy": "namespace",
"range": "7d"
}
}
Recommendations
Returns cost-saving recommendations for a cluster.
| Parameter | Type | Description |
|---|---|---|
type |
string | Filter by type: all, idle, rightsizing, spot. Default: all |
minSavings |
number | Minimum monthly savings to include. Default: 0 |
{
"data": {
"summary": {
"totalPotentialSavings": 450.00,
"recommendationCount": 12,
"byType": {
"idle": { "count": 5, "savings": 200.00 },
"rightsizing": { "count": 4, "savings": 150.00 }
}
},
"recommendations": [
{
"id": "rec-123",
"type": "idle",
"priority": "high",
"resourceType": "deployment",
"resourceName": "unused-api",
"namespace": "default",
"description": "Deployment has 0% CPU usage over 7 days",
"monthlySavings": 45.00,
"action": "Consider removing or scaling down"
}
]
},
"meta": {
"clusterId": "123",
"currency": "USD"
}
}
Alerts
Returns alerts and anomalies for a cluster.
| Parameter | Type | Description |
|---|---|---|
status |
string | Filter by status: active, acknowledged, resolved, all. Default: active |
severity |
string | Filter by severity: critical, warning, info, all. Default: all |
limit |
number | Maximum results to return. Default: 50 |
{
"data": {
"summary": {
"total": 8,
"bySeverity": { "critical": 1, "warning": 3, "info": 4 },
"byStatus": { "active": 5, "acknowledged": 2, "resolved": 1 }
},
"alerts": [
{
"id": 123,
"type": "cost",
"category": "cost_spike",
"severity": "warning",
"status": "active",
"title": "Cost Spike Detected",
"message": "Cost increased 25% in namespace 'production'",
"resource": {
"kind": "Namespace",
"name": "production"
},
"createdAt": "2024-01-15T08:00:00Z"
}
]
},
"meta": {
"clusterId": "123"
}
}
AI Insights
Returns AI-generated cost insights and recommendations.
{
"data": {
"summary": "Your production cluster is running at 72% efficiency...",
"metrics": {
"monthlyCost": 1234.56,
"potentialSavings": 150.00,
"efficiency": 72.5,
"gpuCost": 234.56,
"cpuCost": 1000.00
},
"wasteDrivers": [
"Idle deployments in default namespace",
"Over-provisioned redis pods"
],
"topActions": [
"Remove 3 idle deployments to save $120/month",
"Rightsize redis pods to save $30/month"
],
"generatedAt": "2024-01-15T10:00:00Z"
},
"meta": {
"clusterId": "123",
"hasData": true
}
}
Error Handling
The API uses standard HTTP status codes to indicate success or failure:
| Status Code | Description |
|---|---|
200 |
Success |
400 |
Bad request - Invalid parameters |
401 |
Unauthorized - Invalid or missing API key |
403 |
Forbidden - Missing required scope or subscription |
404 |
Not found - Cluster not found or no access |
429 |
Too many requests - Rate limit exceeded |
500 |
Server error |
Error responses include a JSON body:
{
"error": "Invalid or revoked API key",
"code": "INVALID_API_KEY"
}
Examples
cURL
# List clusters curl -H "Authorization: Bearer pc_api_your_key" \ https://podcost.io/api/v1/clusters # Get cost breakdown by namespace curl -H "Authorization: Bearer pc_api_your_key" \ "https://podcost.io/api/v1/clusters/123/costs/breakdown?groupBy=namespace&range=30d" # Get high-priority recommendations curl -H "Authorization: Bearer pc_api_your_key" \ "https://podcost.io/api/v1/clusters/123/recommendations?minSavings=50"
Python
import requests
API_KEY = "pc_api_your_key"
BASE_URL = "https://podcost.io/api/v1"
headers = {"Authorization": f"Bearer {API_KEY}"}
# Get clusters
response = requests.get(f"{BASE_URL}/clusters", headers=headers)
clusters = response.json()["data"]
# Get costs for first cluster
cluster_id = clusters[0]["id"]
costs = requests.get(
f"{BASE_URL}/clusters/{cluster_id}/costs",
params={"range": "7d"},
headers=headers
).json()
print(f"Monthly cost: ${costs['data']['summary']['totalCost']}")
JavaScript
const API_KEY = 'pc_api_your_key';
const BASE_URL = 'https://podcost.io/api/v1';
async function getCosts(clusterId) {
const response = await fetch(
`${BASE_URL}/clusters/${clusterId}/costs?range=7d`,
{
headers: {
'Authorization': `Bearer ${API_KEY}`
}
}
);
const data = await response.json();
console.log(`Monthly cost: $${data.data.summary.totalCost}`);
}