API reference
The Forzelite Partner API is documented as an OpenAPI 3.1 spec. Copy the YAML below into Postman, ReDoc, or your preferred generator. The live runtime spec is also available at /openapi.json on every API host.
# Forzelite Partner API
# OpenAPI 3.1 spec for /api/v2/external/*
# Export this file and import it into Postman or your generator of choice.
openapi: 3.1.0
info:
title: Forzelite Partner API
version: "2.0"
description: |
OAuth 2.0 client_credentials surface for third-party integrations
against Forzelite tenant data.
servers:
- url: https://api.forzelite.com
description: Production
- url: http://localhost:8000
description: Local development
paths:
/api/v2/external/oauth/token:
post:
summary: Issue an access token (client_credentials grant)
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
type: object
required: [grant_type, client_id, client_secret]
properties:
grant_type:
type: string
enum: [client_credentials]
client_id: { type: string }
client_secret: { type: string }
scope: { type: string }
responses:
"200":
description: Token issued
content:
application/json:
schema:
$ref: "#/components/schemas/TokenResponse"
"401": { description: invalid_client }
"400": { description: unsupported_grant_type }
/api/v2/external/whoami:
get:
summary: Token introspection helper
security: [{ bearerAuth: [] }]
responses:
"200":
description: caller identity
content:
application/json:
schema:
$ref: "#/components/schemas/WhoAmIResponse"
/api/v2/external/athletes/{athlete_id}:
get:
summary: Read a consented athlete profile
security: [{ bearerAuth: ["athletes:read"] }]
parameters:
- in: path
name: athlete_id
required: true
schema: { type: string, format: uuid }
responses:
"200":
description: athlete profile
content:
application/json:
schema:
$ref: "#/components/schemas/AthleteProfile"
"404": { description: not found or not consented }
/api/v2/external/insights:
post:
summary: Submit a third-party insight card
security: [{ bearerAuth: ["insights:write"] }]
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/InsightSubmit"
responses:
"201":
description: card created
content:
application/json:
schema:
$ref: "#/components/schemas/InsightResult"
/api/v2/external/usage:
get:
summary: Read this application's recent usage
security: [{ bearerAuth: ["usage:read"] }]
responses:
"200":
description: usage entries
content:
application/json:
schema:
$ref: "#/components/schemas/UsageDashboard"
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: HMAC-SHA256
schemas:
TokenResponse:
type: object
properties:
access_token: { type: string }
token_type: { type: string }
expires_in: { type: integer }
scope: { type: string }
WhoAmIResponse:
type: object
properties:
client_id: { type: string }
tenant_id: { type: string, format: uuid }
scopes:
type: array
items: { type: string }
expires_at: { type: string, format: date-time }
AthleteProfile:
type: object
properties:
athlete_user_id: { type: string, format: uuid }
tenant_id: { type: string, format: uuid }
primary_sport: { type: string }
graduation_year: { type: integer, nullable: true }
height_cm: { type: number, nullable: true }
weight_kg: { type: number, nullable: true }
school_name: { type: string, nullable: true }
is_consented: { type: boolean }
InsightSubmit:
type: object
required: [athlete_user_id, title, body]
properties:
athlete_user_id: { type: string, format: uuid }
title: { type: string }
body: { type: string }
category: { type: string }
cta_label: { type: string, nullable: true }
cta_action: { type: object, nullable: true }
InsightResult:
type: object
properties:
id: { type: string, format: uuid }
accepted: { type: boolean }
created_at: { type: string, format: date-time }
UsageDashboard:
type: object
properties:
client_id: { type: string }
total_calls: { type: integer }
items:
type: array
items:
$ref: "#/components/schemas/UsageEntry"
UsageEntry:
type: object
properties:
id: { type: string, format: uuid }
request_method: { type: string }
request_path: { type: string }
response_status: { type: integer }
duration_ms: { type: integer }
created_at: { type: string, format: date-time }