{
  "openapi": "3.1.0",
  "info": {
    "title": "Caffeine Clock",
    "version": "1.0.0",
    "description": "See how much caffeine is still in your bloodstream, what is left at bedtime, and when you drop below your limit."
  },
  "servers": [
    {
      "url": "https://caffeine-clock.tinyverb.com"
    }
  ],
  "paths": {
    "/api/caffeine-level": {
      "post": {
        "operationId": "caffeine-level",
        "summary": "Caffeine level",
        "description": "Estimate how much caffeine is in someone's bloodstream now, how much will still be there at bedtime, and how long until it falls below a threshold. Takes the drinks consumed in the last 24 hours (mg and minutes ago) and an optional half-life (3–7 h, default 5). First-order exponential decay, instant absorption; deterministic, no medical advice.",
        "x-price-per-call": {
          "amount": 0.002,
          "currency": "USD",
          "freeCallsPerDay": 50,
          "rails": []
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "intakes": {
                    "minItems": 1,
                    "maxItems": 50,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "mg": {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 2000,
                          "description": "Caffeine in the drink, in milligrams (coffee ≈ 95, espresso ≈ 63)"
                        },
                        "minutesAgo": {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 1440,
                          "description": "How long ago it was drunk, in minutes. 0 = just now; beyond 1440 (24 h) it no longer counts"
                        },
                        "label": {
                          "description": "Optional drink name, echoed back",
                          "type": "string",
                          "maxLength": 60
                        }
                      },
                      "required": [
                        "mg",
                        "minutesAgo"
                      ]
                    },
                    "description": "Caffeinated drinks consumed in the last 24 hours"
                  },
                  "halfLifeHours": {
                    "default": 5,
                    "description": "Caffeine half-life for this person in hours; adult typical range 3–7, default 5",
                    "type": "number",
                    "minimum": 3,
                    "maximum": 7
                  },
                  "bedtimeInHours": {
                    "default": 8,
                    "description": "Hours from now until bedtime, used for the bedtime projection",
                    "type": "number",
                    "minimum": 0,
                    "maximum": 24
                  },
                  "thresholdMg": {
                    "default": 50,
                    "description": "Milligrams to fall below; the answer says how long that takes",
                    "type": "number",
                    "minimum": 1,
                    "maximum": 1000
                  }
                },
                "required": [
                  "intakes"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "currentMg": {
                      "type": "number",
                      "description": "Caffeine in the bloodstream right now, in milligrams"
                    },
                    "atBedtimeMg": {
                      "type": "number",
                      "description": "Projected milligrams still in the bloodstream at bedtime"
                    },
                    "bedtimeEquivalent": {
                      "type": "string",
                      "description": "Plain-language equivalent of atBedtimeMg, e.g. \"about a cup of coffee\""
                    },
                    "hoursToThreshold": {
                      "description": "Hours until the level falls below thresholdMg; 0 if already below, null if not within 24 h",
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "totalMg": {
                      "type": "number",
                      "description": "Sum of the milligrams consumed in the submitted intakes"
                    }
                  },
                  "required": [
                    "currentMg",
                    "atBedtimeMg",
                    "bedtimeEquivalent",
                    "hoursToThreshold",
                    "totalMg"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid input"
          },
          "402": {
            "description": "Payment required: free tier exhausted. Headers carry an MPP challenge (WWW-Authenticate: Payment) and/or an x402 PAYMENT-REQUIRED payload.",
            "headers": {
              "WWW-Authenticate": {
                "schema": {
                  "type": "string"
                }
              },
              "PAYMENT-REQUIRED": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    }
  }
}
