WeFitter

WeFitter is a health and fitness data platform ("one API to access wearable data, gamification and AI") operated by Thunderbyte.AI in Groningen, Netherlands. Its REST API aggregates health and activity data from 300+ wearables and fitness apps — Fitbit, Garmin, Google Fit, Apple Health, Withings, Polar, Oura, Whoop, Samsung Health, Huawei and more — into a single unified, deduplicated data model, and layers gamification (challenges, leaderboards, teams, points) and AI insights (biological age, recommendations) on top. Organizations use it to build corporate wellbeing, digital fitness, e-health and insurance solutions. WeFitter also ships mobile SDK bridges for Apple Health, Samsung Health and Android Health Connect.

WeFitter publishes 9 APIs on the APIs.io network, including app API, challenge API, connection API, and 6 more. Tagged areas include Company, Health, Fitness, Wearables, and Health Data.

The WeFitter catalog on APIs.io includes 1 event-driven AsyncAPI specification.

WeFitter’s developer surface includes documentation, getting-started guide, API reference, support, engineering blog, changelog, signup flow, and 24 more developer resources.

51.1/100 developing ▬ flat Agent 71/100 agent native Full breakdown ↓
scored 2026-07-27 · rubric v0.5
AccessSelf serve
9 APIs 1 MCP Servers
CompanyHealthFitnessWearablesHealth DataWellbeingGamificationDigital HealthInsuranceActivity Tracking

Kin Score

Kin Score Kin Score How this is scored →
scored 2026-07-27 · rubric v0.5
Composite quality — 51.1/100 · developing
Contract Quality 15.1 / 25
Developer Ergonomics 14.8 / 20
Commercial Clarity 6.8 / 20
Operational Transparency 3.8 / 13
Governance 0.0 / 12
Discoverability 10.0 / 10
Agent readiness — 71/100 · agent native
Machine-Readable Contract 18 / 18
Agentic Access Contract 15 / 15
MCP Server 12 / 12
Machine-Readable Auth 10 / 10
Idempotency 0 / 9
Stable Error Semantics 8 / 8
Request/Response Examples 0 / 7
Rate-Limit Signaling 0 / 7
Typed Event Surface 6 / 6
Agent Skills 5 / 5
Well-Known Catalog 0 / 4
Consent & Bot Identity 0 / 3
Improve this rating by publishing the missing artifacts — every area above can be raised, and the full rubric is at apis.io/rating/. This rating is computed from github.com/api-evangelist/wefitter: open an issue to ask a question, or submit a pull request to add artifacts. Want it done for you? Prioritized profiling — $2,500 →

APIs 9

Individual APIs this provider publishes, each with its own machine-readable definition.

WeFitter app API

The app API from WeFitter — 1 operation(s) for app.

WeFitter challenge API

WeFitter API’s challenge engine will bring endless engagement to your platform. For more information about the possibilities in challenges please go to https://www.wefitter.com/...

WeFitter connection API

Connections are the links between profiles and their wearables.

WeFitter insights API

The insights API from WeFitter — 1 operation(s) for insights.

WeFitter loyalty API

The loyalty API from WeFitter — 2 operation(s) for loyalty.

WeFitter notification API

