API Reference
Module: Lens
Version: 1.0.0-RELEASE
Last Updated: October 25, 2025
Base URL: https://api.cloudkeeper.com (production)
Documentation: /swagger-ui/index.html
API Overview
Total Endpoints: 100+ REST APIs across 40 controllers
Authentication: JWT Bearer token (required for all endpoints)
Common Headers:
Authorization: Bearer <JWT_TOKEN>
auth-customer: <CUSTOMER_ID>
Content-Type: application/json
Response Format: All responses wrapped in ResponseDto
{
"status": "success", // or "error"
"data": { ... },
"message": "Optional message",
"code": 200
}
Core APIs
1. Cost Summary API
GET /admin-pages/cost/summary
Purpose: Compare AWS billed costs vs actual usage costs
Query Parameters:
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
| customerId | String | Yes | Customer ID | CUST-123 |
| accountId | String | Yes | AWS Account ID | 123456789012 |
| startDate | String | Yes | Start date (YYYY-MM-DD) | 2024-01-01 |
| endDate | String | Yes | End date (YYYY-MM-DD) | 2024-01-31 |
| service | String | No | Filter by service | EC2 |
Request Example:
curl -X GET "https://api.cloudkeeper.com/admin-pages/cost/summary?customerId=CUST-123&accountId=123456789012&startDate=2024-01-01&endDate=2024-01-31" \
-H "Authorization: Bearer eyJhbGc..." \
-H "auth-customer: CUST-123"
Response Example (200 OK):
{
"status": "success",
"data": [
{
"service": "Amazon Elastic Compute Cloud - Compute",
"awsCost": 5000.00,
"actualCost": 4500.00,
"variance": -500.00,
"variancePercent": -10.00,
"savingsRealized": 500.00
},
{
"service": "Amazon Relational Database Service",
"awsCost": 2000.00,
"actualCost": 1900.00,
"variance": -100.00,
"variancePercent": -5.00,
"savingsRealized": 100.00
}
],
"code": 200
}
Error Responses:
// 400 Bad Request - Invalid date range
{
"status": "error",
"message": "End date must be after start date",
"code": 400
}
// 401 Unauthorized - Invalid JWT
{
"status": "error",
"message": "Invalid or expired token",
"code": 401
}
// 403 Forbidden - No permission
{
"status": "error",
"message": "You do not have permission to access this resource",
"code": 403
}
2. Billing Console API
GET /billing-console/cost
Purpose: Current month cost with end-of-month projection
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| customerId | String | Yes | Customer ID |
| accountId | String | Yes | AWS Account ID |
Response Example:
{
"status": "success",
"data": {
"monthToDateCost": 12500.75,
"projectedMonthEndCost": 18750.00,
"budget": 20000.00,
"budgetUtilizationPercent": 93.75,
"daysElapsed": 20,
"daysRemaining": 10,
"topServices": [
{
"service": "EC2",
"cost": 6000.00,
"percentOfTotal": 48.00
},
{
"service": "RDS",
"cost": 3000.00,
"percentOfTotal": 24.00
}
],
"alert": {
"severity": "WARNING",
"message": "Projected to exceed 90% of budget"
}
}
}
GET /billing-console/dailyBreakup
Purpose: Daily cost breakdown for time-series chart
Response Example:
{
"status": "success",
"data": {
"dailyCosts": [
{
"date": "2024-01-01",
"cost": 650.25
},
{
"date": "2024-01-02",
"cost": 675.50
}
// ... 30 days
],
"averageDailyCost": 625.02,
"highestCostDay": {
"date": "2024-01-15",
"cost": 850.00
}
}
}
3. Reserved Instance APIs
GET /reservation-summary/get
Purpose: Fetch all active Reserved Instances
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| customerId | String | Yes | Customer ID |
| accountId | String | Yes | AWS Account ID |
| service | String | No | EC2, RDS, ElastiCache |
| status | String | No | active, retired |
Response Example:
{
"status": "success",
"data": {
"totalReservations": 45,
"totalMonthlyCost": 25000.00,
"totalSavings": 18000.00,
"reservations": [
{
"reservationId": "ri-123456",
"instanceType": "m5.xlarge",
"service": "EC2",
"region": "us-east-1",
"availabilityZone": "us-east-1a",
"instanceCount": 10,
"offeringClass": "standard",
"offeringType": "No Upfront",
"term": "3yr",
"startDate": "2023-06-01",
"endDate": "2026-05-31",
"daysUntilExpiry": 580,
"utilizationPercent": 95.5,
"monthlySavings": 1200.00
}
]
}
}
GET /reservation-utilization
Purpose: RI utilization metrics
Response Example:
{
"status": "success",
"data": {
"overallUtilization": 89.2,
"utilizationByRI": [
{
"reservationId": "ri-123456",
"instanceType": "m5.xlarge",
"riHoursPurchased": 7200,
"riHoursUsed": 6840,
"utilizationPercent": 95.0,
"unusedHours": 360,
"wastedCost": 125.50,
"alert": null
},
{
"reservationId": "ri-789012",
"instanceType": "r5.large",
"riHoursPurchased": 7200,
"riHoursUsed": 4320,
"utilizationPercent": 60.0,
"unusedHours": 2880,
"wastedCost": 850.00,
"alert": {
"severity": "CRITICAL",
"message": "Utilization below 60%. Consider modifying or selling."
}
}
]
}
}
4. Cost Breakup APIs
GET /cost-breakup/database
Purpose: Database service cost breakdown
Query Parameters: customerId, accountId, startDate, endDate
Response Example:
{
"status": "success",
"data": {
"totalCost": 8500.00,
"breakdown": [
{
"service": "RDS",
"cost": 5000.00,
"instances": [
{
"instanceId": "mydb-prod",
"instanceType": "db.r5.xlarge",
"engine": "postgres",
"instanceHours": 720,
"storageCost": 200.00,
"iopsCost": 150.00,
"backupCost": 50.00,
"totalCost": 2400.00
}
]
},
{
"service": "DynamoDB",
"cost": 2000.00,
"tables": [
{
"tableName": "UserData",
"readCapacityUnits": 100,
"writeCapacityUnits": 50,
"storageGB": 500,
"cost": 1200.00
}
]
},
{
"service": "ElastiCache",
"cost": 1500.00
}
]
}
}
GET /cost-breakup/storage
Purpose: Storage service cost breakdown (S3, EBS, EFS)
Response Example:
{
"status": "success",
"data": {
"totalCost": 12000.00,
"s3": {
"totalCost": 8000.00,
"byStorageClass": [
{
"storageClass": "STANDARD",
"storageGB": 10000,
"storageCost": 2300.00,
"requestCost": 500.00,
"dataTransferCost": 1200.00,
"totalCost": 4000.00
},
{
"storageClass": "INTELLIGENT_TIERING",
"storageGB": 50000,
"storageCost": 2000.00,
"totalCost": 2000.00
},
{
"storageClass": "GLACIER",
"storageGB": 200000,
"storageCost": 800.00,
"totalCost": 800.00
}
],
"recommendations": [
{
"type": "LIFECYCLE_POLICY",
"message": "Move 30TB of STANDARD data (>90 days old) to INTELLIGENT_TIERING",
"estimatedMonthlySavings": 500.00
}
]
},
"ebs": {
"totalCost": 3000.00,
"volumes": 150,
"totalSizeGB": 50000,
"byType": [
{
"volumeType": "gp3",
"count": 100,
"sizeGB": 30000,
"cost": 2400.00
},
{
"volumeType": "io2",
"count": 50,
"sizeGB": 20000,
"cost": 600.00
}
],
"recommendations": [
{
"type": "GP2_TO_GP3_MIGRATION",
"message": "Migrate 15 gp2 volumes to gp3",
"estimatedMonthlySavings": 80.00
}
]
}
}
}
5. Cost Alert APIs
POST /alerts/cost-alert
Purpose: Create cost alert
Request Body:
{
"customerId": "CUST-123",
"accountId": "123456789012",
"alertName": "Production Budget Alert",
"alertType": "BUDGET_THRESHOLD",
"thresholds": [
{
"percent": 80,
"notificationChannels": ["email", "slack"]
},
{
"percent": 100,
"notificationChannels": ["email", "slack", "pagerduty"]
}
],
"budget": 20000.00,
"enabled": true
}
Response Example:
{
"status": "success",
"data": {
"alertId": "ALERT-456",
"message": "Cost alert created successfully"
}
}
GET /alerts/daily-report
Purpose: Get yesterday's cost summary
Response Example:
{
"status": "success",
"data": {
"date": "2024-10-24",
"totalCost": 720.50,
"previousDayCost": 650.25,
"change": {
"absolute": 70.25,
"percent": 10.8
},
"topCostIncreases": [
{
"service": "Lambda",
"cost": 150.00,
"previousCost": 50.00,
"change": 100.00
}
],
"anomalies": [
{
"service": "S3",
"metric": "Requests",
"actual": 2500000000,
"expected": 500000000,
"severity": "HIGH",
"message": "5x increase in S3 GET requests"
}
]
}
}
6. CUDOS Dashboard APIs
GET /cudos/s3-dashboard
Purpose: S3-specific cost and usage dashboard
Query Parameters: customerId, accountId, startDate, endDate
Response Example:
{
"status": "success",
"data": {
"totalCost": 8000.00,
"totalStorageGB": 260000,
"storageByClass": [
{
"storageClass": "STANDARD",
"sizeGB": 10000,
"cost": 2300.00,
"percentOfTotal": 3.8
},
{
"storageClass": "INTELLIGENT_TIERING",
"sizeGB": 50000,
"cost": 2000.00,
"percentOfTotal": 19.2
},
{
"storageClass": "GLACIER",
"sizeGB": 200000,
"cost": 800.00,
"percentOfTotal": 76.9
}
],
"requestCosts": {
"getPutRequests": 500.00,
"listRequests": 50.00,
"total": 550.00
},
"dataTransferCosts": {
"cloudFrontToOrigin": 200.00,
"internetEgress": 1000.00,
"total": 1200.00
},
"topBuckets": [
{
"bucketName": "prod-media-assets",
"sizeGB": 150000,
"cost": 4500.00
}
],
"lifecyclePolicyEffectiveness": {
"bucketsWithPolicies": 15,
"totalBuckets": 50,
"dataTransitioned": 50000,
"savingsRealized": 1200.00
}
}
}
7. Recommendation APIs
GET /recommendations
Purpose: Fetch all cost optimization recommendations
Query Parameters: customerId, accountId
Response Example:
{
"status": "success",
"data": {
"totalRecommendations": 25,
"totalEstimatedSavings": 5800.00,
"recommendations": [
{
"id": "REC-001",
"type": "EC2_RIGHTSIZING",
"category": "COMPUTE",
"severity": "HIGH",
"title": "Downsize over-provisioned EC2 instances",
"description": "5 instances have avg CPU < 10% over 30 days",
"resources": [
{
"resourceId": "i-1234567890abcdef0",
"instanceType": "m5.2xlarge",
"avgCpuUtilization": 8.5,
"recommendedInstanceType": "m5.xlarge",
"currentMonthlyCost": 280.00,
"recommendedMonthlyCost": 140.00,
"estimatedMonthlySavings": 140.00
}
],
"totalMonthlySavings": 700.00,
"annualSavings": 8400.00,
"implementationDifficulty": "EASY",
"riskLevel": "LOW"
},
{
"id": "REC-002",
"type": "RI_PURCHASE",
"category": "COMMITMENT",
"severity": "MEDIUM",
"title": "Purchase Reserved Instances for stable workloads",
"description": "20 m5.xlarge instances running 24/7 without RIs",
"estimatedMonthlySavings": 1800.00,
"annualSavings": 21600.00,
"upfrontCost": 0.00,
"paybackPeriod": "N/A (No Upfront)",
"implementationDifficulty": "EASY",
"riskLevel": "LOW"
},
{
"id": "REC-003",
"type": "IDLE_RESOURCES",
"category": "WASTE",
"severity": "MEDIUM",
"title": "Delete idle load balancers",
"description": "3 load balancers with 0 active connections",
"resources": [
{
"resourceId": "my-old-lb",
"type": "classic",
"activeConnections": 0,
"monthlyCost": 25.00
}
],
"totalMonthlySavings": 75.00,
"annualSavings": 900.00,
"implementationDifficulty": "EASY",
"riskLevel": "LOW"
}
],
"breakdownByCategory": {
"COMPUTE": 700.00,
"STORAGE": 500.00,
"DATABASE": 300.00,
"COMMITMENT": 1800.00,
"WASTE": 75.00
}
}
}
Export APIs
All major endpoints support Excel export via /export suffix.
POST /admin-pages/cost/export
Purpose: Export cost summary to Excel
Request Body:
{
"customerId": "CUST-123",
"accountId": "123456789012",
"startDate": "2024-01-01",
"endDate": "2024-01-31",
"format": "XLSX", // or "CSV"
"emailTo": "user@example.com" // Optional: email instead of download
}
Response: Binary file download (Excel)
Pagination
Endpoints with large result sets support pagination:
Query Parameters:
page=0 # Page number (0-indexed)
size=100 # Results per page (default 20, max 1000)
sort=cost,desc # Sort field and direction
Response (Page object):
{
"status": "success",
"data": {
"content": [ ... ], // Array of results
"pageable": {
"pageNumber": 0,
"pageSize": 100,
"offset": 0
},
"totalElements": 1500,
"totalPages": 15,
"last": false,
"first": true,
"numberOfElements": 100
}
}
Rate Limiting
Limits:
- General APIs: 100 requests per minute per customer
- Export APIs: 10 requests per minute per customer
- Alert APIs: 30 requests per minute per customer
Rate Limit Headers:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1698345600 # Unix timestamp
Rate Limit Exceeded Response (429):
{
"status": "error",
"message": "Rate limit exceeded. Retry after 60 seconds.",
"code": 429,
"retryAfter": 60
}
Error Codes
| Code | Status | Description |
|---|---|---|
| 200 | OK | Success |
| 201 | Created | Resource created |
| 400 | Bad Request | Invalid input |
| 401 | Unauthorized | Invalid/missing JWT |
| 403 | Forbidden | No permission |
| 404 | Not Found | Resource not found |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Internal Server Error | Server error |
| 503 | Service Unavailable | Database/service down |
API Client Examples
cURL
# Cost summary
curl -X GET "https://api.cloudkeeper.com/admin-pages/cost/summary?customerId=CUST-123&accountId=123456789012&startDate=2024-01-01&endDate=2024-01-31" \
-H "Authorization: Bearer ${JWT_TOKEN}" \
-H "auth-customer: CUST-123"
Python (requests)
import requests
url = "https://api.cloudkeeper.com/admin-pages/cost/summary"
headers = {
"Authorization": f"Bearer {jwt_token}",
"auth-customer": "CUST-123"
}
params = {
"customerId": "CUST-123",
"accountId": "123456789012",
"startDate": "2024-01-01",
"endDate": "2024-01-31"
}
response = requests.get(url, headers=headers, params=params)
data = response.json()
print(data['data'])
JavaScript (fetch)
const url = new URL('https://api.cloudkeeper.com/admin-pages/cost/summary');
url.searchParams.append('customerId', 'CUST-123');
url.searchParams.append('accountId', '123456789012');
url.searchParams.append('startDate', '2024-01-01');
url.searchParams.append('endDate', '2024-01-31');
const response = await fetch(url, {
headers: {
'Authorization': `Bearer ${jwtToken}`,
'auth-customer': 'CUST-123'
}
});
const data = await response.json();
console.log(data.data);
Java (RestTemplate)
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer " + jwtToken);
headers.set("auth-customer", "CUST-123");
HttpEntity<String> entity = new HttpEntity<>(headers);
String url = "https://api.cloudkeeper.com/admin-pages/cost/summary" +
"?customerId=CUST-123&accountId=123456789012" +
"&startDate=2024-01-01&endDate=2024-01-31";
`ResponseEntity<ResponseDto>` response = restTemplate.exchange(
url, HttpMethod.GET, entity, ResponseDto.class);
`List<CostSummaryDTO>` data = (`List<CostSummaryDTO>`) response.getBody().getData();
Interactive API Documentation
Swagger UI: https://api.cloudkeeper.com/swagger-ui/index.html
Features:
- Try out APIs directly from browser
- View request/response schemas
- Generate client code
- Download OpenAPI spec
OpenAPI Spec: https://api.cloudkeeper.com/v3/api-docs
Webhooks (Optional)
Lens can send webhooks for events:
Cost Alert Webhook
Endpoint: Your configured URL Method: POST Payload:
{
"event": "COST_ALERT_TRIGGERED",
"customerId": "CUST-123",
"timestamp": "2024-10-25T18:30:00Z",
"data": {
"alertId": "ALERT-456",
"alertName": "Production Budget Alert",
"threshold": 80,
"currentUtilization": 85.5,
"totalCost": 17100.00,
"budget": 20000.00
}
}
Webhook Configuration: Contact support to configure webhook URLs.
Summary
API Endpoints: 100+ REST APIs
Authentication: JWT Bearer token
Response Format: Standardized JSON wrapper
Rate Limiting: 100 req/min (general), 10 req/min (exports)
Documentation: Swagger UI at /swagger-ui/index.html
Key API Categories:
- Cost Summary: AWS vs actual cost comparison
- Billing Console: Dashboard data, daily/monthly summaries
- Reservations: RI inventory, utilization, coverage
- Cost Breakups: Service-specific cost analysis (12 categories)
- Alerts: Budget alerts, daily reports, RI expiry
- CUDOS: Pre-built dashboards (S3, data transfer, database)
- Recommendations: Optimization suggestions
Related Documents:
- 05-component-design - Controller/service details
- 07-data-models - Request/response DTO schemas
- 12-developer-guide - API integration guide
Document Version: 1.0 Last Updated: October 25, 2025