Skip to main content
The Public API uses OAuth client credentials for server-to-server access. This matches the Jortt-style pattern: use client_id and client_secret at the token endpoint, then call API resources with a Bearer token.
Setting up for the first time? The Quickstart walks through credential creation, token exchange, and a first call step by step.
Public API resource calls do not accept x-api-key. The x-api-key header is not part of the new Public API auth model.
/public/v1/access/* uses a separate device-key contract for gates and scanners. It does not use OAuth scopes or fspt_... Bearer tokens. See Access Devices for x-device-key authentication.

1. Create an OAuth client

A coach creates a Public API OAuth client from the authenticated FITsociety app API:
The response includes clientSecret once. Store it securely. FITsociety stores only a hash of the secret. Some scopes expose health data or private communication. Granting them requires an explicit consent in the optional consents object:
  • Scopes marked requiresConsent: "health" in the scope catalog (measurements, progress summaries and photos, intakes, checkups, form assignments, habits, goals, documents) require "consents": { "healthData": true }. Otherwise creation fails with 400 PUBLIC_API_HEALTH_CONSENT_REQUIRED.
  • Scopes marked requiresConsent: "private_communication" (messages, client notes) require "consents": { "privateCommunication": true }. Otherwise creation fails with 400 PUBLIC_API_PRIVATE_COMM_CONSENT_REQUIRED.
Accepted consents are stored on the client with the acceptance timestamp and accepting coach. At runtime, tokens for a client without the matching accepted consent receive 403 scopes.health_consent_required or 403 scopes.private_communication_consent_required on consent-gated endpoints, even when the scope itself was granted. GET /public/v1/scopes marks each consent-gated scope with a requiresConsent field.

2. Request an access token

Exchange the client credentials for an access token:
Response:
If scope is omitted, FITsociety issues all scopes assigned to the client. Requested scopes must be a subset of the client’s assigned scopes.

Current company access

Each resource request checks whether Public API access is currently available for the company bound to the token. Removing that company from a private provider’s allowlist, or disabling the provider globally, blocks the next request with 403 auth.provider_unavailable, including requests with an unexpired token. Re-enabling access allows otherwise valid tokens to work again. Revoking an OAuth client cannot be undone and returns 401 auth.invalid_client (or 401 auth.invalid_token for revoked tokens).

Available scopes

3. Call a resource

Use the access token in the Authorization header:
Example:
Write requests require a stable Idempotency-Key header. Reuse the same key only when retrying the exact same request.

Token lifetime

Rotating a client secret revokes existing access tokens for that client.