{
  "schemaVersion": "1.0",
  "item": {
    "slug": "whoop-central",
    "name": "WHOOP Central",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/4xiomdev/whoop-central",
    "canonicalUrl": "https://clawhub.ai/4xiomdev/whoop-central",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/whoop-central",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=whoop-central",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "SKILL.md",
      "credentials.example.json",
      "package.json",
      "src/auth.js",
      "src/import-historical.js",
      "src/recovery.js"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-05-07T17:22:31.273Z",
      "expiresAt": "2026-05-14T17:22:31.273Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=afrexai-annual-report",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=afrexai-annual-report",
        "contentDisposition": "attachment; filename=\"afrexai-annual-report-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/whoop-central"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/whoop-central",
    "agentPageUrl": "https://openagent3.xyz/skills/whoop-central/agent",
    "manifestUrl": "https://openagent3.xyz/skills/whoop-central/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/whoop-central/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "WHOOP Central",
        "body": "Access sleep, recovery, strain, and workout data from WHOOP via the v2 API."
      },
      {
        "title": "Quick Commands",
        "body": "# 1) One-time setup (writes ~/.clawdbot/whoop/credentials.json)\nnode src/setup.js\n\n# 2) Recommended: Get tokens via Postman (see Auth section), then verify\nnode src/verify.js\nnode src/verify.js --refresh\n\n# Prompt-friendly snapshot (includes last workout)\nnode src/today.js\n\n# Daily summary (all metrics)\nnode src/summary.js\n\n# Individual metrics\nnode src/recovery.js\nnode src/sleep.js\nnode src/strain.js\nnode src/workouts.js\n\n# Bulk import to ~/clawd/health/logs/whoop/*\nnode src/import-historical.js"
      },
      {
        "title": "Data Available",
        "body": "MetricData PointsRecoveryScore (0-100%), HRV, resting HR, SpO2, skin tempSleepDuration, stages (REM/deep/light), efficiency, performanceStrainDaily strain (0-21), calories, avg/max HRWorkoutsActivity type, duration, strain, calories, HR"
      },
      {
        "title": "Recovery Score Guide",
        "body": "💚 67-100% Green - Ready to perform\n💛 34-66% Yellow - Moderate readiness\n❤️ 0-33% Red - Focus on recovery"
      },
      {
        "title": "0. Requirements",
        "body": "Node.js 18+ (this repo uses ESM)\nopenssl (only needed for the optional auth.js flow when using https://localhost; Postman auth does not need it)"
      },
      {
        "title": "1. Create WHOOP Developer App",
        "body": "Go to https://developer.whoop.com/\nSign in with your WHOOP account\nCreate a new App\nAdd these Redirect URIs (exact match; no extra trailing slashes):\n\nPostman browser callback (recommended auth path):\nhttps://oauth.pstmn.io/v1/browser-callback\n\n\nOptional local callback (only used by auth.js):\nhttps://localhost:3000/callback\n\n\n\nYou can keep both registered at the same time.\nCopy the Client ID and Client Secret\n\nTeam note: this skill does not ship any client credentials. Each user can create their own WHOOP app,\nor (if you trust each other) a team can share one app's client_id/client_secret and let multiple WHOOP\naccounts authorize it."
      },
      {
        "title": "2. Save Credentials (recommended: interactive)",
        "body": "Run:\n\nnode src/setup.js\n\nThis writes ~/.clawdbot/whoop/credentials.json (and optionally token.json if you paste tokens)."
      },
      {
        "title": "3. Authenticate (Recommended: Postman)",
        "body": "Postman is the most reliable bootstrap for many accounts because WHOOP may block browser-like traffic\nto the OAuth endpoints (or behave differently depending on headers).\n\nPostman checklist (don’t skip these):\n\nWHOOP dashboard Redirect URIs include:\n\nhttps://oauth.pstmn.io/v1/browser-callback\n\n\nPostman OAuth settings:\n\nScopes include offline (or you won’t get a refresh_token)\nClient Authentication is Send client credentials in body (client_secret_post)\n\nIn WHOOP dashboard, ensure you registered the Postman callback Redirect URI:\n\nhttps://oauth.pstmn.io/v1/browser-callback\n\nIn Postman:\n\nCreate an Environment and set variables:\n\nClientId = your WHOOP client id\nClientSecret = your WHOOP client secret\n\n\nOpen the WHOOP API collection (or any request), then open the Authorization tab:\n\nType: OAuth 2.0\nAdd auth data to: Request Headers\nGrant Type: Authorization Code\nCallback URL: check Authorize using browser\nAuth URL:\nhttps://api.prod.whoop.com/oauth/oauth2/auth\n\n\nAccess Token URL:\nhttps://api.prod.whoop.com/oauth/oauth2/token\n\n\nClient ID: {{ClientId}}\nClient Secret: {{ClientSecret}}\nScope (space-delimited): include offline plus any read scopes you need, e.g.:\noffline read:profile read:sleep read:recovery read:workout read:cycles read:body_measurement\n\n\nState: any 8+ chars (e.g. loomingState)\nClient Authentication: Send client credentials in body\n\nClick \"Get New Access Token\", sign in to WHOOP, and click \"Grant\".\n\n\nIn Postman’s \"Manage Access Tokens\" modal:\n\nClick \"Use Token\" (so requests work)\nIMPORTANT: copy and save both:\n\naccess_token\nrefresh_token\nPostman often does not retain the refresh token for you later.\n\nSave tokens to ~/.clawdbot/whoop/token.json:\n\nUse token.example.json as a template\nSet:\n\nobtained_at to current time in milliseconds\nredirect_uri to:\nhttps://oauth.pstmn.io/v1/browser-callback\n\nVerify (and test refresh):\n\nnode src/verify.js\nnode src/verify.js --refresh"
      },
      {
        "title": "4. Optional: Authenticate via auth.js (may fail on some accounts)",
        "body": "If you prefer a fully local OAuth loop (and WHOOP allows it), you can use auth.js.\n\nPre-req: add this redirect URI in WHOOP dashboard:\n\nhttps://localhost:3000/callback\n\nRun:\n\nWHOOP_REDIRECT_URI='https://localhost:3000/callback' node src/auth.js\n\nIf you need to do it from a phone/remote device:\n\nWHOOP_REDIRECT_URI='https://localhost:3000/callback' node src/auth.js --manual\n\nNote: for localhost HTTPS, the script generates a self-signed cert and your browser will show a TLS warning.\nYou must proceed past the warning so the redirect can complete."
      },
      {
        "title": "4. Verify It Works",
        "body": "node src/verify.js\nnode src/summary.js"
      },
      {
        "title": "Browser shows NotAuthorizedException before the login page",
        "body": "This is a WHOOP-side block on browser User-Agents hitting api.prod.whoop.com OAuth endpoints.\n\nUse the updated node src/auth.js which bootstraps the login URL and sends your browser directly to id.whoop.com.\nIf you still see it, try node src/auth.js --manual and open the printed URL."
      },
      {
        "title": "\"redirect_uri not whitelisted\"",
        "body": "Go to https://developer.whoop.com/\nEdit your app\nEnsure this EXACT URI is in Redirect URIs:\nhttps://oauth.pstmn.io/v1/browser-callback\n\nIf you're using auth.js locally, also add:\nhttps://localhost:3000/callback\n\n\nSave and try again"
      },
      {
        "title": "Token Expired",
        "body": "Tokens auto-refresh on demand (no cron needed). If issues persist:\n\nrm ~/.clawdbot/whoop/token.json\nnode src/auth.js"
      },
      {
        "title": "\"Authorization was not valid\"",
        "body": "This usually means your access token is stale/invalidated (common if you re-auth or refresh tokens elsewhere; WHOOP refresh tokens rotate).\n\nRe-run node src/auth.js, or\nCopy the latest access_token + refresh_token from Postman into ~/.clawdbot/whoop/token.json and update obtained_at."
      },
      {
        "title": "Auth from Phone/Remote Device",
        "body": "Use manual mode:\n\nnode src/auth.js --manual\n\nOpen the URL on any device, authorize, then copy the code from the callback URL."
      },
      {
        "title": "error=request_forbidden / \"The request is not allowed\"",
        "body": "This is WHOOP rejecting the authorization request after login/consent. Common causes:\n\nRedirect URI policy (WHOOP docs only mention https:// or whoop:// redirect URIs)\nApp/account restrictions (membership/approval/test-user restrictions)\nScope restrictions (try requesting fewer scopes)\n\nIf you suspect redirect URI policy, use an HTTPS tunnel:\n\n# 1) Get a public HTTPS URL that forwards to localhost:3000 (example)\nngrok http 3000\n\n# 2) Add the ngrok HTTPS URL + /callback to WHOOP dashboard Redirect URIs, then run:\nWHOOP_REDIRECT_URI=https://YOUR-NGROK-DOMAIN.ngrok-free.app/callback node src/auth.js\n\nIf you suspect scope restrictions, try a minimal scope set:\n\nWHOOP_SCOPES=\"read:profile\" node src/auth.js"
      },
      {
        "title": "If your WHOOP Redirect URL is https://localhost:3000/callback",
        "body": "This changes how the local callback server must run: it must be HTTPS (not HTTP).\n\nThe script supports this. Run:\n\nWHOOP_REDIRECT_URI=https://localhost:3000/callback node src/auth.js\n\nIt will generate a self-signed cert locally and your browser will likely show a warning for https://localhost.\nProceed past the warning so the redirect can complete."
      },
      {
        "title": "JSON Output (for tooling)",
        "body": "These commands support:\n\n--json (single JSON blob)\n--jsonl (one JSON object per line; useful for piping)\n--limit N (where supported)\nTime filters (where supported): --days N, --since 7d / 12h, --start ISO, --end ISO\n\nnode src/summary.js --json\nnode src/recovery.js --json --limit 1\nnode src/sleep.js --json --limit 1\nnode src/strain.js --json --limit 1\nnode src/workouts.js --json --limit 1\n\n# Examples with filters\nnode src/sleep.js --json --days 7\nnode src/workouts.js --jsonl --since 30d\nnode src/recovery.js --json --start 2026-01-01T00:00:00Z --end 2026-02-01T00:00:00Z"
      },
      {
        "title": "API Notes",
        "body": "Uses WHOOP Developer API v2\nOAuth 2.0 authentication with refresh tokens\nScopes: offline, read:recovery, read:sleep, read:workout, read:cycles, read:profile\nToken auto-refreshes when expired"
      }
    ],
    "body": "WHOOP Central\n\nAccess sleep, recovery, strain, and workout data from WHOOP via the v2 API.\n\nQuick Commands\n# 1) One-time setup (writes ~/.clawdbot/whoop/credentials.json)\nnode src/setup.js\n\n# 2) Recommended: Get tokens via Postman (see Auth section), then verify\nnode src/verify.js\nnode src/verify.js --refresh\n\n# Prompt-friendly snapshot (includes last workout)\nnode src/today.js\n\n# Daily summary (all metrics)\nnode src/summary.js\n\n# Individual metrics\nnode src/recovery.js\nnode src/sleep.js\nnode src/strain.js\nnode src/workouts.js\n\n# Bulk import to ~/clawd/health/logs/whoop/*\nnode src/import-historical.js\n\nData Available\nMetric\tData Points\nRecovery\tScore (0-100%), HRV, resting HR, SpO2, skin temp\nSleep\tDuration, stages (REM/deep/light), efficiency, performance\nStrain\tDaily strain (0-21), calories, avg/max HR\nWorkouts\tActivity type, duration, strain, calories, HR\nRecovery Score Guide\n💚 67-100% Green - Ready to perform\n💛 34-66% Yellow - Moderate readiness\n❤️ 0-33% Red - Focus on recovery\nSetup\n0. Requirements\nNode.js 18+ (this repo uses ESM)\nopenssl (only needed for the optional auth.js flow when using https://localhost; Postman auth does not need it)\n1. Create WHOOP Developer App\nGo to https://developer.whoop.com/\nSign in with your WHOOP account\nCreate a new App\nAdd these Redirect URIs (exact match; no extra trailing slashes):\nPostman browser callback (recommended auth path):\nhttps://oauth.pstmn.io/v1/browser-callback\n\nOptional local callback (only used by auth.js):\nhttps://localhost:3000/callback\n\nYou can keep both registered at the same time.\nCopy the Client ID and Client Secret\n\nTeam note: this skill does not ship any client credentials. Each user can create their own WHOOP app, or (if you trust each other) a team can share one app's client_id/client_secret and let multiple WHOOP accounts authorize it.\n\n2. Save Credentials (recommended: interactive)\n\nRun:\n\nnode src/setup.js\n\n\nThis writes ~/.clawdbot/whoop/credentials.json (and optionally token.json if you paste tokens).\n\n3. Authenticate (Recommended: Postman)\n\nPostman is the most reliable bootstrap for many accounts because WHOOP may block browser-like traffic to the OAuth endpoints (or behave differently depending on headers).\n\nPostman checklist (don’t skip these):\n\nWHOOP dashboard Redirect URIs include:\nhttps://oauth.pstmn.io/v1/browser-callback\nPostman OAuth settings:\nScopes include offline (or you won’t get a refresh_token)\nClient Authentication is Send client credentials in body (client_secret_post)\nIn WHOOP dashboard, ensure you registered the Postman callback Redirect URI:\nhttps://oauth.pstmn.io/v1/browser-callback\n\nIn Postman:\nCreate an Environment and set variables:\nClientId = your WHOOP client id\nClientSecret = your WHOOP client secret\nOpen the WHOOP API collection (or any request), then open the Authorization tab:\nType: OAuth 2.0\nAdd auth data to: Request Headers\nGrant Type: Authorization Code\nCallback URL: check Authorize using browser\nAuth URL:\nhttps://api.prod.whoop.com/oauth/oauth2/auth\n\nAccess Token URL:\nhttps://api.prod.whoop.com/oauth/oauth2/token\n\nClient ID: {{ClientId}}\nClient Secret: {{ClientSecret}}\nScope (space-delimited): include offline plus any read scopes you need, e.g.:\noffline read:profile read:sleep read:recovery read:workout read:cycles read:body_measurement\n\nState: any 8+ chars (e.g. loomingState)\nClient Authentication: Send client credentials in body\n\nClick \"Get New Access Token\", sign in to WHOOP, and click \"Grant\".\n\nIn Postman’s \"Manage Access Tokens\" modal:\n\nClick \"Use Token\" (so requests work)\nIMPORTANT: copy and save both:\naccess_token\nrefresh_token Postman often does not retain the refresh token for you later.\nSave tokens to ~/.clawdbot/whoop/token.json:\nUse token.example.json as a template\nSet:\nobtained_at to current time in milliseconds\nredirect_uri to:\nhttps://oauth.pstmn.io/v1/browser-callback\n\nVerify (and test refresh):\nnode src/verify.js\nnode src/verify.js --refresh\n\n4. Optional: Authenticate via auth.js (may fail on some accounts)\n\nIf you prefer a fully local OAuth loop (and WHOOP allows it), you can use auth.js.\n\nPre-req: add this redirect URI in WHOOP dashboard:\n\nhttps://localhost:3000/callback\n\n\nRun:\n\nWHOOP_REDIRECT_URI='https://localhost:3000/callback' node src/auth.js\n\n\nIf you need to do it from a phone/remote device:\n\nWHOOP_REDIRECT_URI='https://localhost:3000/callback' node src/auth.js --manual\n\n\nNote: for localhost HTTPS, the script generates a self-signed cert and your browser will show a TLS warning. You must proceed past the warning so the redirect can complete.\n\n4. Verify It Works\nnode src/verify.js\nnode src/summary.js\n\nTroubleshooting\nBrowser shows NotAuthorizedException before the login page\n\nThis is a WHOOP-side block on browser User-Agents hitting api.prod.whoop.com OAuth endpoints.\n\nUse the updated node src/auth.js which bootstraps the login URL and sends your browser directly to id.whoop.com.\nIf you still see it, try node src/auth.js --manual and open the printed URL.\n\"redirect_uri not whitelisted\"\nGo to https://developer.whoop.com/\nEdit your app\nEnsure this EXACT URI is in Redirect URIs:\nhttps://oauth.pstmn.io/v1/browser-callback\n\nIf you're using auth.js locally, also add:\nhttps://localhost:3000/callback\n\nSave and try again\nToken Expired\n\nTokens auto-refresh on demand (no cron needed). If issues persist:\n\nrm ~/.clawdbot/whoop/token.json\nnode src/auth.js\n\n\"Authorization was not valid\"\n\nThis usually means your access token is stale/invalidated (common if you re-auth or refresh tokens elsewhere; WHOOP refresh tokens rotate).\n\nRe-run node src/auth.js, or\nCopy the latest access_token + refresh_token from Postman into ~/.clawdbot/whoop/token.json and update obtained_at.\nAuth from Phone/Remote Device\n\nUse manual mode:\n\nnode src/auth.js --manual\n\n\nOpen the URL on any device, authorize, then copy the code from the callback URL.\n\nerror=request_forbidden / \"The request is not allowed\"\n\nThis is WHOOP rejecting the authorization request after login/consent. Common causes:\n\nRedirect URI policy (WHOOP docs only mention https:// or whoop:// redirect URIs)\nApp/account restrictions (membership/approval/test-user restrictions)\nScope restrictions (try requesting fewer scopes)\n\nIf you suspect redirect URI policy, use an HTTPS tunnel:\n\n# 1) Get a public HTTPS URL that forwards to localhost:3000 (example)\nngrok http 3000\n\n# 2) Add the ngrok HTTPS URL + /callback to WHOOP dashboard Redirect URIs, then run:\nWHOOP_REDIRECT_URI=https://YOUR-NGROK-DOMAIN.ngrok-free.app/callback node src/auth.js\n\n\nIf you suspect scope restrictions, try a minimal scope set:\n\nWHOOP_SCOPES=\"read:profile\" node src/auth.js\n\nIf your WHOOP Redirect URL is https://localhost:3000/callback\n\nThis changes how the local callback server must run: it must be HTTPS (not HTTP).\n\nThe script supports this. Run:\n\nWHOOP_REDIRECT_URI=https://localhost:3000/callback node src/auth.js\n\n\nIt will generate a self-signed cert locally and your browser will likely show a warning for https://localhost. Proceed past the warning so the redirect can complete.\n\nJSON Output (for tooling)\n\nThese commands support:\n\n--json (single JSON blob)\n--jsonl (one JSON object per line; useful for piping)\n--limit N (where supported)\nTime filters (where supported): --days N, --since 7d / 12h, --start ISO, --end ISO\nnode src/summary.js --json\nnode src/recovery.js --json --limit 1\nnode src/sleep.js --json --limit 1\nnode src/strain.js --json --limit 1\nnode src/workouts.js --json --limit 1\n\n# Examples with filters\nnode src/sleep.js --json --days 7\nnode src/workouts.js --jsonl --since 30d\nnode src/recovery.js --json --start 2026-01-01T00:00:00Z --end 2026-02-01T00:00:00Z\n\nAPI Notes\nUses WHOOP Developer API v2\nOAuth 2.0 authentication with refresh tokens\nScopes: offline, read:recovery, read:sleep, read:workout, read:cycles, read:profile\nToken auto-refreshes when expired"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/4xiomdev/whoop-central",
    "publisherUrl": "https://clawhub.ai/4xiomdev/whoop-central",
    "owner": "4xiomdev",
    "version": "1.0.2",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/whoop-central",
    "downloadUrl": "https://openagent3.xyz/downloads/whoop-central",
    "agentUrl": "https://openagent3.xyz/skills/whoop-central/agent",
    "manifestUrl": "https://openagent3.xyz/skills/whoop-central/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/whoop-central/agent.md"
  }
}