{
  "openapi": "3.1.0",
  "info": {
    "title": "xeve API",
    "version": "1.0.0",
    "summary": "Read and write one person's own measured activity.",
    "description": "The xeve API returns the caller's own analytics: application and website usage, coding time by project and language, GitHub activity, listening history, health samples, heart rate, locations and the AI summaries computed over them.\n\nNo endpoint accepts a user id. The server derives the user from the credential and Postgres row-level security filters every query, so a request can only ever return the caller's own rows.\n\nTwo credentials, both sent as `Authorization: Bearer <token>`: an API token created by a signed-in human, or an OAuth 2.0 access token obtained on a user's behalf. Both carry scopes; a request outside them answers 403 naming the scope it needed.\n\nHuman documentation: https://xeve.io/docs/api",
    "termsOfService": "https://xeve.io/terms",
    "contact": {
      "name": "xeve support",
      "email": "hello@xeve.io",
      "url": "https://xeve.io/contact"
    },
    "license": {
      "name": "MIT",
      "identifier": "MIT"
    }
  },
  "externalDocs": {
    "description": "xeve developer documentation",
    "url": "https://xeve.io/docs"
  },
  "servers": [
    {
      "url": "https://api.xeve.io",
      "description": "Hosted xeve"
    },
    {
      "url": "http://localhost:3001",
      "description": "A local or self-hosted instance"
    }
  ],
  "tags": [
    {
      "name": "Activity",
      "description": "Applications, coding, devices and the aggregates over them"
    },
    {
      "name": "Code",
      "description": "GitHub commits, pull requests and reviews"
    },
    {
      "name": "Health",
      "description": "Health samples, heart rate and recovery"
    },
    {
      "name": "Location",
      "description": "Check-ins and location history"
    },
    {
      "name": "Music",
      "description": "Listening history"
    },
    {
      "name": "Content",
      "description": "Recordings, insights, watch history and calendar"
    },
    {
      "name": "Profile",
      "description": "Profile, integrations, organizations and teams"
    },
    {
      "name": "Ingest",
      "description": "Writing measurements from a tracker"
    },
    {
      "name": "MCP",
      "description": "The Model Context Protocol endpoint"
    },
    {
      "name": "Service",
      "description": "Liveness and capabilities"
    }
  ],
  "security": [
    {
      "apiToken": []
    },
    {
      "oauth2": [
        "read:activity",
        "read:code",
        "read:health",
        "read:location",
        "read:music",
        "read:content",
        "read:profile",
        "ingest:app_sessions",
        "ingest:coding_sessions",
        "ingest:health",
        "ingest:heartbeats"
      ]
    }
  ],
  "paths": {
    "/healthz": {
      "get": {
        "operationId": "healthz",
        "summary": "Liveness",
        "description": "Liveness, database reachability, and the running build. Unauthenticated.",
        "tags": [
          "Service"
        ],
        "security": [],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "503": {
            "description": "The database is unreachable."
          }
        }
      }
    },
    "/api/v1/capabilities": {
      "get": {
        "operationId": "capabilities",
        "summary": "Capabilities",
        "description": "Which optional features this deployment has configured. Unauthenticated.",
        "tags": [
          "Service"
        ],
        "security": [],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          }
        }
      }
    },
    "/api/v1/ingest/schema": {
      "get": {
        "operationId": "ingestSchema",
        "summary": "Ingest contract",
        "description": "The streams a tracker can write to, their scopes, idempotency keys and limits. Unauthenticated, so a tracker author can read it before holding a credential.",
        "tags": [
          "Ingest"
        ],
        "security": [],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          }
        }
      }
    },
    "/api/v1/analytics/daily": {
      "get": {
        "operationId": "analyticsDaily",
        "summary": "Daily totals",
        "description": "Day-by-day tracked, productive, distracted and coding time, and app switches.",
        "tags": [
          "Activity"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:activity"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/fromDate"
          },
          {
            "$ref": "#/components/parameters/toDate"
          }
        ]
      }
    },
    "/api/v1/analytics/app-usage": {
      "get": {
        "operationId": "analyticsAppUsage",
        "summary": "App usage",
        "description": "Time per application, with category and session count.",
        "tags": [
          "Activity"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:activity"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/from"
          },
          {
            "$ref": "#/components/parameters/to"
          }
        ]
      }
    },
    "/api/v1/analytics/categories": {
      "get": {
        "operationId": "analyticsCategories",
        "summary": "Category breakdown",
        "description": "Time per category over a range.",
        "tags": [
          "Activity"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:activity"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/from"
          },
          {
            "$ref": "#/components/parameters/to"
          }
        ]
      }
    },
    "/api/v1/analytics/daily-categories": {
      "get": {
        "operationId": "analyticsDailyCategories",
        "summary": "Categories per day",
        "description": "Category totals, day by day.",
        "tags": [
          "Activity"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:activity"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/from"
          },
          {
            "$ref": "#/components/parameters/to"
          }
        ]
      }
    },
    "/api/v1/analytics/coding": {
      "get": {
        "operationId": "analyticsCoding",
        "summary": "Coding summary",
        "description": "Coding time by project and language.",
        "tags": [
          "Activity"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:activity"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/from"
          },
          {
            "$ref": "#/components/parameters/to"
          }
        ]
      }
    },
    "/api/v1/analytics/hourly": {
      "get": {
        "operationId": "analyticsHourly",
        "summary": "Hourly activity",
        "description": "One day, hour by hour, by category.",
        "tags": [
          "Activity"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:activity"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/date"
          },
          {
            "$ref": "#/components/parameters/tz"
          }
        ]
      }
    },
    "/api/v1/analytics/hourly-patterns": {
      "get": {
        "operationId": "analyticsHourlyPatterns",
        "summary": "Hourly patterns",
        "description": "Historical day-of-week and hour baseline.",
        "tags": [
          "Activity"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:activity"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/weeks"
          },
          {
            "$ref": "#/components/parameters/tz"
          }
        ]
      }
    },
    "/api/v1/analytics/context-switches": {
      "get": {
        "operationId": "analyticsContextSwitches",
        "summary": "Context switches",
        "description": "App-to-app switches and the time spent before each.",
        "tags": [
          "Activity"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:activity"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/from"
          },
          {
            "$ref": "#/components/parameters/to"
          }
        ]
      }
    },
    "/api/v1/analytics/focus-streaks": {
      "get": {
        "operationId": "analyticsFocusStreaks",
        "summary": "Focus streaks",
        "description": "Uninterrupted stretches of work, and what broke them.",
        "tags": [
          "Activity"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:activity"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/from"
          },
          {
            "$ref": "#/components/parameters/to"
          }
        ]
      }
    },
    "/api/v1/sessions/apps": {
      "get": {
        "operationId": "sessionsApps",
        "summary": "App sessions",
        "description": "Individual application sessions, newest first.",
        "tags": [
          "Activity"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:activity"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/from"
          },
          {
            "$ref": "#/components/parameters/to"
          },
          {
            "$ref": "#/components/parameters/limit"
          }
        ]
      }
    },
    "/api/v1/sessions/by-app": {
      "get": {
        "operationId": "sessionsByApp",
        "summary": "Sessions by app",
        "description": "Sessions grouped by application.",
        "tags": [
          "Activity"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:activity"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/from"
          },
          {
            "$ref": "#/components/parameters/to"
          }
        ]
      }
    },
    "/api/v1/sessions/coding": {
      "get": {
        "operationId": "sessionsCoding",
        "summary": "Coding sessions",
        "description": "Individual coding sessions.",
        "tags": [
          "Activity"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:activity"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/from"
          },
          {
            "$ref": "#/components/parameters/to"
          },
          {
            "$ref": "#/components/parameters/limit"
          }
        ]
      }
    },
    "/api/v1/sessions/daily": {
      "get": {
        "operationId": "sessionsDaily",
        "summary": "Sessions per day",
        "description": "Per-day session rollup.",
        "tags": [
          "Activity"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:activity"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/from"
          },
          {
            "$ref": "#/components/parameters/to"
          }
        ]
      }
    },
    "/api/v1/devices": {
      "get": {
        "operationId": "devices",
        "summary": "Devices",
        "description": "Registered trackers and when each last synced.",
        "tags": [
          "Activity"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:activity"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/v1/goals": {
      "get": {
        "operationId": "goals",
        "summary": "Goals",
        "description": "Goals and progress.",
        "tags": [
          "Activity"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:activity"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/v1/export": {
      "get": {
        "operationId": "export",
        "summary": "Export",
        "description": "Everything, as CSV or JSON.",
        "tags": [
          "Activity"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:activity"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/v1/account/correlation": {
      "get": {
        "operationId": "accountCorrelation",
        "summary": "Correlation",
        "description": "Correlation between two metrics over a range.",
        "tags": [
          "Activity"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:activity"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/v1/account/summaries": {
      "get": {
        "operationId": "accountSummaries",
        "summary": "Stored summaries",
        "description": "Stored daily summaries.",
        "tags": [
          "Activity"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:activity"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/v1/github/activity": {
      "get": {
        "operationId": "githubActivity",
        "summary": "GitHub activity",
        "description": "The event feed: commits, pull requests, reviews.",
        "tags": [
          "Code"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:code"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/limit"
          }
        ]
      }
    },
    "/api/v1/github/activity/counts": {
      "get": {
        "operationId": "githubActivityCounts",
        "summary": "GitHub counts",
        "description": "Counts and line changes per event type.",
        "tags": [
          "Code"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:code"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/from"
          },
          {
            "$ref": "#/components/parameters/to"
          }
        ]
      }
    },
    "/api/v1/health/summary": {
      "get": {
        "operationId": "healthSummary",
        "summary": "Health summary",
        "description": "Per-metric totals, averages, minimum and maximum.",
        "tags": [
          "Health"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:health"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/from"
          },
          {
            "$ref": "#/components/parameters/to"
          }
        ]
      }
    },
    "/api/v1/health/samples": {
      "get": {
        "operationId": "healthSamples",
        "summary": "Health samples",
        "description": "Raw samples for one metric.",
        "tags": [
          "Health"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:health"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/metricType"
          },
          {
            "$ref": "#/components/parameters/from"
          },
          {
            "$ref": "#/components/parameters/to"
          },
          {
            "$ref": "#/components/parameters/limit"
          }
        ]
      }
    },
    "/api/v1/health/heart-rate": {
      "get": {
        "operationId": "healthHeartRate",
        "summary": "Heart rate",
        "description": "Readings from connected Bluetooth monitors.",
        "tags": [
          "Health"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:health"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/from"
          },
          {
            "$ref": "#/components/parameters/to"
          },
          {
            "$ref": "#/components/parameters/limit"
          }
        ]
      }
    },
    "/api/v1/health/recovery": {
      "get": {
        "operationId": "healthRecovery",
        "summary": "Recovery",
        "description": "Whoop recovery, strain and sleep, by calendar day.",
        "tags": [
          "Health"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:health"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/fromDate"
          },
          {
            "$ref": "#/components/parameters/toDate"
          }
        ]
      }
    },
    "/api/v1/music/history": {
      "get": {
        "operationId": "musicHistory",
        "summary": "Listening history",
        "description": "Tracks played, with artist and album.",
        "tags": [
          "Music"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:music"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/from"
          },
          {
            "$ref": "#/components/parameters/to"
          },
          {
            "$ref": "#/components/parameters/limit"
          }
        ]
      }
    },
    "/api/v1/music/daily": {
      "get": {
        "operationId": "musicDaily",
        "summary": "Listening per day",
        "description": "Listening totals per day.",
        "tags": [
          "Music"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:music"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/from"
          },
          {
            "$ref": "#/components/parameters/to"
          }
        ]
      }
    },
    "/api/v1/locations": {
      "get": {
        "operationId": "locations",
        "summary": "Locations",
        "description": "Location history.",
        "tags": [
          "Location"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:location"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/from"
          },
          {
            "$ref": "#/components/parameters/to"
          },
          {
            "$ref": "#/components/parameters/limit"
          }
        ]
      }
    },
    "/api/v1/locations/events": {
      "get": {
        "operationId": "locationsEvents",
        "summary": "Check-ins",
        "description": "Check-in events with place and status.",
        "tags": [
          "Location"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:location"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/from"
          },
          {
            "$ref": "#/components/parameters/to"
          },
          {
            "$ref": "#/components/parameters/limit"
          }
        ]
      }
    },
    "/api/v1/insights": {
      "get": {
        "operationId": "insights",
        "summary": "AI insights",
        "description": "Weekly insights already computed over this user's data.",
        "tags": [
          "Content"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:content"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/limit"
          }
        ]
      }
    },
    "/api/v1/recordings": {
      "get": {
        "operationId": "recordings",
        "summary": "Recordings",
        "description": "Voice recordings and transcripts.",
        "tags": [
          "Content"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:content"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/limit"
          }
        ]
      }
    },
    "/api/v1/watching/genres": {
      "get": {
        "operationId": "watchingGenres",
        "summary": "Watch history",
        "description": "Watch history by genre.",
        "tags": [
          "Content"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:content"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/v1/calendar/events": {
      "get": {
        "operationId": "calendarEvents",
        "summary": "Calendar events",
        "description": "Events from connected calendar providers.",
        "tags": [
          "Content"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:content"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/from"
          },
          {
            "$ref": "#/components/parameters/to"
          },
          {
            "$ref": "#/components/parameters/limit"
          }
        ]
      }
    },
    "/api/v1/me": {
      "get": {
        "operationId": "me",
        "summary": "Profile",
        "description": "The caller's own profile, timezone and admin flag.",
        "tags": [
          "Profile"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:profile"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/v1/integrations": {
      "get": {
        "operationId": "integrations",
        "summary": "Integrations",
        "description": "Which integrations are connected. Never their credentials.",
        "tags": [
          "Profile"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:profile"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/v1/orgs": {
      "get": {
        "operationId": "orgs",
        "summary": "Organizations",
        "description": "Organizations the caller belongs to.",
        "tags": [
          "Profile"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:profile"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/v1/teams": {
      "get": {
        "operationId": "teams",
        "summary": "Teams",
        "description": "Teams the caller belongs to.",
        "tags": [
          "Profile"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:profile"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/v1/account/subscription": {
      "get": {
        "operationId": "accountSubscription",
        "summary": "Subscription",
        "description": "Plan and billing state.",
        "tags": [
          "Profile"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:profile"
            ]
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Ok"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    },
    "/api/v1/ingest/app-sessions": {
      "post": {
        "operationId": "ingestAppSessions",
        "summary": "Write app sessions",
        "description": "A batch of events, up to 1000. Always answers 200 with a per-event result: one malformed event must not wedge a client's retry queue. Send an idempotency_key per event, or let the server derive one.",
        "tags": [
          "Ingest"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "ingest:app_sessions"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "events"
                ],
                "properties": {
                  "events": {
                    "type": "array",
                    "maxItems": 1000,
                    "items": {
                      "type": "object"
                    }
                  },
                  "client": {
                    "type": "object",
                    "properties": {
                      "name": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Per-event results.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "accepted": {
                      "type": "integer"
                    },
                    "duplicates": {
                      "type": "integer"
                    },
                    "rejected": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "index": {
                            "type": "integer"
                          },
                          "code": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "server_time": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "413": {
            "description": "More than 1000 events in one batch."
          }
        }
      }
    },
    "/api/v1/ingest/coding-sessions": {
      "post": {
        "operationId": "ingestCodingSessions",
        "summary": "Write coding sessions",
        "description": "A batch of events, up to 1000. Always answers 200 with a per-event result: one malformed event must not wedge a client's retry queue. Send an idempotency_key per event, or let the server derive one.",
        "tags": [
          "Ingest"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "ingest:coding_sessions"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "events"
                ],
                "properties": {
                  "events": {
                    "type": "array",
                    "maxItems": 1000,
                    "items": {
                      "type": "object"
                    }
                  },
                  "client": {
                    "type": "object",
                    "properties": {
                      "name": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Per-event results.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "accepted": {
                      "type": "integer"
                    },
                    "duplicates": {
                      "type": "integer"
                    },
                    "rejected": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "index": {
                            "type": "integer"
                          },
                          "code": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "server_time": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "413": {
            "description": "More than 1000 events in one batch."
          }
        }
      }
    },
    "/mcp": {
      "post": {
        "operationId": "mcp",
        "summary": "MCP endpoint (Streamable HTTP)",
        "description": "The Model Context Protocol endpoint. JSON-RPC 2.0 over HTTP POST: a request returns one JSON object, a notification returns 202 with no body. Stateless - no session id, no SSE stream. Read-only tools, each enforcing the scope it needs. See https://xeve.io/docs/mcp.",
        "tags": [
          "MCP"
        ],
        "security": [
          {
            "apiToken": []
          },
          {
            "oauth2": [
              "read:activity"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "jsonrpc",
                  "method"
                ],
                "properties": {
                  "jsonrpc": {
                    "type": "string",
                    "const": "2.0"
                  },
                  "id": {
                    "type": [
                      "string",
                      "number"
                    ]
                  },
                  "method": {
                    "type": "string"
                  },
                  "params": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A JSON-RPC response.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "202": {
            "description": "A notification was accepted."
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiToken": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "xeve_dt_...",
        "description": "An API token created by a signed-in user at https://xeve.io/dashboard/settings. Scoped, individually revocable, and shown once."
      },
      "oauth2": {
        "type": "oauth2",
        "description": "OAuth 2.0 with PKCE (S256 required) and open dynamic client registration (RFC 7591). Metadata: https://xeve.io/.well-known/oauth-authorization-server. Access tokens expire after one hour and refresh tokens rotate. See https://xeve.io/docs/oauth.",
        "flows": {
          "authorizationCode": {
            "authorizationUrl": "https://xeve.io/oauth/authorize",
            "tokenUrl": "https://xeve.io/oauth/token",
            "refreshUrl": "https://xeve.io/oauth/token",
            "scopes": {
              "read:activity": "App and coding sessions, devices, goals, and the activity aggregates over them",
              "read:code": "GitHub activity: commits, pull requests, reviews",
              "read:health": "Health samples, heart rate, recovery",
              "read:location": "Check-ins and location history",
              "read:music": "Listening history",
              "read:content": "Recordings, AI insights, watch history, calendar",
              "read:profile": "Profile and which integrations are connected, never their credentials",
              "ingest:app_sessions": "Write application usage",
              "ingest:coding_sessions": "Write coding sessions",
              "ingest:health": "Write health samples",
              "ingest:heartbeats": "Write editor heartbeats"
            }
          }
        }
      }
    },
    "parameters": {
      "from": {
        "name": "from",
        "in": "query",
        "required": true,
        "description": "Start of the range, as an ISO 8601 instant.",
        "schema": {
          "type": "string",
          "format": "date-time"
        }
      },
      "to": {
        "name": "to",
        "in": "query",
        "required": true,
        "description": "End of the range, as an ISO 8601 instant.",
        "schema": {
          "type": "string",
          "format": "date-time"
        }
      },
      "fromDate": {
        "name": "from",
        "in": "query",
        "required": true,
        "description": "First calendar day, YYYY-MM-DD.",
        "schema": {
          "type": "string",
          "format": "date"
        }
      },
      "toDate": {
        "name": "to",
        "in": "query",
        "required": true,
        "description": "Last calendar day, YYYY-MM-DD.",
        "schema": {
          "type": "string",
          "format": "date"
        }
      },
      "date": {
        "name": "date",
        "in": "query",
        "required": true,
        "description": "The day, YYYY-MM-DD.",
        "schema": {
          "type": "string",
          "format": "date"
        }
      },
      "tz": {
        "name": "tz",
        "in": "query",
        "required": false,
        "description": "IANA timezone for day and hour boundaries. Defaults to UTC.",
        "schema": {
          "type": "string",
          "default": "UTC"
        }
      },
      "limit": {
        "name": "limit",
        "in": "query",
        "required": false,
        "description": "Maximum rows to return. Each endpoint has its own cap.",
        "schema": {
          "type": "integer",
          "minimum": 0
        }
      },
      "weeks": {
        "name": "weeks",
        "in": "query",
        "required": false,
        "description": "How many weeks of history to average over.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 52,
          "default": 6
        }
      },
      "metricType": {
        "name": "metric_type",
        "in": "query",
        "required": true,
        "description": "The HealthKit metric to return samples for.",
        "schema": {
          "type": "string"
        }
      }
    },
    "responses": {
      "Ok": {
        "description": "Success.",
        "content": {
          "application/json": {
            "schema": {}
          }
        }
      },
      "BadRequest": {
        "description": "A malformed parameter. The body names which one.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "No credential, or one that was revoked, expired or never existed.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Forbidden": {
        "description": "A valid credential without the scope this endpoint needs.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "error"
        ]
      }
    }
  }
}
