{
  "info": {
    "_postman_id": "aifitnessapi-strava",
    "name": "Strava (aifitnessapi.com)",
    "description": "Strava: OAuth 2.0 and Webhook samples requests built from the vendor documentation aifitnessapi.com quotes. Generated by scripts/build-collections.mjs; no secrets included. https://aifitnessapi.com/collections",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "item": [
    {
      "name": "OAuth 2.0",
      "description": "Strava's authorization-code flow as its documentation describes it, read 2026-11-05. Fill client_id, redirect_uri and scope in an environment of your own and keep client_secret there, never in a shared collection.\n\nThe same facts, with each source sentence, at https://aifitnessapi.com/integrate/strava-api and https://aifitnessapi.com/tools/oauth-playground.",
      "item": [
        {
          "name": "1. Authorization URL (open in a browser)",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "https://www.strava.com/oauth/authorize?response_type=code&client_id={{client_id}}&redirect_uri={{redirect_uri}}&scope={{scope}}&state={{state}}&approval_prompt=auto",
              "protocol": "https",
              "host": [
                "www",
                "strava",
                "com"
              ],
              "path": [
                "oauth",
                "authorize"
              ],
              "query": [
                {
                  "key": "response_type",
                  "value": "code"
                },
                {
                  "key": "client_id",
                  "value": "{{client_id}}"
                },
                {
                  "key": "redirect_uri",
                  "value": "{{redirect_uri}}"
                },
                {
                  "key": "scope",
                  "value": "{{scope}}"
                },
                {
                  "key": "state",
                  "value": "{{state}}"
                },
                {
                  "key": "approval_prompt",
                  "value": "auto"
                }
              ]
            },
            "description": "https://www.strava.com/oauth/authorize. Authorization URL for web apps. Open this URL in a browser (in Postman: copy it from the request bar); the user signs in and Strava redirects to {{redirect_uri}} with ?code=… Put that value in the auth_code variable.\n\nSource: Strava Developers, “Authentication”, https://developers.strava.com/docs/authentication/\n\nScope: Required. Comma- or space-delimited; this tool uses commas. The athlete can untick any requested scope, so check the scope the redirect returns. Source: Strava Developers, “Authentication”, https://developers.strava.com/docs/authentication/\n\nDocumented scopes (joined with commas):\n- read: Public segments, public routes, public profile data, public posts, public events, club feeds, and leaderboards\n- read_all: Private routes, private segments, and private events for the user\n- profile:read_all: All profile information, even if the user set profile visibility to Followers or Only You\n- profile:write: Update the user's weight and Functional Threshold Power (FTP), and star or unstar segments\n- activity:read: Activities visible to Everyone and Followers, excluding privacy zone data; required for activity webhooks\n- activity:read_all: As activity:read, plus privacy zone data and Only You activities\n- activity:write: Create manual activities and uploads, and edit activities visible to the app\n\nPKCE: Not mentioned on Strava's Authentication page.\n\nAlso documented: https://www.strava.com/oauth/mobile/authorize. Mobile apps (Android intent or iOS) use the mobile authorize endpoint; the Strava app opens if installed. Source: Strava Developers, “Authentication”, https://developers.strava.com/docs/authentication/"
          },
          "response": []
        },
        {
          "name": "2. Exchange the code for tokens",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/x-www-form-urlencoded",
                "type": "text"
              }
            ],
            "url": {
              "raw": "https://www.strava.com/oauth/token",
              "protocol": "https",
              "host": [
                "www",
                "strava",
                "com"
              ],
              "path": [
                "oauth",
                "token"
              ]
            },
            "description": "https://www.strava.com/oauth/token. Token URL, with the client ID and secret, for both the code exchange and refresh. (Strava's own curl samples post to https://www.strava.com/api/v3/oauth/token.)\n\nSource: Strava Developers, “Authentication”, https://developers.strava.com/docs/authentication/\n\nClient credentials go in the form body.\n\nToken lifetime: Six hours from creation. Source: Strava Developers, “Authentication”, https://developers.strava.com/docs/authentication/\n\nNote: The authorization code is short-lived and single-use. Source: Strava Developers, “Authentication”, https://developers.strava.com/docs/authentication/\n\nNote: approval_prompt is auto by default; force always shows the prompt. Source: Strava Developers, “Authentication”, https://developers.strava.com/docs/authentication/\n\nNote: localhost and 127.0.0.1 are allowed as redirect hosts. Source: Strava Developers, “Authentication”, https://developers.strava.com/docs/authentication/\n\nNote: Deauthorize with POST https://www.strava.com/oauth/revoke (HTTP Basic, the token in the body), the only supported endpoint from June 1, 2027. Source: Strava Developers, “Authentication”, https://developers.strava.com/docs/authentication/",
            "body": {
              "mode": "urlencoded",
              "urlencoded": [
                {
                  "key": "grant_type",
                  "value": "authorization_code",
                  "type": "text"
                },
                {
                  "key": "code",
                  "value": "{{auth_code}}",
                  "type": "text"
                },
                {
                  "key": "redirect_uri",
                  "value": "{{redirect_uri}}",
                  "type": "text"
                },
                {
                  "key": "client_id",
                  "value": "{{client_id}}",
                  "type": "text"
                },
                {
                  "key": "client_secret",
                  "value": "{{client_secret}}",
                  "type": "text"
                }
              ]
            }
          },
          "response": []
        },
        {
          "name": "3. Refresh the access token",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/x-www-form-urlencoded",
                "type": "text"
              }
            ],
            "url": {
              "raw": "https://www.strava.com/oauth/token",
              "protocol": "https",
              "host": [
                "www",
                "strava",
                "com"
              ],
              "path": [
                "oauth",
                "token"
              ]
            },
            "description": "Refresh: Refresh with grant_type=refresh_token. If the current access token expires in more than an hour, the same one comes back; once a new refresh token is returned the old one stops working.\n\nSource: Strava Developers, “Authentication”, https://developers.strava.com/docs/authentication/",
            "body": {
              "mode": "urlencoded",
              "urlencoded": [
                {
                  "key": "grant_type",
                  "value": "refresh_token",
                  "type": "text"
                },
                {
                  "key": "refresh_token",
                  "value": "{{refresh_token}}",
                  "type": "text"
                },
                {
                  "key": "client_id",
                  "value": "{{client_id}}",
                  "type": "text"
                },
                {
                  "key": "client_secret",
                  "value": "{{client_secret}}",
                  "type": "text"
                }
              ]
            }
          },
          "response": []
        }
      ]
    },
    {
      "name": "Webhook samples",
      "description": "Strava's documented example notifications, sent to {{local_url}} (your local handler) unchanged. Signature: No signature is documented for event POSTs. Subscription validation is a GET with hub.mode, hub.challenge and hub.verify_token; echo hub.challenge as JSON. Source: Strava Developers, “Webhook Events API”, https://developers.strava.com/docs/webhooks/\n\nHeaders that carry a signature hold the placeholder Strava prints, so a handler that verifies signatures will reject these: to send correctly signed requests, use https://aifitnessapi.com/webhooks/send-sample.mjs. Respond: Acknowledge each POST with 200 OK within two seconds; do further work asynchronously.\n\nPayload library with JSON Schemas: https://aifitnessapi.com/webhooks#strava.",
      "item": [
        {
          "name": "Activity update",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{local_url}}",
              "host": [
                "{{local_url}}"
              ]
            },
            "description": "Sent when an activity is created or deleted, when its title, type or privacy changes, and when an athlete revokes access (updates then holds \"authorized\": \"false\").\n\nStrava's example event (Example Request). Source: Strava Developers, “Webhook Events API”, https://developers.strava.com/docs/webhooks/",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"aspect_type\": \"update\",\n  \"event_time\": 1516126040,\n  \"object_id\": 1360128428,\n  \"object_type\": \"activity\",\n  \"owner_id\": 134815,\n  \"subscription_id\": 120475,\n  \"updates\": {\n    \"title\": \"Messy\"\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        }
      ]
    }
  ],
  "variable": [
    {
      "key": "client_id",
      "value": "",
      "type": "string",
      "description": "Your app's client ID, from the vendor's developer console."
    },
    {
      "key": "client_secret",
      "value": "",
      "type": "string",
      "description": "Keep it in a Postman or Bruno environment marked secret. This collection ships it empty."
    },
    {
      "key": "redirect_uri",
      "value": "",
      "type": "string",
      "description": "The redirect URI registered with the vendor."
    },
    {
      "key": "scope",
      "value": "",
      "type": "string",
      "description": "Scopes to request, joined as the vendor documents (see the authorization request)."
    },
    {
      "key": "state",
      "value": "",
      "type": "string",
      "description": "A random value you check on the redirect."
    },
    {
      "key": "auth_code",
      "value": "",
      "type": "string",
      "description": "The ?code= value from the redirect."
    },
    {
      "key": "refresh_token",
      "value": "",
      "type": "string",
      "description": "The refresh_token from the token response."
    },
    {
      "key": "local_url",
      "value": "http://localhost:3000/webhooks/strava",
      "type": "string",
      "description": "Where your webhook handler listens."
    }
  ]
}
