{
  "openapi": "3.0.3",
  "info": {
    "title": "Beam AI SDK API",
    "description": "REST API for the Beam AI rPPG SDK. Extracts heart rate, HRV, stress, and SpO₂ from the selfie camera in real-time — no wearables required.\n\n## Authentication\nAll SDK requests require an API key passed in the `X-API-Key` header. Request a key at [beamos-2.polsia.app/keys](https://beamos-2.polsia.app/keys).\n\n## Base URL\n```\nhttps://beamos-2.polsia.app\n```\n\n## Quick Start\nSee the [integration guide](https://beamos-2.polsia.app/quickstart) for code examples.",
    "version": "1.0.0",
    "contact": {
      "name": "Beam AI Support",
      "url": "https://beamos-2.polsia.app/keys"
    },
    "license": {
      "name": "Commercial",
      "url": "https://beamos-2.polsia.app/why"
    }
  },
  "servers": [
    {
      "url": "https://beamos-2.polsia.app",
      "description": "Production"
    }
  ],
  "tags": [
    {
      "name": "Keys",
      "description": "API key management"
    },
    {
      "name": "Dashboard",
      "description": "Analytics and usage metrics"
    }
  ],
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "Beam AI API key (prefix: `beam_`). Obtain at https://beamos-2.polsia.app/keys"
      }
    },
    "schemas": {
      "ErrorResponse": {
        "type": "object",
        "required": ["success", "message"],
        "properties": {
          "success": {
            "type": "boolean",
            "example": false
          },
          "message": {
            "type": "string",
            "example": "Valid email is required"
          }
        }
      },
      "ApiKey": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "example": 42
          },
          "key": {
            "type": "string",
            "example": "beam_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4"
          },
          "name": {
            "type": "string",
            "example": "Jane Smith"
          },
          "email": {
            "type": "string",
            "format": "email",
            "example": "jane@healthapp.io"
          },
          "company": {
            "type": "string",
            "nullable": true,
            "example": "HealthApp Inc"
          },
          "use_case": {
            "type": "string",
            "nullable": true,
            "enum": ["telehealth", "wellness", "fitness", "research", "other"],
            "example": "telehealth"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-04-08T12:00:00Z"
          }
        }
      },
      "DashboardOverview": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "overview": {
            "type": "object",
            "properties": {
              "total_api_keys": {
                "type": "integer",
                "description": "Total registered API keys",
                "example": 127
              },
              "active_api_keys_30d": {
                "type": "integer",
                "description": "Keys that made at least one request in the last 30 days",
                "example": 43
              },
              "requests": {
                "type": "object",
                "properties": {
                  "last_24h": {
                    "type": "integer",
                    "example": 1842
                  },
                  "last_7d": {
                    "type": "integer",
                    "example": 12450
                  },
                  "last_30d": {
                    "type": "integer",
                    "example": 48901
                  }
                }
              },
              "error_rate_pct_30d": {
                "type": "number",
                "format": "float",
                "description": "Percentage of requests with 4xx/5xx status over last 30 days",
                "example": 1.24
              }
            }
          }
        }
      },
      "TimeSeriesBucket": {
        "type": "object",
        "properties": {
          "bucket": {
            "type": "string",
            "format": "date-time",
            "description": "Start of the time bucket (hour or day)",
            "example": "2026-04-07T00:00:00Z"
          },
          "total_requests": {
            "type": "integer",
            "example": 1842
          },
          "error_count": {
            "type": "integer",
            "example": 23
          },
          "server_error_count": {
            "type": "integer",
            "example": 2
          },
          "error_rate_pct": {
            "type": "number",
            "format": "float",
            "example": 1.25
          }
        }
      },
      "DashboardMetrics": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "range": {
            "type": "string",
            "enum": ["24h", "7d", "30d"],
            "example": "30d"
          },
          "time_series": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TimeSeriesBucket"
            }
          },
          "latency_percentiles": {
            "type": "object",
            "properties": {
              "p50_ms": {
                "type": "integer",
                "nullable": true,
                "description": "Median response time in ms",
                "example": 38
              },
              "p95_ms": {
                "type": "integer",
                "nullable": true,
                "description": "95th percentile response time in ms",
                "example": 142
              },
              "p99_ms": {
                "type": "integer",
                "nullable": true,
                "description": "99th percentile response time in ms",
                "example": 287
              },
              "avg_ms": {
                "type": "integer",
                "nullable": true,
                "description": "Average response time in ms",
                "example": 55
              }
            }
          }
        }
      },
      "ErrorEntry": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "example": 18
          },
          "error_type": {
            "type": "string",
            "enum": ["client_error", "server_error"],
            "example": "client_error"
          },
          "message": {
            "type": "string",
            "example": "GET /api/keys → 404"
          },
          "count": {
            "type": "integer",
            "description": "Total occurrences",
            "example": 14
          },
          "first_seen": {
            "type": "string",
            "format": "date-time",
            "example": "2026-04-01T08:22:11Z"
          },
          "last_seen": {
            "type": "string",
            "format": "date-time",
            "example": "2026-04-08T14:05:33Z"
          }
        }
      },
      "DashboardRecentErrors": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ErrorEntry"
            }
          },
          "total": {
            "type": "integer",
            "example": 7
          }
        }
      }
    }
  },
  "paths": {
    "/api/keys": {
      "post": {
        "tags": ["Keys"],
        "operationId": "requestApiKey",
        "summary": "Request an API key",
        "description": "Self-service API key registration. Generates a new `beam_` prefixed key and returns it immediately. Rate-limited to 3 keys per email address.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["name", "email"],
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Developer or contact name",
                    "example": "Jane Smith"
                  },
                  "email": {
                    "type": "string",
                    "format": "email",
                    "description": "Contact email — used for rate limiting (max 3 keys)",
                    "example": "jane@healthapp.io"
                  },
                  "company": {
                    "type": "string",
                    "description": "Company or product name (optional)",
                    "example": "HealthApp Inc"
                  },
                  "use_case": {
                    "type": "string",
                    "enum": ["telehealth", "wellness", "fitness", "research", "other"],
                    "description": "Primary integration use case (optional)",
                    "example": "telehealth"
                  }
                }
              },
              "examples": {
                "telehealth_developer": {
                  "summary": "Telehealth developer",
                  "value": {
                    "name": "Jane Smith",
                    "email": "jane@healthapp.io",
                    "company": "HealthApp Inc",
                    "use_case": "telehealth"
                  }
                },
                "minimal": {
                  "summary": "Minimal (name + email only)",
                  "value": {
                    "name": "John Doe",
                    "email": "john@example.com"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "API key created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "api_key": {
                      "$ref": "#/components/schemas/ApiKey"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error (missing name, invalid email, or invalid use_case)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "examples": {
                  "missing_email": {
                    "value": { "success": false, "message": "Valid email is required" }
                  },
                  "missing_name": {
                    "value": { "success": false, "message": "Name is required" }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — 3 keys per email maximum",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "success": false,
                  "message": "Maximum 3 API keys per email. Contact support for additional keys."
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/dashboard/overview": {
      "get": {
        "tags": ["Dashboard"],
        "operationId": "getDashboardOverview",
        "summary": "SDK dashboard overview",
        "description": "Returns aggregate SDK usage metrics: total keys registered, active keys in last 30 days, request volumes (24h / 7d / 30d), and overall error rate.",
        "security": [{ "ApiKeyAuth": [] }],
        "responses": {
          "200": {
            "description": "Overview data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DashboardOverview"
                }
              }
            }
          },
          "500": {
            "description": "Database error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/dashboard/metrics": {
      "get": {
        "tags": ["Dashboard"],
        "operationId": "getDashboardMetrics",
        "summary": "Time-series metrics",
        "description": "Returns time-bucketed request volume, error counts, and latency percentiles. Bucket size adjusts automatically: hourly for 24h range, daily for 7d and 30d.",
        "security": [{ "ApiKeyAuth": [] }],
        "parameters": [
          {
            "name": "range",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["24h", "7d", "30d"],
              "default": "30d"
            },
            "description": "Time range for the metrics window",
            "example": "30d"
          }
        ],
        "responses": {
          "200": {
            "description": "Time-series metrics and latency percentiles",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DashboardMetrics"
                }
              }
            }
          },
          "500": {
            "description": "Database error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/dashboard/recent-errors": {
      "get": {
        "tags": ["Dashboard"],
        "operationId": "getDashboardRecentErrors",
        "summary": "Recent error log",
        "description": "Returns the 50 most recent aggregated error entries ordered by last occurrence. Each entry includes the error type (client_error / server_error), the request path and status, occurrence count, and timestamps.",
        "security": [{ "ApiKeyAuth": [] }],
        "responses": {
          "200": {
            "description": "List of recent errors",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DashboardRecentErrors"
                }
              }
            }
          },
          "500": {
            "description": "Database error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    }
  }
}
