{
  "openapi": "3.1.0",
  "info": {
    "title": "warm.ac API",
    "version": "1.0.0",
    "description": "Public API for warm.ac — a deliverability observatory tracking warmup pool inbox placement rates across major email sequencers and Azure mailbox configurations.\n\nThis API is designed to be machine-readable and is suitable for use by LLMs, AI agents, and automated tooling. All data is refreshed daily. No authentication required.",
    "contact": {
      "name": "sending.ac",
      "url": "https://sending.ac"
    },
    "license": {
      "name": "Public data — free to use"
    }
  },
  "servers": [
    {
      "url": "https://warm.ac",
      "description": "Production"
    }
  ],
  "paths": {
    "/api/v1/warmup-pool.json": {
      "get": {
        "operationId": "getWarmupPool",
        "summary": "Warmup pool delivery breakdown",
        "description": "Returns the latest warmup pool inbox placement data for all tracked sequencer/mailbox configurations. Includes a 7-day aggregate per configuration (categories) and a daily breakdown for trend analysis. Values are percentages summing to 100 per row. Null entries indicate a configuration was not active during the period.",
        "tags": ["Deliverability"],
        "responses": {
          "200": {
            "description": "Warmup pool data",
            "headers": {
              "Cache-Control": {
                "schema": { "type": "string" },
                "example": "public, max-age=3600"
              },
              "Access-Control-Allow-Origin": {
                "schema": { "type": "string" },
                "example": "*"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WarmupPoolData"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "EspBreakdown": {
        "type": "object",
        "description": "Inbox placement percentage breakdown by receiving ESP. Values sum to 100.",
        "required": ["microsoft", "google", "other"],
        "properties": {
          "microsoft": {
            "type": "number",
            "description": "Percentage of warmup emails landing in Microsoft (Outlook/Exchange) inboxes"
          },
          "google": {
            "type": "number",
            "description": "Percentage of warmup emails landing in Google (Gmail/Workspace) inboxes"
          },
          "other": {
            "type": "number",
            "description": "Percentage of warmup emails landing in other ESP inboxes"
          }
        }
      },
      "CategoryEntry": {
        "type": "object",
        "description": "7-day aggregate inbox placement for a single configuration",
        "required": ["esp"],
        "properties": {
          "esp": { "$ref": "#/components/schemas/EspBreakdown" }
        }
      },
      "DailyEntry": {
        "type": "object",
        "description": "Per-day inbox placement snapshot. Contains a 'date' field plus one key per configuration (or null if inactive that day).",
        "required": ["date"],
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "description": "ISO 8601 date for this row (YYYY-MM-DD)"
          }
        },
        "additionalProperties": {
          "oneOf": [
            { "$ref": "#/components/schemas/EspBreakdown" },
            { "type": "null" }
          ]
        }
      },
      "WarmupPoolData": {
        "type": "object",
        "description": "Full warmup pool dataset. Categories keys follow the pattern {sequencer}-{mailbox-type}-{connection-method}, e.g. 'instantly-azure-oauth'.",
        "required": ["generated_at", "period_start", "period_end", "categories", "daily"],
        "properties": {
          "generated_at": {
            "type": "string",
            "format": "date-time",
            "description": "ISO 8601 timestamp of when this dataset was generated"
          },
          "period_start": {
            "type": "string",
            "format": "date",
            "description": "Start of the reporting period (inclusive)"
          },
          "period_end": {
            "type": "string",
            "format": "date",
            "description": "End of the reporting period (inclusive)"
          },
          "categories": {
            "type": "object",
            "description": "7-day aggregate per configuration. Null means the configuration was not active during the period.",
            "additionalProperties": {
              "oneOf": [
                { "$ref": "#/components/schemas/CategoryEntry" },
                { "type": "null" }
              ]
            }
          },
          "daily": {
            "type": "array",
            "description": "Daily snapshots, one entry per day in the period, newest first",
            "items": { "$ref": "#/components/schemas/DailyEntry" }
          }
        }
      }
    }
  }
}
