{
  "openapi": "3.1.0",
  "info": {
    "title": "Walk15 Connect V1 \u2014 partner backend API",
    "version": "1.0.0",
    "description": "Backend HTTP endpoints of Walk15 Connect V1 for approved customers. The browser authorization step (GET /oauth/authorize \u2192 Walk15 sign-in and consent \u2192 redirect to your callback) is an interactive flow documented in the human-readable guides and intentionally not modelled as an operation here. Generated from the Connect V1 source on 2026-10-10; synthetic examples only."
  },
  "servers": [
    {
      "url": "https://api.walk15.lt",
      "description": "Production issuer."
    }
  ],
  "tags": [
    {
      "name": "OAuth"
    },
    {
      "name": "Activity"
    },
    {
      "name": "Connections"
    }
  ],
  "paths": {
    "/.well-known/oauth-authorization-server": {
      "get": {
        "tags": [
          "OAuth"
        ],
        "operationId": "getAuthorizationServerMetadata",
        "summary": "Authorization server metadata (RFC 8414)",
        "security": [],
        "responses": {
          "200": {
            "description": "Metadata.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthorizationServerMetadata"
                }
              }
            }
          }
        }
      }
    },
    "/oauth/token": {
      "post": {
        "tags": [
          "OAuth"
        ],
        "operationId": "requestToken",
        "summary": "Exchange an authorization code or refresh tokens",
        "security": [
          {
            "clientBasic": []
          }
        ],
        "description": "Form body only (max 8 KB, no query string, no duplicate or unknown fields). Refresh tokens are single use; presenting a used refresh token revokes the credential family.",
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/AuthorizationCodeGrant"
                  },
                  {
                    "$ref": "#/components/schemas/RefreshTokenGrant"
                  }
                ],
                "discriminator": {
                  "propertyName": "grant_type",
                  "mapping": {
                    "authorization_code": "#/components/schemas/AuthorizationCodeGrant",
                    "refresh_token": "#/components/schemas/RefreshTokenGrant"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tokens.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TokenResponse"
                },
                "example": {
                  "grant_id": "22222222-2222-4222-8222-222222222222",
                  "history_from": "2026-10-10",
                  "connection_version": "1",
                  "access_token": "w15a_<access-token>",
                  "token_type": "Bearer",
                  "expires_in": 300,
                  "refresh_token": "w15r2_<refresh-token>",
                  "scope": "daily_steps:read cycling_daily:read"
                }
              }
            }
          },
          "400": {
            "description": "invalid_request, invalid_grant or unsupported_grant_type.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/OAuthError"
                    },
                    {
                      "properties": {
                        "error": {
                          "enum": [
                            "invalid_request",
                            "invalid_grant",
                            "unsupported_grant_type"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Client authentication failed.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWWAuthenticateBasic"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/OAuthError"
                    },
                    {
                      "properties": {
                        "error": {
                          "enum": [
                            "invalid_client"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/OAuthError"
                    },
                    {
                      "properties": {
                        "error": {
                          "enum": [
                            "server_error"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/oauth/revoke": {
      "post": {
        "tags": [
          "OAuth"
        ],
        "operationId": "revokeToken",
        "summary": "Revoke an access or refresh token (RFC 7009)",
        "security": [
          {
            "clientBasic": []
          }
        ],
        "description": "Always 200 with an empty body for unknown, foreign or already-revoked tokens. Revoking a refresh token revokes every token of the connection version; the consent relationship remains.",
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/RevocationRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Revoked (or nothing to revoke). Empty body.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              }
            }
          },
          "400": {
            "description": "invalid_request or unsupported_token_type.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/OAuthError"
                    },
                    {
                      "properties": {
                        "error": {
                          "enum": [
                            "invalid_request",
                            "unsupported_token_type"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Client authentication failed.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWWAuthenticateBasic"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/OAuthError"
                    },
                    {
                      "properties": {
                        "error": {
                          "enum": [
                            "invalid_client"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/OAuthError"
                    },
                    {
                      "properties": {
                        "error": {
                          "enum": [
                            "server_error"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/connect-walk15/v1/grants/{grant_id}/daily-activity": {
      "get": {
        "tags": [
          "Activity"
        ],
        "operationId": "getDailySteps",
        "summary": "Adjusted Walk15 daily step totals",
        "security": [
          {
            "accessToken": [
              "daily_steps:read"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/GrantId"
          },
          {
            "$ref": "#/components/parameters/From"
          },
          {
            "$ref": "#/components/parameters/To"
          }
        ],
        "responses": {
          "200": {
            "description": "Authorized snapshot.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DailyStepsResponse"
                },
                "example": {
                  "data": [
                    {
                      "date": "2026-10-10",
                      "steps": 8412,
                      "updated_at": null
                    }
                  ],
                  "meta": {
                    "from": "2026-10-10",
                    "to": "2026-10-12",
                    "date_basis": "walk15_recorded_date",
                    "source": "walk15",
                    "snapshot_at": "2026-10-12T18:04:11.920Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (invalid_request, invalid_date_range).",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": {
                    "code": "invalid_date_range",
                    "message": "The date range is invalid."
                  },
                  "request_id": "44444444-4444-4444-8444-444444444444"
                }
              }
            }
          },
          "401": {
            "description": "Unusable access token (invalid_access_token).",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              },
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWWAuthenticateBearer"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": {
                    "code": "invalid_access_token",
                    "message": "Access authentication failed."
                  },
                  "request_id": "44444444-4444-4444-8444-444444444444"
                }
              }
            }
          },
          "403": {
            "description": "Missing scope (insufficient_scope).",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              },
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWWAuthenticateBearer"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": {
                    "code": "insufficient_scope",
                    "message": "The required scope is not permitted."
                  },
                  "request_id": "44444444-4444-4444-8444-444444444444"
                }
              }
            }
          },
          "404": {
            "description": "grant_id does not match the access token (not_found).",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": {
                    "code": "not_found",
                    "message": "The resource was not found."
                  },
                  "request_id": "44444444-4444-4444-8444-444444444444"
                }
              }
            }
          },
          "429": {
            "description": "Rate or concurrency budget exhausted (rate_limited).",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": {
                    "code": "rate_limited",
                    "message": "The request limit was reached."
                  },
                  "request_id": "44444444-4444-4444-8444-444444444444"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily unavailable (data_unavailable).",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": {
                    "code": "data_unavailable",
                    "message": "The data is temporarily unavailable."
                  },
                  "request_id": "44444444-4444-4444-8444-444444444444"
                }
              }
            }
          }
        }
      }
    },
    "/connect-walk15/v1/grants/{grant_id}/cycling-daily": {
      "get": {
        "tags": [
          "Activity"
        ],
        "operationId": "getDailyCycling",
        "summary": "Daily cycling distance in metres",
        "security": [
          {
            "accessToken": [
              "cycling_daily:read"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/GrantId"
          },
          {
            "$ref": "#/components/parameters/From"
          },
          {
            "$ref": "#/components/parameters/To"
          }
        ],
        "responses": {
          "200": {
            "description": "Authorized snapshot.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CyclingDailyResponse"
                },
                "example": {
                  "data": [
                    {
                      "date": "2026-10-11",
                      "distance_meters": 18240,
                      "source": "walk15",
                      "updated_at": null
                    }
                  ],
                  "meta": {
                    "from": "2026-10-10",
                    "to": "2026-10-16",
                    "date_basis": "walk15_recorded_date",
                    "snapshot_at": "2026-10-16T08:30:00.000Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (invalid_request, invalid_date_range).",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": {
                    "code": "invalid_date_range",
                    "message": "The date range is invalid."
                  },
                  "request_id": "44444444-4444-4444-8444-444444444444"
                }
              }
            }
          },
          "401": {
            "description": "Unusable access token (invalid_access_token).",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              },
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWWAuthenticateBearer"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": {
                    "code": "invalid_access_token",
                    "message": "Access authentication failed."
                  },
                  "request_id": "44444444-4444-4444-8444-444444444444"
                }
              }
            }
          },
          "403": {
            "description": "Missing scope (insufficient_scope).",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              },
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWWAuthenticateBearer"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": {
                    "code": "insufficient_scope",
                    "message": "The required scope is not permitted."
                  },
                  "request_id": "44444444-4444-4444-8444-444444444444"
                }
              }
            }
          },
          "404": {
            "description": "grant_id does not match the access token (not_found).",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": {
                    "code": "not_found",
                    "message": "The resource was not found."
                  },
                  "request_id": "44444444-4444-4444-8444-444444444444"
                }
              }
            }
          },
          "429": {
            "description": "Rate or concurrency budget exhausted (rate_limited).",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": {
                    "code": "rate_limited",
                    "message": "The request limit was reached."
                  },
                  "request_id": "44444444-4444-4444-8444-444444444444"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily unavailable (data_unavailable).",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": {
                    "code": "data_unavailable",
                    "message": "The data is temporarily unavailable."
                  },
                  "request_id": "44444444-4444-4444-8444-444444444444"
                }
              }
            }
          }
        }
      }
    },
    "/connect-walk15/v1/grants/{grant_id}/cycling-activities": {
      "get": {
        "tags": [
          "Activity"
        ],
        "operationId": "listCyclingActivities",
        "summary": "Individual cycling activities (cursor pagination)",
        "security": [
          {
            "accessToken": [
              "cycling_activities:read"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/GrantId"
          },
          {
            "$ref": "#/components/parameters/From"
          },
          {
            "$ref": "#/components/parameters/To"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "Authorized snapshot.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CyclingActivitiesResponse"
                },
                "example": {
                  "data": [
                    {
                      "id": "ca_Q2xKw9mN3pR7sT1vX5yZ8aB4cD6eF0gH2iJ4kL6mN8o",
                      "date": "2026-10-11",
                      "distance_meters": 18240,
                      "recorded_start_time": "2026-10-11T07:42:10.000000",
                      "recorded_end_time": "2026-10-11T08:31:55.000000",
                      "timezone": null,
                      "manual": null,
                      "granularity": "unknown",
                      "source": "walk15",
                      "updated_at": null
                    }
                  ],
                  "meta": {
                    "from": "2026-10-10",
                    "to": "2026-10-16",
                    "date_basis": "walk15_recorded_date",
                    "time_basis": "walk15_recorded_clock",
                    "snapshot_at": "2026-10-16T08:30:00.000Z",
                    "next_cursor": null
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (invalid_request, invalid_date_range, invalid_cursor).",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": {
                    "code": "invalid_date_range",
                    "message": "The date range is invalid."
                  },
                  "request_id": "44444444-4444-4444-8444-444444444444"
                }
              }
            }
          },
          "401": {
            "description": "Unusable access token (invalid_access_token).",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              },
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWWAuthenticateBearer"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": {
                    "code": "invalid_access_token",
                    "message": "Access authentication failed."
                  },
                  "request_id": "44444444-4444-4444-8444-444444444444"
                }
              }
            }
          },
          "403": {
            "description": "Missing scope (insufficient_scope).",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              },
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWWAuthenticateBearer"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": {
                    "code": "insufficient_scope",
                    "message": "The required scope is not permitted."
                  },
                  "request_id": "44444444-4444-4444-8444-444444444444"
                }
              }
            }
          },
          "404": {
            "description": "grant_id does not match the access token (not_found).",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": {
                    "code": "not_found",
                    "message": "The resource was not found."
                  },
                  "request_id": "44444444-4444-4444-8444-444444444444"
                }
              }
            }
          },
          "429": {
            "description": "Rate or concurrency budget exhausted (rate_limited).",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": {
                    "code": "rate_limited",
                    "message": "The request limit was reached."
                  },
                  "request_id": "44444444-4444-4444-8444-444444444444"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily unavailable (data_unavailable).",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                },
                "example": {
                  "error": {
                    "code": "data_unavailable",
                    "message": "The data is temporarily unavailable."
                  },
                  "request_id": "44444444-4444-4444-8444-444444444444"
                }
              }
            }
          }
        }
      }
    },
    "/connect-walk15/v1/customer/grants/{grant_id}": {
      "delete": {
        "tags": [
          "Connections"
        ],
        "operationId": "disconnectGrant",
        "summary": "Disconnect a user's connection",
        "security": [
          {
            "clientBasic": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/GrantId"
          }
        ],
        "description": "No query string and no body. Returns 204 for owned, already-revoked, unknown and other customers' grants alike.",
        "responses": {
          "204": {
            "description": "Disconnected (idempotent). No body.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              }
            }
          },
          "400": {
            "description": "Invalid grant ID, query string or body present.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/OAuthError"
                    },
                    {
                      "properties": {
                        "error": {
                          "enum": [
                            "invalid_request"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Client authentication failed.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              },
              "WWW-Authenticate": {
                "$ref": "#/components/headers/WWWAuthenticateBasic"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/OAuthError"
                    },
                    {
                      "properties": {
                        "error": {
                          "enum": [
                            "invalid_client"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "500": {
            "description": "Server error.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/CacheControl"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/OAuthError"
                    },
                    {
                      "properties": {
                        "error": {
                          "enum": [
                            "server_error"
                          ]
                        }
                      }
                    }
                  ]
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "clientBasic": {
        "type": "http",
        "scheme": "basic",
        "description": "base64(urlencode(client_id) ':' urlencode(client_secret)). Exactly one Authorization header; credentials in body or query are rejected."
      },
      "accessToken": {
        "type": "http",
        "scheme": "bearer",
        "description": "Opaque access token (at most 300 seconds) from POST /oauth/token. Scopes listed per operation are Connect scopes held by the connection."
      }
    },
    "parameters": {
      "GrantId": {
        "name": "grant_id",
        "in": "path",
        "required": true,
        "description": "grant_id from the token response, exactly as returned (lowercase). Any other value returns 404.",
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      },
      "From": {
        "name": "from",
        "in": "query",
        "required": true,
        "description": "First calendar date, inclusive. Not before history_from (and, for steps, the user's Walk15 registration day).",
        "schema": {
          "type": "string",
          "format": "date",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
        }
      },
      "To": {
        "name": "to",
        "in": "query",
        "required": true,
        "description": "Last calendar date, inclusive. At most 30 days after from (31 dates) and not later than tomorrow in UTC.",
        "schema": {
          "type": "string",
          "format": "date",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
        }
      },
      "Limit": {
        "name": "limit",
        "in": "query",
        "required": false,
        "description": "Page size, plain decimal without leading zeros.",
        "schema": {
          "type": "string",
          "pattern": "^([1-9][0-9]?|[1-4][0-9]{2}|500)$",
          "default": "100",
          "description": "1\u2013500"
        }
      },
      "Cursor": {
        "name": "cursor",
        "in": "query",
        "required": false,
        "description": "meta.next_cursor from the previous page; requires the same from, to and limit. Expires 15 minutes after the first page.",
        "schema": {
          "type": "string",
          "maxLength": 4096
        }
      }
    },
    "headers": {
      "CacheControl": {
        "description": "Always no-store.",
        "schema": {
          "type": "string",
          "const": "no-store"
        }
      },
      "XRequestId": {
        "description": "Server-generated correlation ID.",
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      },
      "RateLimitLimit": {
        "description": "Configured requests per minute for your client.",
        "schema": {
          "type": "integer"
        }
      },
      "RateLimitRemaining": {
        "description": "Whole requests left in the burst budget.",
        "schema": {
          "type": "integer"
        }
      },
      "RateLimitReset": {
        "description": "Seconds until the next request becomes available (minimum 1).",
        "schema": {
          "type": "integer",
          "minimum": 1
        }
      },
      "RetryAfter": {
        "description": "Seconds to wait before retrying (minimum 1).",
        "schema": {
          "type": "integer",
          "minimum": 1
        }
      },
      "WWWAuthenticateBearer": {
        "description": "Bearer realm=\"walk15-connect\" with error=\"invalid_token\" or error=\"insufficient_scope\".",
        "schema": {
          "type": "string"
        }
      },
      "WWWAuthenticateBasic": {
        "description": "Basic realm=\"walk15-connect\".",
        "schema": {
          "type": "string"
        }
      }
    },
    "schemas": {
      "OAuthError": {
        "type": "object",
        "required": [
          "error",
          "error_description"
        ],
        "additionalProperties": false,
        "properties": {
          "error": {
            "type": "string",
            "enum": [
              "invalid_request",
              "invalid_client",
              "invalid_grant",
              "unauthorized_client",
              "unsupported_token_type",
              "unsupported_grant_type",
              "unsupported_response_type",
              "invalid_scope",
              "access_denied",
              "server_error",
              "temporarily_unavailable"
            ]
          },
          "error_description": {
            "type": "string",
            "description": "Fixed text per error code."
          }
        }
      },
      "ApiError": {
        "type": "object",
        "required": [
          "error",
          "request_id"
        ],
        "additionalProperties": false,
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "additionalProperties": false,
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "invalid_request",
                  "invalid_date_range",
                  "invalid_cursor",
                  "invalid_access_token",
                  "insufficient_scope",
                  "not_found",
                  "rate_limited",
                  "data_unavailable"
                ]
              },
              "message": {
                "type": "string",
                "description": "Fixed text per error code."
              }
            }
          },
          "request_id": {
            "type": "string",
            "format": "uuid"
          }
        }
      },
      "AuthorizationServerMetadata": {
        "type": "object",
        "required": [
          "issuer",
          "authorization_endpoint",
          "token_endpoint",
          "revocation_endpoint",
          "token_endpoint_auth_methods_supported",
          "revocation_endpoint_auth_methods_supported",
          "code_challenge_methods_supported",
          "scopes_supported",
          "response_types_supported",
          "grant_types_supported"
        ],
        "properties": {
          "issuer": {
            "type": "string",
            "format": "uri"
          },
          "authorization_endpoint": {
            "type": "string",
            "format": "uri"
          },
          "token_endpoint": {
            "type": "string",
            "format": "uri"
          },
          "revocation_endpoint": {
            "type": "string",
            "format": "uri"
          },
          "token_endpoint_auth_methods_supported": {
            "type": "array",
            "items": {
              "const": "client_secret_basic"
            }
          },
          "revocation_endpoint_auth_methods_supported": {
            "type": "array",
            "items": {
              "const": "client_secret_basic"
            }
          },
          "code_challenge_methods_supported": {
            "type": "array",
            "items": {
              "const": "S256"
            }
          },
          "scopes_supported": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Scope"
            }
          },
          "response_types_supported": {
            "type": "array",
            "items": {
              "const": "code"
            }
          },
          "grant_types_supported": {
            "type": "array",
            "items": {
              "enum": [
                "authorization_code",
                "refresh_token"
              ]
            }
          }
        }
      },
      "Scope": {
        "type": "string",
        "enum": [
          "daily_steps:read",
          "cycling_daily:read",
          "cycling_activities:read"
        ]
      },
      "AuthorizationCodeGrant": {
        "type": "object",
        "required": [
          "grant_type",
          "code",
          "redirect_uri",
          "code_verifier"
        ],
        "additionalProperties": false,
        "properties": {
          "grant_type": {
            "const": "authorization_code"
          },
          "code": {
            "type": "string",
            "maxLength": 2048
          },
          "redirect_uri": {
            "type": "string",
            "maxLength": 2048,
            "description": "The exact registered callback."
          },
          "code_verifier": {
            "type": "string",
            "pattern": "^[A-Za-z0-9._~-]{43,128}$"
          }
        }
      },
      "RefreshTokenGrant": {
        "type": "object",
        "required": [
          "grant_type",
          "refresh_token"
        ],
        "additionalProperties": false,
        "properties": {
          "grant_type": {
            "const": "refresh_token"
          },
          "refresh_token": {
            "type": "string",
            "maxLength": 2048
          }
        }
      },
      "RevocationRequest": {
        "type": "object",
        "required": [
          "token"
        ],
        "additionalProperties": false,
        "properties": {
          "token": {
            "type": "string",
            "maxLength": 2048
          },
          "token_type_hint": {
            "enum": [
              "access_token",
              "refresh_token"
            ]
          }
        }
      },
      "TokenResponse": {
        "type": "object",
        "required": [
          "grant_id",
          "history_from",
          "connection_version",
          "access_token",
          "token_type",
          "expires_in",
          "refresh_token",
          "scope"
        ],
        "additionalProperties": false,
        "properties": {
          "grant_id": {
            "type": "string",
            "format": "uuid",
            "description": "Pairwise connection ID; stable across refreshes and reconnects."
          },
          "history_from": {
            "type": "string",
            "format": "date",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Earliest accessible date (authorization calendar day). Unchanged by refresh."
          },
          "connection_version": {
            "type": "string",
            "pattern": "^[1-9][0-9]{0,18}$",
            "description": "Decimal connection generation."
          },
          "access_token": {
            "type": "string"
          },
          "token_type": {
            "const": "Bearer"
          },
          "expires_in": {
            "type": "integer",
            "minimum": 1,
            "maximum": 300
          },
          "refresh_token": {
            "type": "string",
            "description": "Single-use, rotating."
          },
          "scope": {
            "type": "string",
            "description": "Space-separated approved scopes."
          }
        }
      },
      "DailyStepsResponse": {
        "type": "object",
        "required": [
          "data",
          "meta"
        ],
        "additionalProperties": false,
        "properties": {
          "data": {
            "type": "array",
            "maxItems": 31,
            "items": {
              "type": "object",
              "required": [
                "date",
                "steps",
                "updated_at"
              ],
              "additionalProperties": false,
              "properties": {
                "date": {
                  "type": "string",
                  "format": "date",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "steps": {
                  "type": "integer",
                  "minimum": 0
                },
                "updated_at": {
                  "type": "null"
                }
              }
            }
          },
          "meta": {
            "type": "object",
            "required": [
              "from",
              "to",
              "date_basis",
              "source",
              "snapshot_at"
            ],
            "additionalProperties": false,
            "properties": {
              "from": {
                "type": "string",
                "format": "date",
                "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
              },
              "to": {
                "type": "string",
                "format": "date",
                "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
              },
              "date_basis": {
                "const": "walk15_recorded_date"
              },
              "source": {
                "const": "walk15"
              },
              "snapshot_at": {
                "type": "string",
                "format": "date-time",
                "description": "UTC instant with millisecond precision and Z suffix."
              }
            }
          }
        }
      },
      "CyclingDailyResponse": {
        "type": "object",
        "required": [
          "data",
          "meta"
        ],
        "additionalProperties": false,
        "properties": {
          "data": {
            "type": "array",
            "maxItems": 31,
            "items": {
              "type": "object",
              "required": [
                "date",
                "distance_meters",
                "source",
                "updated_at"
              ],
              "additionalProperties": false,
              "properties": {
                "date": {
                  "type": "string",
                  "format": "date",
                  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
                },
                "distance_meters": {
                  "type": "integer",
                  "minimum": 0,
                  "description": "Metres."
                },
                "source": {
                  "const": "walk15"
                },
                "updated_at": {
                  "type": "null"
                }
              }
            }
          },
          "meta": {
            "$ref": "#/components/schemas/DailyMeta"
          }
        }
      },
      "DailyMeta": {
        "type": "object",
        "required": [
          "from",
          "to",
          "date_basis",
          "snapshot_at"
        ],
        "additionalProperties": false,
        "properties": {
          "from": {
            "type": "string",
            "format": "date",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "to": {
            "type": "string",
            "format": "date",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "date_basis": {
            "const": "walk15_recorded_date"
          },
          "snapshot_at": {
            "type": "string",
            "format": "date-time",
            "description": "UTC instant with millisecond precision and Z suffix."
          }
        }
      },
      "CyclingActivity": {
        "type": "object",
        "required": [
          "id",
          "date",
          "distance_meters",
          "recorded_start_time",
          "recorded_end_time",
          "timezone",
          "manual",
          "granularity",
          "source",
          "updated_at"
        ],
        "additionalProperties": false,
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^ca_[A-Za-z0-9_-]{43}$"
          },
          "date": {
            "type": "string",
            "format": "date",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "distance_meters": {
            "type": "integer",
            "minimum": 0,
            "description": "Metres."
          },
          "recorded_start_time": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{6}$",
            "description": "Unzoned recorded clock. Not UTC; never append Z."
          },
          "recorded_end_time": {
            "oneOf": [
              {
                "type": "string",
                "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{6}$",
                "description": "Unzoned recorded clock. Not UTC; never append Z."
              },
              {
                "type": "null"
              }
            ]
          },
          "timezone": {
            "type": "null"
          },
          "manual": {
            "type": "null"
          },
          "granularity": {
            "const": "unknown"
          },
          "source": {
            "const": "walk15"
          },
          "updated_at": {
            "type": "null"
          }
        }
      },
      "CyclingActivitiesResponse": {
        "type": "object",
        "required": [
          "data",
          "meta"
        ],
        "additionalProperties": false,
        "properties": {
          "data": {
            "type": "array",
            "maxItems": 500,
            "items": {
              "$ref": "#/components/schemas/CyclingActivity"
            }
          },
          "meta": {
            "type": "object",
            "required": [
              "from",
              "to",
              "date_basis",
              "time_basis",
              "snapshot_at",
              "next_cursor"
            ],
            "additionalProperties": false,
            "properties": {
              "from": {
                "type": "string",
                "format": "date",
                "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
              },
              "to": {
                "type": "string",
                "format": "date",
                "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
              },
              "date_basis": {
                "const": "walk15_recorded_date"
              },
              "time_basis": {
                "const": "walk15_recorded_clock"
              },
              "snapshot_at": {
                "type": "string",
                "format": "date-time",
                "description": "UTC instant with millisecond precision and Z suffix."
              },
              "next_cursor": {
                "oneOf": [
                  {
                    "type": "string",
                    "minLength": 1
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            }
          }
        }
      }
    }
  }
}
