{
  "openapi": "3.0.3",
  "info": {
    "title": "CostPulse AWS Pricing API",
    "description": "Cross-region AWS on-demand pricing. Finds the cheapest commercial AWS region for an EC2, RDS, Lambda, S3, Bedrock or other service SKU, compares chosen regions, prices a multi-service workload per region, and calculates savings versus a current region. Generated from packages/pricing/src/handlers/api.ts and verified against the live API on Oct 8 2026.\n",
    "version": "1.1.0"
  },
  "servers": [
    {
      "url": "https://costpulse.waltsoft.net/v1",
      "description": "CostPulse production endpoint"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "paths": {
    "/cheapest": {
      "get": {
        "operationId": "getCheapestRegion",
        "summary": "Cheapest AWS region for a service SKU",
        "description": "Returns the cheapest and most expensive commercial AWS region for one SKU, the savings between them, and every region's price sorted cheapest first. Example: service=ec2, sku=m5.xlarge.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/Service"
          },
          {
            "$ref": "#/components/parameters/Sku"
          }
        ],
        "responses": {
          "200": {
            "description": "Prices found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CheapestResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/compare": {
      "get": {
        "operationId": "compareRegions",
        "summary": "Compare one SKU's price across chosen regions",
        "description": "Side-by-side price of one SKU in the regions you list, cheapest first. Omit regions to get all.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Service"
          },
          {
            "$ref": "#/components/parameters/Sku"
          },
          {
            "name": "regions",
            "in": "query",
            "required": false,
            "description": "Comma-separated region codes",
            "schema": {
              "type": "string",
              "example": "us-east-1,eu-west-1,ap-south-1"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Comparison",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompareResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/workload": {
      "get": {
        "operationId": "estimateWorkloadCost",
        "summary": "Cheapest region for a multi-service workload",
        "description": "Adds the per-unit price of each service:sku in every region that prices all of them, and ranks those regions cheapest first. For instance types the total is per hour.\n",
        "parameters": [
          {
            "name": "services",
            "in": "query",
            "required": true,
            "description": "Comma-separated service:sku pairs",
            "schema": {
              "type": "string",
              "example": "ec2:m5.xlarge,rds:db.m5.large"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Workload totals by region",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkloadResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/savings": {
      "get": {
        "operationId": "calculateSavings",
        "summary": "Savings from moving a SKU to the cheapest region",
        "parameters": [
          {
            "$ref": "#/components/parameters/Service"
          },
          {
            "$ref": "#/components/parameters/Sku"
          },
          {
            "name": "current_region",
            "in": "query",
            "required": false,
            "description": "Region you run in today (default us-east-1)",
            "schema": {
              "type": "string",
              "example": "eu-west-1"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Savings",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SavingsResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "Your mp_ API key, delivered to your AWS Secrets Manager when you subscribe through AWS Marketplace"
      }
    },
    "parameters": {
      "Service": {
        "name": "service",
        "in": "query",
        "required": true,
        "description": "AWS service: ec2, rds, lambda, s3, dynamodb, bedrock, elasticache, opensearch, fargate, and more (case-insensitive)",
        "schema": {
          "type": "string",
          "example": "ec2"
        }
      },
      "Sku": {
        "name": "sku",
        "in": "query",
        "required": true,
        "description": "Instance type or usage type, for example m5.xlarge (ec2), db.m5.large (rds), Lambda-GB-Second (lambda)",
        "schema": {
          "type": "string",
          "example": "m5.xlarge"
        }
      }
    },
    "schemas": {
      "RegionPrice": {
        "type": "object",
        "properties": {
          "region": {
            "type": "string",
            "example": "us-east-1"
          },
          "price_per_unit": {
            "type": "number",
            "example": 0.192
          },
          "unit": {
            "type": "string",
            "example": "Hrs"
          }
        }
      },
      "CheapestResponse": {
        "type": "object",
        "properties": {
          "service": {
            "type": "string",
            "example": "ec2"
          },
          "sku": {
            "type": "string",
            "example": "m5.xlarge"
          },
          "cheapest": {
            "$ref": "#/components/schemas/RegionPrice"
          },
          "most_expensive": {
            "type": "object",
            "properties": {
              "region": {
                "type": "string",
                "example": "sa-east-1"
              },
              "price_per_unit": {
                "type": "number",
                "example": 0.306
              }
            }
          },
          "savings_vs_most_expensive": {
            "type": "string",
            "example": "37%"
          },
          "regions_compared": {
            "type": "integer",
            "example": 30
          },
          "all_regions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RegionPrice"
            }
          },
          "last_updated": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "CompareResponse": {
        "type": "object",
        "properties": {
          "service": {
            "type": "string"
          },
          "sku": {
            "type": "string"
          },
          "regions_requested": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "comparison": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RegionPrice"
            }
          }
        }
      },
      "WorkloadResponse": {
        "type": "object",
        "properties": {
          "workload": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "ec2:m5.xlarge",
              "rds:db.m5.large"
            ]
          },
          "optimal_region": {
            "type": "string",
            "example": "us-east-1"
          },
          "optimal_cost": {
            "type": "number",
            "example": 0.363
          },
          "all_regions": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "region": {
                  "type": "string"
                },
                "total_cost": {
                  "type": "number"
                }
              }
            }
          }
        }
      },
      "SavingsResponse": {
        "type": "object",
        "properties": {
          "service": {
            "type": "string"
          },
          "sku": {
            "type": "string"
          },
          "current_region": {
            "type": "string",
            "example": "eu-west-1"
          },
          "current_price": {
            "type": "number",
            "example": 0.214
          },
          "cheapest_region": {
            "type": "string",
            "example": "us-east-1"
          },
          "cheapest_price": {
            "type": "number",
            "example": 0.192
          },
          "savings_per_unit": {
            "type": "number",
            "example": 0.022
          },
          "savings_percent": {
            "type": "string",
            "example": "10%"
          },
          "recommendation": {
            "type": "string",
            "example": "Move to us-east-1 to save 10%"
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "example": "No pricing data found. Try: ec2, lambda, rds, s3, bedrock"
          }
        }
      },
      "AuthError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "integer",
                "example": 401
              },
              "message": {
                "type": "string",
                "example": "Invalid or inactive API key"
              }
            }
          }
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "A required parameter is missing",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Invalid or inactive API key",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/AuthError"
            }
          }
        }
      },
      "NotFound": {
        "description": "No price for this service, SKU or region (not billed)",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "ServerError": {
        "description": "Server error (not billed)",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    }
  }
}