Public API

Calculate AWS costs from your own code

CloudCostFlow exposes a programmatic API for submitting an architecture graph and getting back a full monthly cost breakdown. Use it for CI checks, internal tooling, migration modelling, or quoting workflows.

The production API is documented here as a static reference because FastAPI's interactive docs are disabled in production. Everything below is derived from the live request/response models in src/api_v1.py and the current rate limiting code in src/rate_limit.py.

Base path
https://cloudcostflow.com/api/v1
Auth
API key via X-API-Key header
Format
JSON request and JSON response
Access
Requires an authenticated user with Pro or Team API access

Overview

The public API currently exposes one calculation endpoint:

  • Submit a graph of AWS services with nodes, edges, and traffic entry points.
  • Validate the architecture before calculation.
  • Return detailed monthly service costs, data transfer costs, optional per-request cost, pricing version, and calculation timestamp.

Important: the API validates both region and service types. It also caps a single request at 50 services. Invalid graphs or unsupported service names return 400 responses.

Authentication

Authenticate each request with an API key using the X-API-Key header:

X-API-Key: ccf_your_api_key_here

You can create and revoke API keys from your CloudCostFlow account settings via the API Keys page. Keys are shown once at creation time, so copy them immediately and store them securely.

Access control: the API only accepts active keys tied to users who still have paid access. In the auth layer, inactive keys, unknown keys, or keys for users without Pro access fail authentication with 401 Not authenticated.

Rate limits

Rate limiting is applied per API key using an in-memory sliding window in src/rate_limit.py with a 3600 second (1 hour) window.

Plan / key type Requests per hour Source
Pro 100 Default API key rate limit in src/api_keys.py and endpoint docstring
Team / org keys 1000 Organisation API key creation in src/organizations.py and endpoint docstring

The calculate endpoint returns these rate limit headers on authenticated API key requests:

  • X-RateLimit-Limit — hourly limit for the key
  • X-RateLimit-Remaining — requests remaining in the current window
  • X-RateLimit-Reset — Unix timestamp when the window resets

If the key exceeds its limit, the API returns 429 Rate limit exceeded and includes Retry-After.

Endpoint

POST /api/v1/calculate

Calculate the monthly cost of an AWS architecture graph. The endpoint accepts an array of services (nodes), the relationships between them (edges), traffic entry points (entryPoints), and an AWS region.

Authentication

X-API-Key header required.

Content type

Content-Type: application/json

Example request

curl -X POST "https://cloudcostflow.com/api/v1/calculate" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: ccf_your_api_key_here" \
  -d '{
    "nodes": [
      {
        "id": "edge-cache",
        "service": "CloudFront",
        "params": {
          "dataTransferOutGB": 2500,
          "httpRequests": 10000000
        }
      },
      {
        "id": "origin-bucket",
        "service": "S3",
        "params": {
          "storageGB": 50,
          "putRequests": 500000,
          "getRequests": 760000
        }
      }
    ],
    "edges": [
      {
        "from": "edge-cache",
        "to": "origin-bucket",
        "metrics": [
          { "type": "requests", "ratio": 1.0 }
        ],
        "network": {
          "context": "cloudfront-origin"
        }
      }
    ],
    "entryPoints": [
      {
        "nodeId": "edge-cache",
        "requestsPerMonth": 10000000
      }
    ],
    "region": "us-east-1"
  }'

Example response

{
  "totalMonthlyCost": 224.95,
  "currency": "USD",
  "region": "us-east-1",
  "services": [
    {
      "id": "edge-cache",
      "type": "CloudFront",
      "monthlyCost": 221.0,
      "breakdown": {
        "requests": 8.5,
        "dataTransferOut": 212.5
      }
    },
    {
      "id": "origin-bucket",
      "type": "S3",
      "monthlyCost": 3.95,
      "breakdown": {
        "storage": 1.15,
        "putRequests": 2.5,
        "getRequests": 0.3
      }
    }
  ],
  "dataTransfer": {
    "monthlyCost": 0,
    "breakdown": {}
  },
  "perRequest": {
    "cost": 0.000022495,
    "requestsPerMonth": 10000000
  },
  "pricingVersion": "8f36d2d8d5f1...",
  "calculatedAt": "2026-03-29T15:24:00.000000+00:00"
}

Request schema

nodes *

Array of services to price. Maximum 50 items.

  • id (string) — unique node identifier used by edges and entry points.
  • service (string) — AWS service type. Must be one of the supported values listed below.
  • params (object, optional) — service-specific pricing inputs. Defaults to an empty object.

edges *

Array describing how requests and network traffic flow between nodes.

  • from (string) — source node ID. In the internal model this becomes from_.
  • to (string) — destination node ID.
  • metrics (array, optional) — request propagation rules. Defaults to [].
  • network (object | null, optional) — extra network context used in transfer pricing.

metrics[]

Each metric object contains:

  • type (string) — metric name such as request count.
  • ratio (number) — multiplier used when propagating usage.

entryPoints *

Traffic injection points for the graph.

  • nodeId (string) — target node ID.
  • requestsPerMonth (integer) — monthly request volume for that entry point.

region

AWS region for pricing. Optional. Defaults to us-east-1.

Response schema

Field Type Description
totalMonthlyCost number Total monthly architecture cost rounded to 2 decimal places.
currency string Always USD.
region string The AWS region used for the calculation.
services array Per-service monthly cost breakdowns.
dataTransfer object Total inter-service/network data transfer cost and breakdown.
perRequest object or null Present only when the total entryPoints.requestsPerMonth is greater than zero.
pricingVersion string Hash representing the pricing data version used in the calculation.
calculatedAt string UTC ISO-8601 timestamp for when the response was generated.

Nested objects

services[]

id (string), type (string), monthlyCost (number), breakdown (object)

dataTransfer

monthlyCost (number), breakdown (object)

perRequest

cost (number), requestsPerMonth (integer)

Error responses

Status When it happens Example response body
200 OK Successful calculation. {"totalMonthlyCost":224.95,...}
400 Bad Request Too many nodes, invalid region, unsupported service, invalid graph, or pricing data file issues. {"detail":"Maximum of 50 services allowed per calculation"}
401 Unauthorized Missing/invalid API key or user no longer has paid access. {"detail":"Not authenticated"}
429 Too Many Requests Hourly API key limit exceeded. {"detail":"Rate limit exceeded"}
500 Internal Server Error Unexpected internal calculation error or an unimplemented service mapping. {"detail":"Internal error: ..."}

Supported values

Supported regions

us-east-1, us-east-2, us-west-1, us-west-2, eu-west-1, eu-west-2, eu-west-3, eu-central-1, ap-southeast-1, ap-southeast-2, ap-northeast-1, ap-south-1, ca-central-1, sa-east-1

Supported service values for nodes[].service

ALB, APIGateway, CloudFront, CloudWatch, DynamoDB, EC2, ECS, EFS, EKS, ElasticIP, ElastiCache, KMS, Lambda, NATGateway, NetworkFirewall, RDS, Route53, S3, SNS, SQS, SecretsManager, StepFunctions, VPCEndpoint, WAF

Implementation detail: the API validates these service names before calculation. If a name passes validation but isn't wired in the backend service map yet, the endpoint can still return 500 Service 'X' not implemented.