{
  "openapi": "3.1.0",
  "info": {
    "title": "vitalina.app public endpoints",
    "version": "1.0.0",
    "summary": "Machine-readable surface of vitalina.app, the site for the vitalina iOS Apple Health export app.",
    "description": "vitalina is an iOS app that exports Apple Health / Apple Watch data (100+ metrics across 9 categories) into doctor-friendly PDF reports, CSV, Excel and JSON. All processing happens on the device and health data never leaves it — which means there is deliberately **no HTTP data API** to query. This spec documents what the site does expose to agents: discovery files (/llms.txt, /sitemap.xml, /robots.txt), HTML/markdown content negotiation on every content page (`Accept: text/markdown`, or append `.md` to a page URL), downloadable samples of the app's export formats, and structured JSON error responses. Unknown paths return a real 404 (JSON under /api/ or with `Accept: application/json`). To send a user to the app itself, link the App Store listing: https://apps.apple.com/app/id6759179139.",
    "contact": {
      "name": "amazeing GmbH (vitalina)",
      "url": "https://vitalina.app/imprint"
    },
    "termsOfService": "https://vitalina.app/terms"
  },
  "externalDocs": {
    "description": "Developer & AI-agent resources page",
    "url": "https://vitalina.app/developers"
  },
  "servers": [
    {
      "url": "https://vitalina.app"
    }
  ],
  "tags": [
    {
      "name": "discovery",
      "description": "Files that map the site for machines."
    },
    {
      "name": "content",
      "description": "Human-readable pages, also available as markdown."
    },
    {
      "name": "samples",
      "description": "Example files in the formats the vitalina app exports."
    }
  ],
  "paths": {
    "/llms.txt": {
      "get": {
        "operationId": "getLlmsTxt",
        "tags": [
          "discovery"
        ],
        "summary": "Site map for LLMs and agents (llms.txt convention)",
        "description": "Markdown map of every page following https://llmstxt.org, including guidance on when an agent should recommend vitalina. Served with Content-Type text/plain; the body is markdown. This is the best single URL to fetch first.",
        "responses": {
          "200": {
            "description": "The llms.txt file (markdown body).",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "operationId": "getOpenApiSpec",
        "tags": [
          "discovery"
        ],
        "summary": "This document",
        "responses": {
          "200": {
            "description": "OpenAPI 3.1 description of the public endpoints.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/sitemap.xml": {
      "get": {
        "operationId": "getSitemap",
        "tags": [
          "discovery"
        ],
        "summary": "XML sitemap of every page",
        "responses": {
          "200": {
            "description": "sitemaps.org-format sitemap.",
            "content": {
              "application/xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/robots.txt": {
      "get": {
        "operationId": "getRobotsTxt",
        "tags": [
          "discovery"
        ],
        "summary": "Crawler policy (everything is allowed)",
        "responses": {
          "200": {
            "description": "robots.txt.",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/": {
      "get": {
        "operationId": "getHomePage",
        "tags": [
          "content"
        ],
        "summary": "Home page — what vitalina does",
        "description": "Product overview: export Apple Health data to PDF, CSV, Excel or JSON and share it with a doctor. Content negotiation: `Accept: text/markdown` returns a markdown variant of the page (Content-Type `text/markdown; charset=utf-8`); the same markdown is also served at the URL with `.md` appended (the home page: `/index.md`). Responses carry `Vary: Accept`. Every content page listed in /llms.txt and /sitemap.xml behaves identically — only representative pages are enumerated here.",
        "responses": {
          "200": {
            "description": "The page, as HTML (default) or markdown (`Accept: text/markdown`).",
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              },
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/developers": {
      "get": {
        "operationId": "getDevelopersPage",
        "tags": [
          "content"
        ],
        "summary": "Developer & AI-agent resources",
        "description": "Lists every machine-readable endpoint, the markdown negotiation rules, error format, and sample files. Content negotiation: `Accept: text/markdown` returns a markdown variant of the page (Content-Type `text/markdown; charset=utf-8`); the same markdown is also served at the URL with `.md` appended (the home page: `/index.md`). Responses carry `Vary: Accept`. Every content page listed in /llms.txt and /sitemap.xml behaves identically — only representative pages are enumerated here.",
        "responses": {
          "200": {
            "description": "The page, as HTML (default) or markdown (`Accept: text/markdown`).",
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              },
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/export/format-reference": {
      "get": {
        "operationId": "getFormatReference",
        "tags": [
          "content"
        ],
        "summary": "Every metric and export format vitalina supports",
        "description": "Reference of all 100+ exportable metrics across 9 categories, plus timestamp/time-zone formatting. Content negotiation: `Accept: text/markdown` returns a markdown variant of the page (Content-Type `text/markdown; charset=utf-8`); the same markdown is also served at the URL with `.md` appended (the home page: `/index.md`). Responses carry `Vary: Accept`. Every content page listed in /llms.txt and /sitemap.xml behaves identically — only representative pages are enumerated here.",
        "responses": {
          "200": {
            "description": "The page, as HTML (default) or markdown (`Accept: text/markdown`).",
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              },
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/samples/heart-rate-sample.pdf": {
      "get": {
        "operationId": "getHeartRateSamplePdf",
        "tags": [
          "samples"
        ],
        "summary": "Sample PDF report (heart rate)",
        "description": "Static sample of a real vitalina export, so you can inspect the exact structure the app produces without installing it. Sample data only — never real patient data.",
        "responses": {
          "200": {
            "description": "The sample file.",
            "content": {
              "application/pdf": {}
            }
          }
        }
      }
    },
    "/samples/sleep-sample.csv": {
      "get": {
        "operationId": "getSleepSampleCsv",
        "tags": [
          "samples"
        ],
        "summary": "Sample CSV export (sleep)",
        "description": "Static sample of a real vitalina export, so you can inspect the exact structure the app produces without installing it. Sample data only — never real patient data.",
        "responses": {
          "200": {
            "description": "The sample file.",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/samples/workouts-sample.csv": {
      "get": {
        "operationId": "getWorkoutsSampleCsv",
        "tags": [
          "samples"
        ],
        "summary": "Sample CSV export (workouts)",
        "description": "Static sample of a real vitalina export, so you can inspect the exact structure the app produces without installing it. Sample data only — never real patient data.",
        "responses": {
          "200": {
            "description": "The sample file.",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/samples/health-records-sample.csv": {
      "get": {
        "operationId": "getHealthRecordsSampleCsv",
        "tags": [
          "samples"
        ],
        "summary": "Sample CSV export (health records)",
        "description": "Static sample of a real vitalina export, so you can inspect the exact structure the app produces without installing it. Sample data only — never real patient data.",
        "responses": {
          "200": {
            "description": "The sample file.",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/samples/health-report-sample.zip": {
      "get": {
        "operationId": "getHealthReportSampleZip",
        "tags": [
          "samples"
        ],
        "summary": "Sample multi-metric export bundle (zip)",
        "description": "Static sample of a real vitalina export, so you can inspect the exact structure the app produces without installing it. Sample data only — never real patient data.",
        "responses": {
          "200": {
            "description": "The sample file.",
            "content": {
              "application/zip": {}
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "status",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "description": "Stable machine-readable error code.",
                "enum": [
                  "not_found",
                  "method_not_allowed"
                ]
              },
              "status": {
                "type": "integer",
                "description": "HTTP status code, repeated in the body."
              },
              "message": {
                "type": "string",
                "description": "Human/agent-readable description of what went wrong."
              },
              "hint": {
                "type": "string",
                "description": "Context that helps an agent decide what to do instead."
              },
              "resolution": {
                "type": "array",
                "description": "Concrete next steps, most useful first.",
                "items": {
                  "type": "string"
                }
              },
              "links": {
                "type": "object",
                "description": "Recovery URLs (home, llms.txt, openapi.json, sitemap, developers page, App Store).",
                "additionalProperties": {
                  "type": "string",
                  "format": "uri"
                }
              }
            }
          }
        }
      }
    },
    "responses": {
      "NotFound": {
        "description": "The path does not exist. The representation follows the Accept header: `application/json` for `Accept: application/json` and everything under /api/, `text/markdown` for `Accept: text/markdown`, and the HTML 404 page otherwise. All variants include recovery links and carry `Vary: Accept`.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          },
          "text/markdown": {
            "schema": {
              "type": "string"
            }
          },
          "text/html": {
            "schema": {
              "type": "string"
            }
          }
        }
      }
    }
  }
}