Send a notification to all devices for the specified profiles The data will be sent to the client in the following format: ``` { "app": , "title": , "body"...</p> </div> <div class="item-card"> <h4><a href="https://apis.io/apis/wefitter/wefitter-profile-api/">WeFitter profile API</a></h4><p>Profiles are containers for wearables data. The profiles can be seen as an extension of users in a different system. Profiles are anonymous objects which can participate in team...</p> </div> <div class="item-card"> <h4><a href="https://apis.io/apis/wefitter/wefitter-team-api/">WeFitter team API</a></h4><p>The team API from WeFitter — 5 operation(s) for team.</p> </div> <div class="item-card"> <h4><a href="https://apis.io/apis/wefitter/wefitter-token-api/">WeFitter token API</a></h4><p><p> Before any calls can be made to wefitter, BasicAuth is needed to verify the identity of the requesting party. This call will result into a Bearer token which has administrat...</p> </div> </div><p class="scroll-hint">Scroll for all 9</p> <!-- Postman Collections --> <!-- Open Collections (open + Bruno formats) --> <!-- Arazzo Workflows --> <!-- MCP Servers --> <h2 class="section-anchor" id="mcp-servers"><a href="#mcp-servers">MCP Servers</a> <span class="section-count">1</span></h2><p class="section-blurb">Model Context Protocol servers that expose these APIs to AI agents.</p> <div class="card-grid scroll-pane"> <div class="item-card" style="border-left: 3px solid #0d9488;"> <h4><a href="https://apis.io/servers/wefitter/wefitter-mcpyml/">wefitter-mcp.yml</a></h4><p></p><span class="card-badge" style="background: #0d9488;">MCP SERVER</span> </div> </div> <!-- Agent Skills --> <!-- GraphQL --> <!-- Pricing Plans --> <!-- Rate Limits --> <!-- FinOps --> <!-- Features --> <!-- Event Specifications (AsyncAPI) --> <h2 class="section-anchor" id="asyncapis"><a href="#asyncapis">Event Specifications</a> <span class="section-count">1</span></h2><p class="section-blurb">AsyncAPI definitions for this provider's event-driven and streaming APIs.</p> <div class="card-grid scroll-pane"> <div class="item-card" style="border-left: 3px solid #1e40af;"> <h4><a href="https://apis.io/asyncapis/wefitter/wefitter-webhooks/">Wefitter Webhooks</a></h4><p></p><span class="card-badge" style="background: #1e40af;">ASYNCAPI</span> </div> </div> <!-- Semantic Vocabularies (JSON-LD) --> <!-- Spectral Rules — bespoke card (severity breakdown) --> <!-- JSON Schema --> <!-- JSON Structure --> <!-- Examples --> <!-- Security Posture --> <h2 class="section-anchor" id="security"><a href="#security">Security Posture</a> <span class="section-count">2</span></h2><p class="section-blurb">Authentication, domain security, vulnerability disclosure, and trust-center signals.</p> <div class="card-grid scroll-pane"> <div class="item-card" style="border-left: 3px solid #b91c1c;"> <h4><a href="https://apis.io/security/wefitter/wefitter-authentication/">Wefitter Authentication</a></h4><p>apiKey/http · 2 schemes</p><span class="card-badge" style="background: #b91c1c;">SECURITY</span> </div> <div class="item-card" style="border-left: 3px solid #b91c1c;"> <h4><a href="https://apis.io/security/wefitter/wefitter-domain-security/">Wefitter Domain Security</a></h4><p>TLSv1.3 · HSTS · DNSSEC · DMARC</p><span class="card-badge" style="background: #b91c1c;">SECURITY</span> </div> </div> <!-- Scopes --> <!-- Agentic Access --> <h2 class="section-anchor" id="agentic-access"><a href="#agentic-access">Agentic Access</a> <span class="section-count">1</span></h2><p class="section-blurb">Recommended x-agentic-access execution contracts for AI agents.</p> <div class="card-grid scroll-pane"> <div class="item-card" style="border-left: 3px solid #6d28d9;"> <h4><a href="https://apis.io/agentic-access/wefitter/wefitter-agentic-access/">Wefitter Agentic Access</a></h4><p>77 operations · 34 acting</p><p class="card-meta">77 operations · 34 acting</p><span class="card-badge" style="background: #6d28d9;">AGENTIC</span> </div> </div> <!-- Use Cases --> <!-- Integrations --> <!-- Solutions --> <!-- Kubernetes CRDs — bespoke card (external links) --> <!-- Press — bespoke card (external links) --> <!-- Resources Section — grouped by the JOB the resource does, mirroring the way the rating panel groups its checks into facets. A provider can declare 50+ properties; ungrouped they were an undifferentiated wall of cards where a status page sat next to a privacy policy. The groups follow the integrator's arc: start it, read it, build it, secure it, learn it, run it, then the commercial and corporate surface. Each property's `group` is assigned in build.py (resource_group()), so this template only has to filter — Liquid has no array-append, which makes the equivalent in-template grouping quadratic and fragile. --> <h2 class="section-anchor" id="resources"><a href="#resources">Resources</a></h2> <div class="res-group"> <div class="res-group-head"> <h3 id="resources-start">Get Started <span class="res-count">3</span></h3> <p>Portal, sign-up, and the first successful call</p> </div> <div class="card-grid"> <a href="https://www.wefitter.com/en-us/developers/" target="_blank" rel="noopener" class="item-card res-card res-start"> <strong>DeveloperPortal</strong> <div class="res-type">DeveloperPortal</div> </a> <a href="https://www.wefitter.com/en-us/developers/getting-started/" target="_blank" rel="noopener" class="item-card res-card res-start"> <strong>GettingStarted</strong> <div class="res-type">GettingStarted</div> </a> <a href="https://api.wefitter.com/dashboard" target="_blank" rel="noopener" class="item-card res-card res-start"> <strong>SignUp</strong> <div class="res-type">SignUp</div> </a> </div> </div> <div class="res-group"> <div class="res-group-head"> <h3 id="resources-docs">Documentation <span class="res-count">4</span></h3> <p>Reference material describing how the API behaves</p> </div> <div class="card-grid"> <a href="https://www.wefitter.com/en-us/developers/documentation/" target="_blank" rel="noopener" class="item-card res-card res-docs"> <strong>Documentation</strong> <div class="res-type">Documentation</div> </a> <a href="https://api.wefitter.com/api/v1.3/redoc/" target="_blank" rel="noopener" class="item-card res-card res-docs"> <strong>APIReference</strong> <div class="res-type">APIReference</div> </a> <a href="https://www.wefitter.com/en-us/developers/guides/" target="_blank" rel="noopener" class="item-card res-card res-docs"> <strong>Guides</strong> <div class="res-type">Guides</div> </a> <a href="openapi/wefitter-openapi-original.json" target="_blank" rel="noopener" class="item-card res-card res-docs"> <strong>OpenAPI</strong> <div class="res-type">OpenAPI</div> </a> </div> </div> <div class="res-group"> <div class="res-group-head"> <h3 id="resources-agent">Agent Surfaces <span class="res-count">4</span></h3> <p>MCP servers, agent skills, and machine-readable catalogs</p> </div> <div class="card-grid"> <a href="mcp/wefitter-mcp.yml" target="_blank" rel="noopener" class="item-card res-card res-agent"> <strong>MCPServer</strong> <div class="res-type">MCPServer</div> </a> <a href="llms/wefitter-llms.txt" target="_blank" rel="noopener" class="item-card res-card res-agent"> <strong>LLMsTxt</strong> <div class="res-type">LLMsTxt</div> </a> <a href="skills/_index.yml" target="_blank" rel="noopener" class="item-card res-card res-agent"> <strong>AgentSkill</strong> <div class="res-type">AgentSkill</div> </a> <a href="agentic-access/wefitter-agentic-access.yml" target="_blank" rel="noopener" class="item-card res-card res-agent"> <strong>AgenticAccess</strong> <div class="res-type">AgenticAccess</div> </a> </div> </div> <div class="res-group"> <div class="res-group-head"> <h3 id="resources-design">Design & Contract <span class="res-count">7</span></h3> <p>Pagination, idempotency, versioning, errors, and events</p> </div> <div class="card-grid scroll-pane"> <a href="conformance/wefitter-conformance.yml" target="_blank" rel="noopener" class="item-card res-card res-design"> <strong>Conformance</strong> <div class="res-type">Conformance</div> </a> <a href="errors/wefitter-problem-types.yml" target="_blank" rel="noopener" class="item-card res-card res-design"> <strong>ErrorCatalog</strong> <div class="res-type">ErrorCatalog</div> </a> <a href="lifecycle/wefitter-lifecycle.yml" target="_blank" rel="noopener" class="item-card res-card res-design"> <strong>Lifecycle</strong> <div class="res-type">Lifecycle</div> </a> <a href="conventions/wefitter-conventions.yml" target="_blank" rel="noopener" class="item-card res-card res-design"> <strong>Conventions</strong> <div class="res-type">Conventions</div> </a> <a href="data-model/wefitter-data-model.yml" target="_blank" rel="noopener" class="item-card res-card res-design"> <strong>DataModel</strong> <div class="res-type">DataModel</div> </a> <a href="asyncapi/wefitter-webhooks.yml" target="_blank" rel="noopener" class="item-card res-card res-design"> <strong>Webhooks</strong> <div class="res-type">Webhooks</div> </a> <a href="components/wefitter-components.yml" target="_blank" rel="noopener" class="item-card res-card res-design"> <strong>Components</strong> <div class="res-type">Components</div> </a> </div> <p class="scroll-hint">Scroll for all 7</p> </div> <div class="res-group"> <div class="res-group-head"> <h3 id="resources-build">Build <span class="res-count">3</span></h3> <p>SDKs, sample code, and the tooling you integrate with</p> </div> <div class="card-grid"> <a href="https://github.com/wefitter" target="_blank" rel="noopener" class="item-card res-card res-build"> <strong>GitHubOrganization</strong> <div class="res-type">GitHubOrganization</div> </a> <a href="packages/wefitter-packages.yml" target="_blank" rel="noopener" class="item-card res-card res-build"> <strong>Packages</strong> <div class="res-type">Packages</div> </a> <a href="packages/wefitter-packages.yml" target="_blank" rel="noopener" class="item-card res-card res-build"> <strong>SDKs</strong> <div class="res-type">SDKs</div> </a> </div> </div> <div class="res-group"> <div class="res-group-head"> <h3 id="resources-auth">Access & Security <span class="res-count">2</span></h3> <p>Authentication, authorization, and security posture</p> </div> <div class="card-grid"> <a href="security/wefitter-domain-security.yml" target="_blank" rel="noopener" class="item-card res-card res-auth"> <strong>DomainSecurity</strong> <div class="res-type">DomainSecurity</div> </a> <a href="authentication/wefitter-authentication.yml" target="_blank" rel="noopener" class="item-card res-card res-auth"> <strong>Authentication</strong> <div class="res-type">Authentication</div> </a> </div> </div> <div class="res-group"> <div class="res-group-head"> <h3 id="resources-operate">Operate <span class="res-count">3</span></h3> <p>Status, limits, changes, and where to get help</p> </div> <div class="card-grid"> <a href="https://developers.wefitter.com/support" target="_blank" rel="noopener" class="item-card res-card res-operate"> <strong>Support</strong> <div class="res-type">Support</div> </a> <a href="https://www.wefitter.com/en-us/developers/changelog/" target="_blank" rel="noopener" class="item-card res-card res-operate"> <strong>ChangeLog</strong> <div class="res-type">ChangeLog</div> </a> <a href="changelog/wefitter-changelog.yml" target="_blank" rel="noopener" class="item-card res-card res-operate"> <strong>ChangeLog</strong> <div class="res-type">ChangeLog</div> </a> </div> </div> <div class="res-group"> <div class="res-group-head"> <h3 id="resources-commercial">Commercial <span class="res-count">2</span></h3> <p>Pricing, plans, and the legal terms of use</p> </div> <div class="card-grid"> <a href="https://www.wefitter.com/en-us/terms-and-conditions/" target="_blank" rel="noopener" class="item-card res-card res-commercial"> <strong>TermsOfService</strong> <div class="res-type">TermsOfService</div> </a> <a href="https://www.wefitter.com/en-us/privacy-policy/" target="_blank" rel="noopener" class="item-card res-card res-commercial"> <strong>PrivacyPolicy</strong> <div class="res-type">PrivacyPolicy</div> </a> </div> </div> <div class="res-group"> <div class="res-group-head"> <h3 id="resources-company">Company <span class="res-count">2</span></h3> <p>The organization behind the API</p> </div> <div class="card-grid"> <a href="https://www.wefitter.com/en-us/resources/blog/" target="_blank" rel="noopener" class="item-card res-card res-company"> <strong>Blog</strong> <div class="res-type">Blog</div> </a> <a href="https://wefitter.com" target="_blank" rel="noopener" class="item-card res-card res-company"> <strong>Website</strong> <div class="res-type">Website</div> </a> </div> </div> <div class="res-group"> <div class="res-group-head"> <h3 id="resources-other">Other <span class="res-count">1</span></h3> <p>Properties that don't map to a standard resource type</p> </div> <div class="card-grid"> <a href="overlays/wefitter-openapi-overlay.yaml" target="_blank" rel="noopener" class="item-card res-card res-other"> <strong>Overlay</strong> <div class="res-type">Overlay</div> </a> </div> </div> <!-- Source (apis.yml) — always rendered last, at the bottom of the page. The include renders its own heading with id="source" (the #source anchor target). specs='none' keeps this to apis.yml alone: a provider page describes the company, and its individual specs belong on the API pages they document. --> <link rel="stylesheet" href="/assets/prism/prism-coy.min.css"> <link rel="stylesheet" href="/assets/prism/prism-line-numbers.min.css"> <style> .src-widget { background: #fdfdfd; border: 1px solid #e3e7ee; border-radius: 10px; overflow: hidden; margin-top: 0.75rem; } .src-widget-head { display: flex; align-items: center; gap: 0.5rem; padding: 0.55rem 0.85rem; background: #f8fafc; border-bottom: 1px solid #e3e7ee; flex-wrap: wrap; } .src-label { color: #475569; font-weight: 600; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-size: 0.8rem; flex: 0 0 auto; } .src-picker { flex: 0 0 auto; max-width: 360px; padding: 0.3em 0.55em; border: 1px solid #cbd5e1; border-radius: 4px; background: #fff; font-size: 0.78rem; color: #1a1a2e; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; cursor: pointer; } .src-picker:focus { outline: none; border-color: #1e40af; box-shadow: 0 0 0 2px rgba(30, 64, 175, 0.15); } .src-loading { color: #94a3b8; font-style: italic; padding: 1rem; } .src-search { flex: 1 1 200px; min-width: 140px; } .src-search input { width: 100%; padding: 0.3em 0.6em; border: 1px solid #cbd5e1; border-radius: 4px; font-size: 0.8rem; background: #fff; color: #1a1a2e; } .src-search input:focus { outline: none; border-color: #1e40af; box-shadow: 0 0 0 2px rgba(30, 64, 175, 0.15); } .src-actions { display: flex; gap: 0.25rem; flex: 0 0 auto; } .src-actions a, .src-actions button { background: none; border: 1px solid transparent; padding: 0.25em 0.6em; color: #1e40af; font-size: 0.78rem; font-weight: 500; cursor: pointer; text-decoration: none; border-radius: 4px; line-height: 1.4; } .src-actions a:hover, .src-actions button:hover { background: #eef2f7; } .src-actions button.active { background: #dbeafe; border-color: #93c5fd; } .src-actions button:disabled { color: #94a3b8; cursor: not-allowed; } .src-actions button:disabled:hover { background: none; } .src-widget pre[class*="language-"] { margin: 0; padding: 1rem 0; background: #fdfdfd; box-shadow: none; border: none; max-height: 540px; overflow: auto; font-size: 0.82rem; line-height: 1.5; } .src-widget pre[class*="language-"] > code { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; padding-right: 1rem; } .src-widget pre[class*="language-"]::before, .src-widget pre[class*="language-"]::after { display: none; } .src-widget pre.line-numbers { padding-left: 3.5em; counter-reset: linenumber; position: relative; } .src-widget pre.line-numbers > code { position: relative; white-space: inherit; } .src-widget pre.line-numbers .line-numbers-rows { position: absolute; pointer-events: none; top: 1rem; font-size: 100%; left: -3em; width: 2.7em; letter-spacing: -1px; border-right: 1px solid #e3e7ee; user-select: none; } .src-widget pre.line-numbers .line-numbers-rows > span { display: block; counter-increment: linenumber; } .src-widget pre.line-numbers .line-numbers-rows > span:before { content: counter(linenumber); color: #cbd5e1; display: block; padding-right: 0.7em; text-align: right; font-size: 0.78rem; } .src-widget .token.key, .src-widget .token.property, .src-widget .token.atrule { color: #1e40af; font-weight: 600; } .src-widget .token.string { color: #047857; } .src-widget .token.number, .src-widget .token.boolean, .src-widget .token.null { color: #b45309; } .src-widget .token.comment { color: #94a3b8; font-style: italic; } .src-widget .token.punctuation, .src-widget .token.operator { color: #64748b; } .src-widget .token.tag { color: #7c3aed; } .src-widget .token.anchor, .src-widget .token.alias { color: #be185d; } .src-widget mark.src-hit { background: #fef08a; color: inherit; padding: 0; border-radius: 2px; } .src-widget mark.src-hit-active { background: #fb923c; color: #fff; } .src-copied { color: #047857 !important; } .src-empty { padding: 2rem 1rem; text-align: center; color: #94a3b8; font-size: 0.85rem; } </style> <h3 class="section-title" id="source">Source (apis.yml)</h3> <div class="src-widget" data-src-widget data-original-lang="yaml" data-current-lang="yaml" data-original-filename="apis.yml"> <div class="src-widget-head"> <span class="src-label" data-src-filename>apis.yml</span> <span class="src-search"> <input type="search" data-src-search placeholder="Search in source… (n / N to navigate)" aria-label="Search source"> </span> <span class="src-actions"> <button type="button" data-src-toggle data-target="yaml" aria-label="View as YAML">YAML</button> <button type="button" data-src-toggle data-target="json" aria-label="View as JSON">JSON</button> <button type="button" data-src-download aria-label="Download source">Download</button> <a data-src-raw href="https://raw.githubusercontent.com/api-evangelist/wefitter/refs/heads/main/apis.yml" target="_blank" rel="noopener">Raw ↑</a> <button type="button" data-src-copy>Copy</button> </span> </div> <pre class="line-numbers language-yaml"><code class="language-yaml" data-src-code>x-enrichment: date: '2026-07-21' status: enriched artifacts_added: 16 pass: local-v1 aid: wefitter name: WeFitter description: WeFitter is a health and fitness data platform ("one API to access wearable data, gamification and AI") operated by Thunderbyte.AI in Groningen, Netherlands. Its REST API aggregates health and activity data from 300+ wearables and fitness apps — Fitbit, Garmin, Google Fit, Apple Health, Withings, Polar, Oura, Whoop, Samsung Health, Huawei and more — into a single unified, deduplicated data model, and layers gamification (challenges, leaderboards, teams, points) and AI insights (biological age, recommendations) on top. Organizations use it to build corporate wellbeing, digital fitness, e-health and insurance solutions. WeFitter also ships mobile SDK bridges for Apple Health, Samsung Health and Android Health Connect. accessModel: pricing: unknown onboarding: self-serve trial: false try_now: false public: false label: Self-serve signup confidence: medium source: - authentication generated: '2026-07-22' method: derived image: https://www.wefitter.com/static/frontend/img/website/wefitter.png url: https://raw.githubusercontent.com/api-evangelist/wefitter/refs/heads/main/apis.yml x-type: company x-source: vc-portfolio x-backed-by: - 500-global x-operator: Thunderbyte.AI specificationVersion: '0.20' created: '2026-07-17' modified: '2026-07-21' tags: - Company - Health - Fitness - Wearables - Health Data - Wellbeing - Gamification - Digital Health - Insurance - Activity Tracking apis: - aid: wefitter:wefitter-app-api name: WeFitter app API description: The app API from WeFitter — 1 operation(s) for app. humanURL: https://www.wefitter.com/en-us/developers/ baseURL: https://api.wefitter.com/api/v1.3 tags: - app properties: - type: OpenAPI url: openapi/wefitter-app-api-openapi.yml - type: Swagger url: https://api.wefitter.com/api/v1.3/redoc/?format=openapi - type: APIReference url: https://api.wefitter.com/api/v1.3/redoc/ - aid: wefitter:wefitter-challenge-api name: WeFitter challenge API description: "WeFitter API’s challenge engine will bring endless engagement to your platform.\nFor more information about\ \ the possibilities in challenges please go to https://www.wefitter.com/en-us/features/gamification/\n\nChallenges have\ \ multilanguage support on the fields: `Title`, `Slogan`, and `Description`.\nBy default, challenges get the default-language\ \ that is configured in the app. Whenever a challenge is requested through the API this challenge will be presented in\ \ the default language.\nIf another language is preferred, this can be requested by adding the header parameter `Accept-Language`\ \ stating the language short code (ex. `en` for english). If this language short code is not present in the title of the\ \ challenge, the default language will be returned.\n\nThese translation fields contain JSON strings, for example:\n```{\"\ en\":\"this is the English title\",\"nl\":\"this is the Dutch title\"}```\nSo to create a multilanguage challenge, please\ \ provide the title, slogan, and description field as json strings, be aware that because of serialization this should\ \ be formed with backward slashes:\n\n\n<table><tbody>\n <tr><td>\n{\n\n\"title\": \"{\\\"en\\\":\\\"this is the English\ \ title\\\", \\\"nl\\\":\\\"this is the dutch title\\\"}\",\n\n\"slogan\": \"{\\\"en\\\":\\\"this is the English title\\\ \", \\\"nl\\\":\\\"this is the dutch slogan\\\"}\",\n\n\"description\": \"{\\\"en\\\":\\\"this is the English title\\\"\ , \\\"nl\\\":\\\"this is the dutch description\\\"}\",\n\n}\n</td></tr>\n</tbody></table>" humanURL: https://www.wefitter.com/en-us/developers/ baseURL: https://api.wefitter.com/api/v1.3 tags: - challenge properties: - type: OpenAPI url: openapi/wefitter-challenge-api-openapi.yml - type: Swagger url: https://api.wefitter.com/api/v1.3/redoc/?format=openapi - type: APIReference url: https://api.wefitter.com/api/v1.3/redoc/ - aid: wefitter:wefitter-connection-api name: WeFitter connection API description: Connections are the links between profiles and their wearables. humanURL: https://www.wefitter.com/en-us/developers/ baseURL: https://api.wefitter.com/api/v1.3 tags: - connection properties: - type: OpenAPI url: openapi/wefitter-connection-api-openapi.yml - type: Swagger url: https://api.wefitter.com/api/v1.3/redoc/?format=openapi - type: APIReference url: https://api.wefitter.com/api/v1.3/redoc/ - aid: wefitter:wefitter-insights-api name: WeFitter insights API description: The insights API from WeFitter — 1 operation(s) for insights. humanURL: https://www.wefitter.com/en-us/developers/ baseURL: https://api.wefitter.com/api/v1.3 tags: - insights properties: - type: OpenAPI url: openapi/wefitter-insights-api-openapi.yml - type: Swagger url: https://api.wefitter.com/api/v1.3/redoc/?format=openapi - type: APIReference url: https://api.wefitter.com/api/v1.3/redoc/ - aid: wefitter:wefitter-loyalty-api name: WeFitter loyalty API description: The loyalty API from WeFitter — 2 operation(s) for loyalty. humanURL: https://www.wefitter.com/en-us/developers/ baseURL: https://api.wefitter.com/api/v1.3 tags: - loyalty properties: - type: OpenAPI url: openapi/wefitter-loyalty-api-openapi.yml - type: Swagger url: https://api.wefitter.com/api/v1.3/redoc/?format=openapi - type: APIReference url: https://api.wefitter.com/api/v1.3/redoc/ - aid: wefitter:wefitter-notification-api name: WeFitter notification API description: "Send a notification to all devices for the specified profiles\nThe data will be sent to the client in the\ \ following format:\n```\n{\n \"app\": <app public id>,\n \"title\": <title>,\n \"body\": <body>,\n\ \ \"link\": <optional link>\n}\n```" humanURL: https://www.wefitter.com/en-us/developers/ baseURL: https://api.wefitter.com/api/v1.3 tags: - notification properties: - type: OpenAPI url: openapi/wefitter-notification-api-openapi.yml - type: Swagger url: https://api.wefitter.com/api/v1.3/redoc/?format=openapi - type: APIReference url: https://api.wefitter.com/api/v1.3/redoc/ - aid: wefitter:wefitter-profile-api name: WeFitter profile API description: 'Profiles are containers for wearables data. The profiles can be seen as an extension of users in a different system. Profiles are anonymous objects which can participate in teams and challenges. Keep in mind, listing profiles and creating profiles need an administrative bearer token, all profile specific actions need a seperate bearer token that is returned after creating a profile. This bearer token is used in place of the administrative bearer token. (see profile create action for more information)' humanURL: https://www.wefitter.com/en-us/developers/ baseURL: https://api.wefitter.com/api/v1.3 tags: - profile properties: - type: OpenAPI url: openapi/wefitter-profile-api-openapi.yml - type: Swagger url: https://api.wefitter.com/api/v1.3/redoc/?format=openapi - type: APIReference url: https://api.wefitter.com/api/v1.3/redoc/ - aid: wefitter:wefitter-team-api name: WeFitter team API description: The team API from WeFitter — 5 operation(s) for team. humanURL: https://www.wefitter.com/en-us/developers/ baseURL: https://api.wefitter.com/api/v1.3 tags: - team properties: - type: OpenAPI url: openapi/wefitter-team-api-openapi.yml - type: Swagger url: https://api.wefitter.com/api/v1.3/redoc/?format=openapi - type: APIReference url: https://api.wefitter.com/api/v1.3/redoc/ - aid: wefitter:wefitter-token-api name: WeFitter token API description: '<p> Before any calls can be made to wefitter, BasicAuth is needed to verify the identity of the requesting party. This call will result into a Bearer token which has administrator privileges and is valid for 1 day. This token can be used to create profiles, challenges, etc. </p> <p> The returned bearer is a JWT (<a href="https://en.wikipedia.org/wiki/JSON_Web_Token">JSON Web Token</a>). </p>' humanURL: https://www.wefitter.com/en-us/developers/ baseURL: https://api.wefitter.com/api/v1.3 tags: - token properties: - type: OpenAPI url: openapi/wefitter-token-api-openapi.yml - type: Swagger url: https://api.wefitter.com/api/v1.3/redoc/?format=openapi - type: APIReference url: https://api.wefitter.com/api/v1.3/redoc/ maintainers: - FN: Kin Lane email: kin@apievangelist.com - FN: APIs.json email: info@apis.io common: - type: DeveloperPortal url: https://www.wefitter.com/en-us/developers/ - type: Documentation url: https://www.wefitter.com/en-us/developers/documentation/ - type: GettingStarted url: https://www.wefitter.com/en-us/developers/getting-started/ - type: APIReference url: https://api.wefitter.com/api/v1.3/redoc/ - type: Guides url: https://www.wefitter.com/en-us/developers/guides/ - type: Support url: https://developers.wefitter.com/support - type: Blog url: https://www.wefitter.com/en-us/resources/blog/ - type: ChangeLog url: https://www.wefitter.com/en-us/developers/changelog/ - type: GitHubOrganization url: https://github.com/wefitter - type: SignUp url: https://api.wefitter.com/dashboard - type: TermsOfService url: https://www.wefitter.com/en-us/terms-and-conditions/ - type: PrivacyPolicy url: https://www.wefitter.com/en-us/privacy-policy/ - type: OpenAPI url: openapi/wefitter-openapi-original.json - type: Overlay url: overlays/wefitter-openapi-overlay.yaml - type: Packages url: packages/wefitter-packages.yml - type: SDKs url: packages/wefitter-packages.yml - type: MCPServer url: mcp/wefitter-mcp.yml - type: LLMsTxt url: llms/wefitter-llms.txt - type: Conformance url: conformance/wefitter-conformance.yml - type: ErrorCatalog url: errors/wefitter-problem-types.yml - type: Lifecycle url: lifecycle/wefitter-lifecycle.yml - type: ChangeLog url: changelog/wefitter-changelog.yml - type: Conventions url: conventions/wefitter-conventions.yml - type: DataModel url: data-model/wefitter-data-model.yml - type: Webhooks url: asyncapi/wefitter-webhooks.yml - type: Components url: components/wefitter-components.yml - type: AgentSkill url: skills/_index.yml - type: DomainSecurity url: security/wefitter-domain-security.yml - type: AgenticAccess url: agentic-access/wefitter-agentic-access.yml - type: Authentication url: authentication/wefitter-authentication.yml - type: Website url: https://wefitter.com </code></pre> </div> <script src="/assets/prism/prism-core.min.js" defer></script> <script src="/assets/prism/prism-yaml.min.js" defer></script> <script src="/assets/prism/prism-json.min.js" defer></script> <script src="/assets/prism/prism-line-numbers.min.js" defer></script> <script src="/assets/prism/js-yaml.min.js" defer></script> <script> (function () { if (window.__srcWidgetInit) return; window.__srcWidgetInit = true; function initWidget(widget) { var codeEl = widget.querySelector('[data-src-code]'); var preEl = widget.querySelector('pre'); var search = widget.querySelector('[data-src-search]'); var toggles = widget.querySelectorAll('[data-src-toggle]'); var downloadBtn = widget.querySelector('[data-src-download]'); var copyBtn = widget.querySelector('[data-src-copy]'); var fileLabel = widget.querySelector('[data-src-filename]'); var picker = widget.querySelector('[data-src-picker]'); var rawLink = widget.querySelector('[data-src-raw]'); var headingEl = widget.previousElementSibling && widget.previousElementSibling.tagName === 'H3' ? widget.previousElementSibling : null; var fetchedCache = {}; // Original raw text — we always re-render from this so toggles + searches don't compound. var originalLang = widget.dataset.originalLang; var originalText = codeEl.textContent; var originalFilename = widget.dataset.originalFilename; var currentLang = originalLang; var currentText = originalText; var searchHits = []; var activeHit = -1; function highlight() { if (window.Prism) window.Prism.highlightElement(codeEl); } function setActiveToggle() { toggles.forEach(function (b) { if (b.dataset.target === currentLang) b.classList.add('active'); else b.classList.remove('active'); }); } function updateFilenameForLang() { if (!fileLabel) return; var base = (currentSourceFilename || originalFilename).replace(/\.(ya?ml|json)$/i, ''); fileLabel.textContent = base + '.' + currentLang; } var currentSourceFilename = originalFilename; var currentSourceUrl = null; if (rawLink) currentSourceUrl = rawLink.getAttribute('href'); function setLangContent(lang, text) { currentLang = lang; currentText = text; codeEl.textContent = text; codeEl.className = 'language-' + lang; preEl.className = 'line-numbers language-' + lang; highlight(); setActiveToggle(); updateFilenameForLang(); runSearch(); } function tryConvert(targetLang) { if (targetLang === currentLang) return; if (!window.jsyaml) return; try { var parsed; if (currentLang === 'yaml') parsed = window.jsyaml.load(currentText); else parsed = JSON.parse(currentText); var out; if (targetLang === 'yaml') { out = window.jsyaml.dump(parsed, { indent: 2, lineWidth: 100, noRefs: true }); } else { out = JSON.stringify(parsed, null, 2); } setLangContent(targetLang, out); } catch (err) { alert('Cannot convert: source is not valid ' + currentLang.toUpperCase() + '.\n' + err.message); } } // ---- Search highlighting (DOM walker over text nodes inside <code>) ---- function clearSearch() { widget.querySelectorAll('mark.src-hit').forEach(function (m) { var parent = m.parentNode; while (m.firstChild) parent.insertBefore(m.firstChild, m); parent.removeChild(m); parent.normalize(); }); searchHits = []; activeHit = -1; } function runSearch() { clearSearch(); var q = (search.value || '').trim(); if (q.length < 2) return; var qLower = q.toLowerCase(); var walker = document.createTreeWalker(codeEl, NodeFilter.SHOW_TEXT, null); var nodes = []; var n; while ((n = walker.nextNode())) nodes.push(n); nodes.forEach(function (node) { var text = node.nodeValue; var lower = text.toLowerCase(); var idx = lower.indexOf(qLower); if (idx === -1) return; var frag = document.createDocumentFragment(); var cursor = 0; while (idx !== -1) { if (idx > cursor) frag.appendChild(document.createTextNode(text.slice(cursor, idx))); var mark = document.createElement('mark'); mark.className = 'src-hit'; mark.textContent = text.slice(idx, idx + q.length); frag.appendChild(mark); searchHits.push(mark); cursor = idx + q.length; idx = lower.indexOf(qLower, cursor); } if (cursor < text.length) frag.appendChild(document.createTextNode(text.slice(cursor))); node.parentNode.replaceChild(frag, node); }); if (searchHits.length) jumpToHit(0); } function jumpToHit(i) { if (!searchHits.length) return; if (activeHit >= 0 && searchHits[activeHit]) searchHits[activeHit].classList.remove('src-hit-active'); activeHit = ((i % searchHits.length) + searchHits.length) % searchHits.length; var el = searchHits[activeHit]; el.classList.add('src-hit-active'); el.scrollIntoView({ block: 'center', behavior: 'smooth' }); } // ---- Wire up ---- var debounce; search.addEventListener('input', function () { clearTimeout(debounce); debounce = setTimeout(runSearch, 100); }); search.addEventListener('keydown', function (ev) { if (ev.key === 'Enter' || ev.key === 'n') { ev.preventDefault(); jumpToHit(activeHit + 1); } else if (ev.key === 'N' || (ev.key === 'p')) { ev.preventDefault(); jumpToHit(activeHit - 1); } else if (ev.key === 'Escape') { search.value = ''; runSearch(); } }); toggles.forEach(function (b) { b.addEventListener('click', function () { tryConvert(b.dataset.target); }); }); downloadBtn.addEventListener('click', function () { var blob = new Blob([codeEl.textContent], { type: currentLang === 'json' ? 'application/json' : 'application/yaml' }); var url = URL.createObjectURL(blob); var a = document.createElement('a'); a.href = url; a.download = fileLabel.textContent; document.body.appendChild(a); a.click(); document.body.removeChild(a); setTimeout(function () { URL.revokeObjectURL(url); }, 0); }); copyBtn.addEventListener('click', function () { navigator.clipboard.writeText(codeEl.textContent).then(function () { var orig = copyBtn.textContent; copyBtn.textContent = 'Copied'; copyBtn.classList.add('src-copied'); setTimeout(function () { copyBtn.textContent = orig; copyBtn.classList.remove('src-copied'); }, 1500); }); }); // ---- Picker (provider pages with multiple specs) ---- function applySource(text, lang, filename, url, heading) { currentSourceFilename = filename || originalFilename; currentSourceUrl = url || null; if (rawLink) { if (url) { rawLink.setAttribute('href', url); rawLink.style.display = ''; } else { rawLink.style.display = 'none'; } } if (headingEl && heading) headingEl.textContent = heading; setLangContent(lang, text); } if (picker) { picker.addEventListener('change', function () { var opt = picker.options[picker.selectedIndex]; var url = opt.dataset.url; var fmt = opt.dataset.format || 'yaml'; var fname = opt.dataset.filename || ''; var heading = opt.dataset.heading || ''; if (!url) { // Original embedded source applySource(originalText, originalLang, originalFilename, picker.options[0].dataset.url || null, picker.options[0].dataset.heading || ''); return; } if (fetchedCache[url]) { applySource(fetchedCache[url], fmt, fname, url, heading); return; } codeEl.textContent = 'Loading ' + fname + '…'; codeEl.className = ''; preEl.className = ''; fetch(url).then(function (r) { if (!r.ok) throw new Error('HTTP ' + r.status); return r.text(); }).then(function (text) { fetchedCache[url] = text; applySource(text, fmt, fname, url, heading); }).catch(function (err) { codeEl.textContent = 'Could not load: ' + err.message; }); }); // Stash the default option's url so we can restore "Raw" link when reset. if (rawLink && picker.options[0]) { picker.options[0].dataset.url = rawLink.getAttribute('href') || ''; picker.options[0].dataset.heading = (headingEl ? headingEl.textContent : '') || ''; } } // Auto-fetch when initial source is empty but a remote URL is available. // This happens when the build found an external OpenAPI URL but didn't // inline the content — the widget fetches it on page load instead. if (!originalText.trim() && currentSourceUrl) { var remoteUrl = currentSourceUrl; codeEl.textContent = 'Loading…'; codeEl.className = ''; preEl.className = 'line-numbers language-' + originalLang; fetch(remoteUrl) .then(function (r) { if (!r.ok) throw new Error('HTTP ' + r.status); return r.text(); }) .then(function (text) { var ext = remoteUrl.replace(/\?.*/, '').split('.').pop().toLowerCase(); var fmt = ext === 'json' ? 'json' : 'yaml'; originalText = text; originalLang = fmt; currentLang = fmt; widget.dataset.originalLang = fmt; applySource(text, fmt, originalFilename, remoteUrl, headingEl ? headingEl.textContent : ''); }) .catch(function (err) { codeEl.textContent = 'Could not load spec: ' + err.message; }); } // Initial state setActiveToggle(); // Wait for Prism to load before highlighting / line-numbers wiring. var tries = 0; var waitPrism = setInterval(function () { if (window.Prism && window.Prism.plugins) { clearInterval(waitPrism); highlight(); } else if (++tries > 80) { clearInterval(waitPrism); } }, 50); } function initAll() { document.querySelectorAll('[data-src-widget]').forEach(initWidget); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initAll); } else { initAll(); } })(); </script> <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "Organization", "name": "WeFitter", "description": "WeFitter is a health and fitness data platform (\"one API to access wearable data, gamification and AI\") operated by Thunderbyte.AI in Groningen, Netherlands. Its REST API aggregates health and activity data from 300+ wearables and fitness apps — Fitbit, Garmin, Google Fit, Apple Health, Withings, Polar, Oura, Whoop, Samsung Health, Huawei and more — into a single unified, deduplicated data model, and layers gamification (challenges, leaderboards, teams, points) and AI insights (biological age, recommendations) on top. Organizations use it to build corporate wellbeing, digital fitness, e-health and insurance solutions. WeFitter also ships mobile SDK bridges for Apple Health, Samsung Health and Android Health Connect.", "logo": "https://www.wefitter.com/static/frontend/img/website/wefitter.png", "keywords": "Company, Health, Fitness, Wearables, Health Data, Wellbeing, Gamification, Digital Health, Insurance, Activity Tracking" } </script> <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "BreadcrumbList", "itemListElement": [ { "@type": "ListItem", "position": 1, "name": "Home", "item": "https://apis.io/" }, { "@type": "ListItem", "position": 2, "name": "Providers", "item": "https://apis.io/providers/" }, { "@type": "ListItem", "position": 3, "name": "WeFitter" } ] } </script> </main> <footer class="footer"> <div class="container"> <div class="footer-links d-flex flex-wrap justify-content-center column-gap-4 row-gap-2 align-items-center"> <a href="https://apis.io/about/">About</a> <a href="https://apis.io/add/">Add API</a> <a href="http://apisjson.org">APIs.json</a> <a href="http://apicommons.org">API Commons</a> <a href="https://apis.io/developer">Developers</a> <a href="https://apis.io/roadmap/">Roadmap</a> <a href="https://apis.io/changelog/">Changelog</a> <a href="https://github.com/api-search">GitHub</a> <a href="https://apis.io/terms/">Terms</a> <a href="https://apis.io/privacy/">Privacy</a> </div> </div> </footer><script src="/assets/js/kin-glyph.js"></script> </body> </html>