{
  "openapi": "3.1.0",
  "info": {
    "title": "Sonar Public API",
    "version": "1.0.0",
    "description": "Create API users, connect cloud device providers, and read normalized daily metrics, scores, workouts, sleep sessions, and sampled vitals."
  },
  "servers": [{ "url": "https://atlas.sonarhealth.co", "description": "Production API" }],
  "security": [{ "BearerAuth": [] }],
  "paths": {
    "/v1/providers": {
      "get": {
        "operationId": "listProviders",
        "summary": "List device providers",
        "description": "Returns the authoritative catalog of cloud providers available for hosted authorization.",
        "tags": ["Devices"],
        "responses": {
          "200": {
            "description": "Provider catalog",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ProviderCatalog" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/PaymentRequired" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/consolidation/catalog": {
      "get": {
        "operationId": "getConsolidationCatalog",
        "summary": "Retrieve the consolidation catalog",
        "description": "Returns the authoritative metrics, groups, defaults, and methods available for user consolidation configuration.",
        "tags": ["Consolidation"],
        "responses": {
          "200": {
            "description": "Consolidation catalog",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ConsolidationCatalog" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/PaymentRequired" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/users": {
      "post": {
        "operationId": "createUser",
        "summary": "Create a user",
        "tags": ["Users"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": { "schema": { "$ref": "#/components/schemas/CreateUserRequest" } }
          }
        },
        "responses": {
          "201": {
            "description": "User created",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/User" } } }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/PaymentRequired" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "get": {
        "operationId": "listUsers",
        "summary": "List users",
        "tags": ["Users"],
        "parameters": [
          {
            "name": "external_ref",
            "in": "query",
            "description": "Exact external reference lookup.",
            "schema": { "type": "string", "minLength": 1 }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "Opaque cursor from the prior page.",
            "schema": { "type": "string", "minLength": 1 }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of users",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/UserList" } }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/PaymentRequired" },
          "422": { "$ref": "#/components/responses/Unprocessable" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/users/{id}": {
      "parameters": [{ "$ref": "#/components/parameters/UserId" }],
      "get": {
        "operationId": "getUser",
        "summary": "Retrieve a user",
        "tags": ["Users"],
        "responses": {
          "200": {
            "description": "User",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/UserDetails" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/PaymentRequired" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "patch": {
        "operationId": "updateUserProfile",
        "summary": "Update a user",
        "tags": ["Users"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": { "schema": { "$ref": "#/components/schemas/UpdateUserRequest" } }
          }
        },
        "responses": {
          "200": {
            "description": "Updated user",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/User" } } }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/PaymentRequired" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "delete": {
        "operationId": "deleteUser",
        "summary": "Delete a user",
        "description": "Queues asynchronous provider disconnection and data deletion.",
        "tags": ["Users"],
        "responses": {
          "202": {
            "description": "Deletion accepted",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/DeletionAccepted" } }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/PaymentRequired" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/atlas/roster/invitations": {
      "post": {
        "operationId": "inviteAtlasRosterMember",
        "summary": "Invite an Atlas roster member",
        "description": "Creates and sends a 14-day invitation. Live API keys only.",
        "tags": ["Atlas Roster"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/RosterInvitationRequest" }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Invitation created",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/RosterInvitation" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/PaymentRequired" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/atlas/roster/invitations/{id}": {
      "parameters": [{ "$ref": "#/components/parameters/RosterInvitationId" }],
      "get": {
        "operationId": "getAtlasRosterInvitation",
        "summary": "Retrieve an Atlas roster invitation",
        "tags": ["Atlas Roster"],
        "responses": {
          "200": {
            "description": "Invitation status",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/RosterInvitationStatus" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/PaymentRequired" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "delete": {
        "operationId": "revokeAtlasRosterInvitation",
        "summary": "Revoke an Atlas roster invitation",
        "tags": ["Atlas Roster"],
        "responses": {
          "204": { "description": "Invitation revoked or already inactive" },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/PaymentRequired" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/atlas/roster/{id}": {
      "parameters": [{ "$ref": "#/components/parameters/RosterSubjectId" }],
      "patch": {
        "operationId": "updateAtlasRosterMember",
        "summary": "Archive or reactivate an Atlas roster member",
        "description": "Changes the active roster status without deleting the person's Sonar account or health data. Live API keys only.",
        "tags": ["Atlas Roster"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/RosterStatusPatch" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Current roster member",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/RosterMember" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/PaymentRequired" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "delete": {
        "operationId": "deleteAtlasRosterMember",
        "summary": "Remove a member from the Atlas roster",
        "description": "Revokes organization sharing and removes the roster projection without deleting the person's Sonar account or health data. Live API keys only.",
        "tags": ["Atlas Roster"],
        "responses": {
          "204": { "description": "Roster member removed or already removed" },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/PaymentRequired" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/users/{id}/sdk-sessions": {
      "parameters": [{ "$ref": "#/components/parameters/UserId" }],
      "post": {
        "operationId": "createSdkSession",
        "summary": "Create or recover a Mobile SDK session",
        "tags": ["Mobile SDKs"],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": { "type": "string", "format": "uuid" }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/CreateSdkSessionRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Recovery bootstrap or idempotent replay",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/SdkBootstrap" } }
            }
          },
          "201": {
            "description": "Installation session created",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/SdkBootstrap" } }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": { "$ref": "#/components/responses/Conflict" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "get": {
        "operationId": "listSdkSessions",
        "summary": "List current Mobile SDK sessions",
        "tags": ["Mobile SDKs"],
        "responses": {
          "200": {
            "description": "Pending and active installation sessions",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/SdkSessionList" } }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/users/{id}/sdk-sessions/{session_id}": {
      "delete": {
        "operationId": "revokeSdkSession",
        "summary": "Revoke a Mobile SDK session",
        "tags": ["Mobile SDKs"],
        "parameters": [
          { "$ref": "#/components/parameters/UserId" },
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "format": "uuid" }
          }
        ],
        "responses": {
          "204": { "description": "Session revoked" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/sdk/sessions/exchange": {
      "post": {
        "operationId": "exchangeSdkClientToken",
        "summary": "Exchange a single-use Mobile SDK client token",
        "tags": ["Mobile SDKs"],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["client_token"],
                "properties": { "client_token": { "type": "string" } }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Renewable Mobile SDK credentials",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SdkCredentialResponse" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/v1/sdk/sessions/refresh": {
      "post": {
        "operationId": "refreshSdkSession",
        "summary": "Rotate Mobile SDK credentials",
        "tags": ["Mobile SDKs"],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": { "schema": { "$ref": "#/components/schemas/SdkRefreshRequest" } }
          }
        },
        "responses": {
          "200": {
            "description": "Rotated Mobile SDK credentials",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SdkCredentialResponse" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/v1/sdk/sessions/current": {
      "delete": {
        "operationId": "revokeCurrentSdkSession",
        "summary": "Revoke the authenticated Mobile SDK session",
        "tags": ["Mobile SDKs"],
        "security": [{ "SdkBearerAuth": [] }],
        "responses": {
          "204": { "description": "Session revoked" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/users/{id}/devices": {
      "post": {
        "operationId": "startDeviceAuthorization",
        "summary": "Start a device-provider authorization",
        "tags": ["Devices"],
        "parameters": [{ "$ref": "#/components/parameters/UserId" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/DeviceAuthorizationRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Hosted provider authorization URL",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/DeviceAuthorizationResponse" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/PaymentRequired" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/users/{id}/consolidation": {
      "parameters": [{ "$ref": "#/components/parameters/UserId" }],
      "get": {
        "operationId": "getUserConsolidation",
        "summary": "Retrieve a user's consolidation configuration",
        "tags": ["Consolidation"],
        "responses": {
          "200": {
            "description": "Resolved consolidation configuration",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/UserConsolidation" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/PaymentRequired" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "patch": {
        "operationId": "updateUserConsolidation",
        "summary": "Update a user's consolidation configuration",
        "description": "Atomically applies the supplied settings. A null method restores its catalog default. Historical data is reconsolidated asynchronously.",
        "tags": ["Consolidation"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/UpdateConsolidationRequest" }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Configuration accepted and historical reconsolidation requested when needed",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ConsolidationAccepted" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/PaymentRequired" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "422": { "$ref": "#/components/responses/Unprocessable" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "delete": {
        "operationId": "resetUserConsolidation",
        "summary": "Reset a user's consolidation configuration",
        "description": "Restores aggregation methods and provider inclusion to catalog defaults. Workout ordering and other user settings are unchanged.",
        "tags": ["Consolidation"],
        "responses": {
          "202": {
            "description": "Reset accepted and historical reconsolidation requested when needed",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ConsolidationAccepted" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/PaymentRequired" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/users/{id}/devices/{provider}": {
      "delete": {
        "operationId": "disconnectDeviceProvider",
        "summary": "Disconnect a device provider",
        "tags": ["Devices"],
        "parameters": [
          { "$ref": "#/components/parameters/UserId" },
          {
            "name": "provider",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "minLength": 1 }
          }
        ],
        "responses": {
          "204": { "description": "Provider disconnected" },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/PaymentRequired" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/users/{id}/daily": {
      "get": {
        "operationId": "getDailyData",
        "summary": "Get daily health data",
        "tags": ["Health data"],
        "parameters": [
          { "$ref": "#/components/parameters/UserId" },
          {
            "name": "types",
            "in": "query",
            "description": "Comma-separated daily metric IDs. Omit for all public metrics.",
            "schema": { "type": "string" }
          },
          { "$ref": "#/components/parameters/FromDate" },
          { "$ref": "#/components/parameters/ToDate" }
        ],
        "responses": {
          "200": {
            "description": "Daily values for every date in the inclusive range",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/DailyResponse" } }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/PaymentRequired" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "422": { "$ref": "#/components/responses/Unprocessable" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/users/{id}/workouts": {
      "get": {
        "operationId": "listWorkouts",
        "summary": "List workouts",
        "tags": ["Health data"],
        "parameters": [
          { "$ref": "#/components/parameters/UserId" },
          { "$ref": "#/components/parameters/FromDate" },
          { "$ref": "#/components/parameters/ToDate" },
          {
            "name": "limit",
            "in": "query",
            "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "Opaque next_cursor from the prior page.",
            "schema": { "type": "string", "minLength": 1 }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of workouts",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/WorkoutList" } }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/PaymentRequired" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "422": { "$ref": "#/components/responses/Unprocessable" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/users/{id}/workouts/{workout_id}": {
      "get": {
        "operationId": "getWorkout",
        "summary": "Retrieve a workout",
        "tags": ["Health data"],
        "parameters": [
          { "$ref": "#/components/parameters/UserId" },
          {
            "name": "workout_id",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "minLength": 1 }
          }
        ],
        "responses": {
          "200": {
            "description": "Workout detail",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/WorkoutDetail" } }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/PaymentRequired" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/users/{id}/sleep": {
      "get": {
        "operationId": "listSleepSessions",
        "summary": "List sleep sessions",
        "tags": ["Health data"],
        "parameters": [
          { "$ref": "#/components/parameters/UserId" },
          { "$ref": "#/components/parameters/FromDate" },
          { "$ref": "#/components/parameters/ToDate" },
          {
            "name": "limit",
            "in": "query",
            "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "Opaque next_cursor from the prior page.",
            "schema": { "type": "string", "minLength": 1 }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of sleep sessions",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/SleepList" } }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/PaymentRequired" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "422": { "$ref": "#/components/responses/Unprocessable" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/users/{id}/timeseries": {
      "get": {
        "operationId": "getTimeseries",
        "summary": "Read one sampled metric in buckets",
        "tags": ["Health data"],
        "parameters": [
          { "$ref": "#/components/parameters/UserId" },
          {
            "name": "metric",
            "in": "query",
            "required": true,
            "description": "A timeseries metric ID from the data catalog.",
            "schema": { "type": "string" }
          },
          { "$ref": "#/components/parameters/TimeseriesFromDate" },
          { "$ref": "#/components/parameters/ToDate" },
          {
            "name": "resolution",
            "in": "query",
            "description": "Bucket width. At most 31 days per request, or 7 days at 1m.",
            "schema": { "type": "string", "enum": ["1m", "5m", "15m", "1h"], "default": "5m" }
          }
        ],
        "responses": {
          "200": {
            "description": "Bucketed samples",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/TimeseriesResponse" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/PaymentRequired" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "422": { "$ref": "#/components/responses/Unprocessable" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/users/{id}/scores": {
      "get": {
        "operationId": "getScores",
        "summary": "Read daily scores",
        "tags": ["Health data"],
        "parameters": [
          { "$ref": "#/components/parameters/UserId" },
          {
            "name": "types",
            "in": "query",
            "description": "Comma-separated score IDs; omit for all five.",
            "schema": { "type": "string" }
          },
          { "$ref": "#/components/parameters/FromDate" },
          { "$ref": "#/components/parameters/ToDate" }
        ],
        "responses": {
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": { "$ref": "#/components/responses/PaymentRequired" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "422": { "$ref": "#/components/responses/Unprocessable" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "200": {
            "description": "Scores by date",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/ScoresResponse" } }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Sandbox or live API key created in the Sonar Developers workspace."
      },
      "SdkBearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Short-lived Mobile SDK access token."
      }
    },
    "parameters": {
      "UserId": {
        "name": "id",
        "in": "path",
        "required": true,
        "description": "Sonar user UUID.",
        "schema": { "type": "string", "format": "uuid" }
      },
      "RosterSubjectId": {
        "name": "id",
        "in": "path",
        "required": true,
        "description": "Atlas roster subject UUID returned after invitation acceptance.",
        "schema": { "type": "string", "format": "uuid" }
      },
      "RosterInvitationId": {
        "name": "id",
        "in": "path",
        "required": true,
        "description": "Opaque invitation identifier returned when the invitation is created.",
        "schema": { "type": "string", "minLength": 64, "maxLength": 64 }
      },
      "FromDate": {
        "name": "from_date",
        "in": "query",
        "description": "Inclusive start date. Defaults to 29 days before to_date.",
        "schema": { "type": "string", "format": "date" }
      },
      "TimeseriesFromDate": {
        "name": "from_date",
        "in": "query",
        "description": "Inclusive start date. Defaults to to_date, producing a one-day window.",
        "schema": { "type": "string", "format": "date" }
      },
      "ToDate": {
        "name": "to_date",
        "in": "query",
        "description": "Inclusive calendar date in the user's profile timezone. Defaults to the current date in that timezone; UTC when no timezone is set.",
        "schema": { "type": "string", "format": "date" }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Invalid path, query, JSON, or request body",
        "content": {
          "application/json": { "schema": { "$ref": "#/components/schemas/ErrorEnvelope" } }
        }
      },
      "Unauthorized": {
        "description": "Missing or invalid API key",
        "content": {
          "application/json": { "schema": { "$ref": "#/components/schemas/ErrorEnvelope" } }
        }
      },
      "Forbidden": {
        "description": "The organization is not permitted to perform this operation",
        "content": {
          "application/json": { "schema": { "$ref": "#/components/schemas/ErrorEnvelope" } }
        }
      },
      "PaymentRequired": {
        "description": "The Developers plan or required billing subscription is not active",
        "content": {
          "application/json": { "schema": { "$ref": "#/components/schemas/ErrorEnvelope" } }
        }
      },
      "NotFound": {
        "description": "Resource not found",
        "content": {
          "application/json": { "schema": { "$ref": "#/components/schemas/ErrorEnvelope" } }
        }
      },
      "Conflict": {
        "description": "Resource conflict",
        "content": {
          "application/json": { "schema": { "$ref": "#/components/schemas/ErrorEnvelope" } }
        }
      },
      "Unprocessable": {
        "description": "Semantically invalid date range, metric, provider, configuration, or cursor",
        "content": {
          "application/json": { "schema": { "$ref": "#/components/schemas/ErrorEnvelope" } }
        }
      },
      "RateLimited": {
        "description": "Rate limit exceeded",
        "headers": {
          "Retry-After": {
            "description": "Seconds to wait before retrying.",
            "schema": { "type": "integer", "minimum": 1 }
          }
        },
        "content": {
          "application/json": { "schema": { "$ref": "#/components/schemas/ErrorEnvelope" } }
        }
      }
    },
    "schemas": {
      "ErrorEnvelope": {
        "type": "object",
        "required": ["error"],
        "properties": {
          "error": {
            "type": "object",
            "required": ["code", "message"],
            "properties": { "code": { "type": "string" }, "message": { "type": "string" } }
          }
        }
      },
      "UtcInstant": {
        "type": "string",
        "format": "date-time",
        "pattern": "Z$",
        "description": "RFC 3339 UTC instant ending in Z."
      },
      "CreateSdkSessionRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": ["app_id", "installation_id"],
        "properties": {
          "app_id": { "type": "string" },
          "installation_id": { "type": "string", "format": "uuid" }
        }
      },
      "SdkBootstrap": {
        "type": "object",
        "required": ["session_id", "client_token", "expires_at"],
        "properties": {
          "session_id": { "type": "string", "format": "uuid" },
          "client_token": { "type": "string" },
          "expires_at": { "$ref": "#/components/schemas/UtcInstant" }
        }
      },
      "SdkSession": {
        "type": "object",
        "required": [
          "id",
          "app_id",
          "installation_id",
          "platform",
          "providers",
          "status",
          "created_at",
          "activated_at",
          "last_refreshed_at",
          "expires_at"
        ],
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "app_id": { "type": "string" },
          "installation_id": { "type": "string", "format": "uuid" },
          "platform": { "type": "string", "enum": ["ios", "android"] },
          "providers": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": ["apple_health", "health_connect", "samsung_health"]
            }
          },
          "status": { "type": "string", "enum": ["pending", "active"] },
          "created_at": { "$ref": "#/components/schemas/UtcInstant" },
          "activated_at": {
            "oneOf": [{ "$ref": "#/components/schemas/UtcInstant" }, { "type": "null" }]
          },
          "last_refreshed_at": {
            "oneOf": [{ "$ref": "#/components/schemas/UtcInstant" }, { "type": "null" }]
          },
          "expires_at": { "$ref": "#/components/schemas/UtcInstant" }
        }
      },
      "SdkSessionList": {
        "type": "object",
        "required": ["sessions"],
        "properties": {
          "sessions": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/SdkSession" }
          }
        }
      },
      "SdkRefreshRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": ["refresh_token", "request_id"],
        "properties": {
          "refresh_token": { "type": "string", "writeOnly": true },
          "request_id": { "type": "string", "format": "uuid" }
        }
      },
      "SdkCredentialResponse": {
        "type": "object",
        "required": [
          "session_id",
          "access_token",
          "access_expires_at",
          "refresh_token",
          "refresh_expires_at",
          "session_expires_at"
        ],
        "properties": {
          "session_id": { "type": "string", "format": "uuid" },
          "access_token": { "type": "string" },
          "access_expires_at": { "$ref": "#/components/schemas/UtcInstant" },
          "refresh_token": { "type": "string" },
          "refresh_expires_at": { "$ref": "#/components/schemas/UtcInstant" },
          "session_expires_at": { "$ref": "#/components/schemas/UtcInstant" }
        }
      },
      "User": {
        "type": "object",
        "required": ["id", "external_ref", "display_name", "created_at"],
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "external_ref": { "type": "string" },
          "display_name": { "type": "string" },
          "created_at": { "$ref": "#/components/schemas/UtcInstant" }
        }
      },
      "RosterInvitationRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": ["email", "full_name"],
        "properties": {
          "email": { "type": "string", "format": "email" },
          "full_name": { "type": "string", "minLength": 1, "maxLength": 120 }
        }
      },
      "RosterInvitation": {
        "type": "object",
        "required": ["id", "email", "full_name", "status", "expires_at", "accept_url"],
        "properties": {
          "id": { "type": "string", "minLength": 64, "maxLength": 64 },
          "email": { "type": "string", "format": "email" },
          "full_name": { "type": "string" },
          "status": { "type": "string", "const": "pending" },
          "expires_at": { "$ref": "#/components/schemas/UtcInstant" },
          "accept_url": { "type": "string", "format": "uri" }
        }
      },
      "RosterInvitationStatus": {
        "type": "object",
        "required": ["id", "status", "subject_id"],
        "properties": {
          "id": { "type": "string", "minLength": 64, "maxLength": 64 },
          "status": {
            "type": "string",
            "enum": ["pending", "accepted", "revoked", "expired"]
          },
          "subject_id": { "type": ["string", "null"], "format": "uuid" }
        }
      },
      "RosterStatusPatch": {
        "type": "object",
        "additionalProperties": false,
        "required": ["status"],
        "properties": {
          "status": { "type": "string", "enum": ["active", "archived"] }
        }
      },
      "RosterMember": {
        "type": "object",
        "required": [
          "id",
          "display_name",
          "email",
          "source",
          "status",
          "created_at",
          "archived_at"
        ],
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "display_name": { "type": ["string", "null"] },
          "email": { "type": ["string", "null"], "format": "email" },
          "source": { "type": "string", "const": "b2c" },
          "status": { "type": "string", "enum": ["active", "archived"] },
          "created_at": { "$ref": "#/components/schemas/UtcInstant" },
          "archived_at": {
            "oneOf": [{ "$ref": "#/components/schemas/UtcInstant" }, { "type": "null" }]
          }
        }
      },
      "UserConnection": {
        "type": "object",
        "required": ["provider", "status", "connected_at", "last_sync_at"],
        "properties": {
          "provider": { "type": "string" },
          "status": {
            "type": "string",
            "enum": ["connected", "stale"],
            "description": "`stale`: an SDK connection (Apple Health, Health Connect) that has sent nothing for 14 days."
          },
          "connected_at": { "$ref": "#/components/schemas/UtcInstant" },
          "last_sync_at": {
            "oneOf": [{ "$ref": "#/components/schemas/UtcInstant" }, { "type": "null" }]
          }
        }
      },
      "UserDetails": {
        "type": "object",
        "required": ["id", "external_ref", "display_name", "created_at", "connections"],
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "external_ref": { "type": "string" },
          "display_name": { "type": "string" },
          "created_at": { "$ref": "#/components/schemas/UtcInstant" },
          "connections": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/UserConnection" }
          }
        }
      },
      "UserProfile": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "date_of_birth": { "type": ["string", "null"], "format": "date" },
          "birth_sex": { "type": ["string", "null"], "enum": ["Male", "Female", null] },
          "timezone": {
            "type": ["string", "null"],
            "description": "IANA timezone name.",
            "maxLength": 64
          }
        }
      },
      "CreateUserRequest": {
        "type": "object",
        "required": ["external_ref"],
        "additionalProperties": false,
        "properties": {
          "external_ref": { "type": "string", "minLength": 1 },
          "display_name": { "type": "string", "minLength": 1, "maxLength": 120 },
          "profile": { "$ref": "#/components/schemas/UserProfile" }
        }
      },
      "UpdateUserRequest": {
        "type": "object",
        "minProperties": 1,
        "additionalProperties": false,
        "properties": {
          "display_name": { "type": "string", "minLength": 1, "maxLength": 120 },
          "profile": { "$ref": "#/components/schemas/UserProfile" }
        }
      },
      "UserList": {
        "type": "object",
        "required": ["users", "next_cursor"],
        "properties": {
          "users": { "type": "array", "items": { "$ref": "#/components/schemas/User" } },
          "next_cursor": { "type": ["string", "null"] }
        }
      },
      "DeletionAccepted": {
        "type": "object",
        "required": ["id", "status"],
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "status": { "type": "string", "const": "deleting" }
        }
      },
      "DeviceAuthorizationRequest": {
        "type": "object",
        "required": ["provider", "redirect_url"],
        "additionalProperties": false,
        "properties": {
          "provider": { "type": "string", "minLength": 1 },
          "redirect_url": {
            "type": "string",
            "format": "uri",
            "description": "HTTPS URL whose origin is registered in Atlas."
          }
        }
      },
      "DeviceAuthorizationResponse": {
        "type": "object",
        "required": ["auth_url"],
        "properties": { "auth_url": { "type": "string", "format": "uri" } }
      },
      "Provider": {
        "type": "object",
        "required": ["slug", "name", "thumbnail_url"],
        "properties": {
          "slug": {
            "type": "string",
            "description": "Exact provider identifier accepted by device connection endpoints."
          },
          "name": { "type": "string" },
          "thumbnail_url": { "type": ["string", "null"], "format": "uri" }
        }
      },
      "ProviderCatalog": {
        "type": "object",
        "required": ["providers"],
        "properties": {
          "providers": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/Provider" }
          }
        }
      },
      "ConsolidationMethod": {
        "type": "string",
        "enum": ["avg", "max", "sum"]
      },
      "ConsolidationCatalogMetric": {
        "type": "object",
        "required": [
          "key",
          "display_name",
          "category",
          "kind",
          "default_method",
          "allowed_methods"
        ],
        "properties": {
          "key": { "type": "string" },
          "display_name": { "type": "string" },
          "category": { "type": "string" },
          "kind": { "type": "string", "enum": ["metric", "group"] },
          "default_method": { "$ref": "#/components/schemas/ConsolidationMethod" },
          "allowed_methods": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/ConsolidationMethod" }
          }
        }
      },
      "ConsolidationCatalog": {
        "type": "object",
        "required": ["category_order", "metrics"],
        "properties": {
          "category_order": { "type": "array", "items": { "type": "string" } },
          "metrics": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/ConsolidationCatalogMetric" }
          }
        }
      },
      "ConsolidationProvider": {
        "type": "object",
        "required": ["provider", "enabled"],
        "properties": {
          "provider": { "type": "string" },
          "enabled": { "type": "boolean" }
        }
      },
      "UserConsolidationMetric": {
        "type": "object",
        "required": [
          "key",
          "category",
          "default_method",
          "method",
          "overridden",
          "providers"
        ],
        "properties": {
          "key": { "type": "string" },
          "category": { "type": "string" },
          "default_method": { "$ref": "#/components/schemas/ConsolidationMethod" },
          "method": { "$ref": "#/components/schemas/ConsolidationMethod" },
          "overridden": { "type": "boolean" },
          "providers": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/ConsolidationProvider" }
          }
        }
      },
      "UserConsolidation": {
        "type": "object",
        "required": ["providers", "metrics"],
        "properties": {
          "providers": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/ConsolidationProvider" }
          },
          "metrics": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/UserConsolidationMetric" }
          }
        }
      },
      "MetricConsolidationPatch": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "method": {
            "oneOf": [
              { "$ref": "#/components/schemas/ConsolidationMethod" },
              { "type": "null" }
            ]
          },
          "providers": {
            "type": "object",
            "minProperties": 1,
            "additionalProperties": { "type": "boolean" }
          }
        },
        "anyOf": [{ "required": ["method"] }, { "required": ["providers"] }]
      },
      "UpdateConsolidationRequest": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "metrics": {
            "type": "object",
            "minProperties": 1,
            "additionalProperties": { "$ref": "#/components/schemas/MetricConsolidationPatch" }
          },
          "providers": {
            "type": "object",
            "minProperties": 1,
            "additionalProperties": { "type": "boolean" }
          }
        },
        "anyOf": [{ "required": ["metrics"] }, { "required": ["providers"] }]
      },
      "ConsolidationAccepted": {
        "type": "object",
        "required": ["status", "configuration"],
        "properties": {
          "status": { "type": "string", "enum": ["reconsolidating", "unchanged"] },
          "configuration": { "$ref": "#/components/schemas/UserConsolidation" }
        }
      },
      "DailyResponse": {
        "type": "object",
        "required": ["from_date", "to_date", "dates", "series"],
        "properties": {
          "from_date": {
            "type": "string",
            "format": "date",
            "description": "Inclusive calendar date in the user's profile timezone."
          },
          "to_date": {
            "type": "string",
            "format": "date",
            "description": "Inclusive calendar date in the user's profile timezone."
          },
          "dates": {
            "type": "array",
            "description": "Calendar-day axis in the user's profile timezone.",
            "items": { "type": "string", "format": "date" }
          },
          "series": { "$ref": "#/components/schemas/DailySeries" }
        }
      },
      "WorkoutSummary": {
        "type": "object",
        "required": [
          "id",
          "type",
          "start_time",
          "duration_minutes",
          "calories",
          "distance_km",
          "source",
          "avg_heart_rate",
          "max_heart_rate",
          "strain"
        ],
        "properties": {
          "id": { "type": "string" },
          "type": { "type": "string" },
          "start_time": {
            "type": "string",
            "description": "User-local wall time with no zone suffix."
          },
          "duration_minutes": { "type": "number" },
          "calories": { "type": ["number", "null"] },
          "distance_km": { "type": ["number", "null"] },
          "source": { "type": ["string", "null"] },
          "avg_heart_rate": { "type": ["number", "null"] },
          "max_heart_rate": { "type": ["number", "null"] },
          "strain": { "type": ["number", "null"] }
        }
      },
      "WorkoutList": {
        "type": "object",
        "required": ["from_date", "to_date", "data", "next_cursor"],
        "properties": {
          "from_date": { "type": "string", "format": "date" },
          "to_date": { "type": "string", "format": "date" },
          "data": { "type": "array", "items": { "$ref": "#/components/schemas/WorkoutSummary" } },
          "next_cursor": { "type": ["string", "null"] }
        }
      },
      "WorkoutMetrics": {
        "type": "object",
        "required": [
          "elevation_meters",
          "steps",
          "avg_speed_kmh",
          "avg_pace_seconds_per_km",
          "avg_mets",
          "weather_temperature_c",
          "weather_humidity_pct",
          "swimming_stroke_count",
          "swimming_lap_length_m"
        ],
        "properties": {
          "elevation_meters": { "type": ["number", "null"] },
          "steps": { "type": ["number", "null"] },
          "avg_speed_kmh": { "type": ["number", "null"] },
          "avg_pace_seconds_per_km": { "type": ["number", "null"] },
          "avg_mets": { "type": ["number", "null"] },
          "weather_temperature_c": { "type": ["number", "null"] },
          "weather_humidity_pct": { "type": ["number", "null"] },
          "swimming_stroke_count": { "type": ["number", "null"] },
          "swimming_lap_length_m": { "type": ["number", "null"] }
        }
      },
      "HeartRateZone": {
        "type": "object",
        "required": ["zone", "total_seconds_on_zone", "percentage", "zone_ranges"],
        "properties": {
          "zone": { "type": "string" },
          "total_seconds_on_zone": { "type": "number" },
          "percentage": { "type": "number" },
          "zone_ranges": {
            "type": ["object", "null"],
            "additionalProperties": { "type": "number" }
          }
        }
      },
      "WorkoutHeartRate": {
        "type": "object",
        "required": ["avg_bpm", "max_bpm", "zones", "samples"],
        "properties": {
          "avg_bpm": { "type": ["number", "null"] },
          "max_bpm": { "type": ["number", "null"] },
          "zones": { "type": "array", "items": { "$ref": "#/components/schemas/HeartRateZone" } },
          "samples": {
            "type": "array",
            "description": "Heart-rate trace averaged into 15, 30, or 60 second buckets; empty without a trace.",
            "items": { "$ref": "#/components/schemas/HeartRateSample" }
          }
        }
      },
      "WorkoutDetail": {
        "allOf": [
          { "$ref": "#/components/schemas/WorkoutSummary" },
          {
            "type": "object",
            "required": ["name", "metrics", "heart_rate"],
            "properties": {
              "name": { "type": ["string", "null"] },
              "metrics": { "$ref": "#/components/schemas/WorkoutMetrics" },
              "heart_rate": {
                "oneOf": [{ "$ref": "#/components/schemas/WorkoutHeartRate" }, { "type": "null" }]
              }
            }
          }
        ]
      },
      "HeartRateSample": {
        "type": "object",
        "required": ["timestamp", "bpm"],
        "properties": {
          "timestamp": { "type": "string", "description": "User wall clock, no zone suffix." },
          "bpm": { "type": "integer" }
        }
      },
      "SleepSession": {
        "type": "object",
        "required": [
          "id",
          "date",
          "start_time",
          "end_time",
          "duration_minutes",
          "is_main_sleep",
          "source",
          "asleep_minutes",
          "deep_minutes",
          "light_minutes",
          "rem_minutes",
          "awake_minutes",
          "in_bed_minutes",
          "efficiency_pct"
        ],
        "properties": {
          "id": { "type": "string", "description": "Opaque, stable across reads." },
          "date": {
            "type": "string",
            "format": "date",
            "description": "The day the session counts toward."
          },
          "start_time": { "type": "string", "description": "User wall clock, no zone suffix." },
          "end_time": {
            "type": "string",
            "description": "User-local wall time with no zone suffix."
          },
          "duration_minutes": { "type": "number" },
          "is_main_sleep": { "type": "boolean" },
          "source": { "type": "string" },
          "asleep_minutes": { "type": ["number", "null"] },
          "deep_minutes": { "type": ["number", "null"] },
          "light_minutes": { "type": ["number", "null"] },
          "rem_minutes": { "type": ["number", "null"] },
          "awake_minutes": { "type": ["number", "null"] },
          "in_bed_minutes": { "type": ["number", "null"] },
          "efficiency_pct": { "type": ["number", "null"] }
        }
      },
      "SleepList": {
        "type": "object",
        "required": ["from_date", "to_date", "data", "next_cursor"],
        "properties": {
          "from_date": { "type": "string", "format": "date" },
          "to_date": { "type": "string", "format": "date" },
          "data": { "type": "array", "items": { "$ref": "#/components/schemas/SleepSession" } },
          "next_cursor": { "type": ["string", "null"] }
        }
      },
      "TimeseriesResponse": {
        "type": "object",
        "required": [
          "metric",
          "resolution",
          "from_date",
          "to_date",
          "start",
          "step_seconds",
          "values"
        ],
        "properties": {
          "metric": { "type": "string" },
          "resolution": { "type": "string", "enum": ["1m", "5m", "15m", "1h"] },
          "from_date": { "type": "string", "format": "date" },
          "to_date": { "type": "string", "format": "date" },
          "start": {
            "type": "string",
            "description": "Window start in the user's wall clock with no zone suffix; bucket i begins at start + i * step_seconds. The grid has a fixed number of buckets per calendar day: skipped DST buckets are null and repeated-hour samples share the same buckets."
          },
          "step_seconds": { "type": "integer" },
          "values": {
            "type": "array",
            "description": "One slot per bucket across the whole window; empty buckets are null.",
            "items": { "type": ["number", "null"] }
          }
        }
      },
      "DailySeries": {
        "type": "object",
        "description": "One array per requested metric, each the same length as `dates`; missing days are null.",
        "additionalProperties": { "type": "array", "items": { "type": ["number", "null"] } }
      },
      "ScoreLatest": {
        "type": "object",
        "required": ["date", "value", "previous_value"],
        "properties": {
          "date": { "type": "string", "format": "date" },
          "value": { "type": "number" },
          "previous_value": { "type": ["number", "null"] }
        }
      },
      "ScoresResponse": {
        "type": "object",
        "required": ["from_date", "to_date", "dates", "series", "latest"],
        "properties": {
          "from_date": { "type": "string", "format": "date" },
          "to_date": { "type": "string", "format": "date" },
          "dates": { "type": "array", "items": { "type": "string", "format": "date" } },
          "series": { "$ref": "#/components/schemas/DailySeries" },
          "latest": {
            "type": "object",
            "description": "Per requested score: the most recent scored day in the range, or null.",
            "additionalProperties": {
              "oneOf": [{ "$ref": "#/components/schemas/ScoreLatest" }, { "type": "null" }]
            }
          }
        }
      }
    }
  }
}
