FullOut

FullOut Partner API & Embeds

Live competitive cheer scores, competition results, and event listings for approved media partners. Access is by invitation: keys are issued by the FullOut team. Contact team@fullout.energy to become a partner.

Authentication

Two kinds of keys. Secret keys (fo_live_…) are for server-to-server calls: send them in a header, never in a browser or URL. Publishable keys (fo_pk_…) are safe to appear in your page source; they only work for embeds and for browser calls from the domains registered to your key.

# Either header works:
curl -H "Authorization: Bearer fo_live_YOUR_KEY" https://fullout.energy/api/v1/scores/recent
curl -H "x-api-key: fo_live_YOUR_KEY" https://fullout.energy/api/v1/scores/recent

Responses are JSON in a { data, meta } envelope; errors are { error: { status, message } }. Every response carries RateLimit-* headers; your per-minute allowance is set on your key. CORS is enabled for your registered domains.

Endpoints

GET/api/v1/scores/recent

The freshest score updates (the same feed behind our live page), newest first. Params: limit (1–50, default 20), cursor (from meta.nextCursor), after (ISO timestamp; only newer items).

{
  "data": [
    {
      "id": "…", "sortAt": "2026-07-04T16:20:00.000Z", "round": "Finals", "placement": 1,
      "team": { "id": "…", "name": "Cheetahs", "gym": { "name": "Cheer Athletics", … } },
      "competition": { "id": "…", "name": "The Summit", "slug": "the-summit-2026", "date": "…" },
      "division": { "name": "L5 Senior Small", "level": "L5", … },
      "score": { "totalScore": 98.75, "finalScore": 98.4, "totalDeductions": 0.25 }
    }
  ],
  "meta": { "nextCursor": "2026-07-04T15:58:11.000Z" }
}

GET/api/v1/competitions

Competition listings. Params: status (upcoming | recent), state (e.g. TX), producer (producer slug, e.g. varsity), discipline (name from /api/v1/disciplines, case-insensitive), limit (1–100), cursor. Filters combine.

# Upcoming Varsity events in Texas
GET /api/v1/competitions?producer=varsity&state=TX&status=upcoming

# Recent All Star Cheer competitions
GET /api/v1/competitions?discipline=All%20Star%20Cheer&status=recent

GET/api/v1/competitions/{'{id-or-slug}'}

One competition with full results grouped by division: placement, team, gym, round, scores, and each division's discipline. Add ?division=<id | slug | exact name> to return just one division. 404 if unknown.

# All divisions
GET /api/v1/competitions/the-summit-2026

# One division only
GET /api/v1/competitions/the-summit-2026?division=L5%20Senior%20Small

GET/api/v1/disciplines

Reference list of active disciplines (All Star Cheer, School Cheer, College Cheer, Dance, STUNT, …) — the valid values for the discipline filter.

Embeddable widgets

Drop-in widgets served from fullout.energy, styled to blend into your pages and updated automatically. Requires a publishable key; widgets only render on your registered domains. Available: ticker (auto-scrolling latest scores), scoreboard (one competition's results; pass data-competition, optionally narrow with a division query param on the iframe URL), events (upcoming + recent events).

<script async src="https://fullout.energy/embed.js"
        data-widget="ticker"
        data-key="fo_pk_YOUR_KEY"
        data-theme="light"></script>

<script async src="https://fullout.energy/embed.js"
        data-widget="scoreboard"
        data-key="fo_pk_YOUR_KEY"
        data-competition="the-summit-2026"></script>

Prefer not to load third-party scripts? Place the iframe directly (the loader only injects it and auto-sizes the height):

<iframe src="https://fullout.energy/embed/ticker?key=fo_pk_YOUR_KEY"
        style="width:100%;border:0;height:48px" title="FullOut live scores"></iframe>

First-party profiles and Sessions linking

These server-to-server endpoints require an admin-issued first-party secret key. Ordinary partner keys and publishable keys receive 403 scope_denied. In Admin → API keys, create a Secret key and select “First-party Sessions profile integration”. Copy the key when it is shown; it cannot be retrieved later. The default allowance is 600 requests per minute, configurable per key.

GET/api/v1/people/search

Scope: profiles:read. Params: q (required, 2–64 characters), limit (1–50, default 10), opaque cursor, optional gym slug gym and gym state. Public profiles are ordered by creation time, newest first. Keep the filters unchanged when following meta.nextCursor. Cache: 10 minutes.

{ "data": [{ "id": "opaque-person-id", "name": "Katie Smith", "profileSlug": "katie-smith",
  "gym": { "name": "Cheer Athletics", "slug": "cheer-athletics" },
  "teams": [{ "name": "Cheetahs", "level": "L5", "season": "2025-26", "isCurrent": false }],
  "avatarUrl": null, "matchedAt": "2026-07-04T16:20:00.000Z" }], "meta": { "nextCursor": null } }

IDs are FullOut’s existing opaque IDs; do not assume a prefix. profileSlug is the profile username, falling back to its ID. matchedAt is the most recent public result posting or material score change during the person’s recorded team tenure, or null. Gym, avatar and level may also be null. Name search is for display and never establishes identity.

GET/api/v1/people/lookup?email=

Requires both profiles:read and identity:link. Exact, case-insensitive account email only. Returns the account’s own public person profile, never a child merely sharing its owner account. Missing, ambiguous or non-public identities return 404 not_found. No caching.

{ "data": { "id": "opaque-person-id", "name": "Katie Smith", "profileSlug": "katie-smith", "accountEmailVerified": true }, "meta": {} }

GET/api/v1/people/{id}

Scope: profiles:read. Accepts a person ID or profile slug. Returns the search profile fields, teams with isCurrent, and public placements with competition (name, slug, date), division (name, level), round, placement, and score (totalScore, finalScore). Private or unknown profiles return 404 not_found. Confidential producer results are always excluded. Cache: 10 minutes.

POST/api/v1/connect/sessions

Scope: identity:link. Redeem a code generated under Settings → Connections → Connect to Sessions in FullOut. Sessions must derive the account headers from its authenticated athlete account, never from a name search. Percent-encode the display-name header for non-ASCII text. No caching.

curl -X POST https://fullout.energy/api/v1/connect/sessions \
  -H "Authorization: Bearer fo_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "X-Sessions-Account-Id: sessions-athlete-id" \
  -H "X-Sessions-Display-Name: Katie%20Smith" \
  -d '{"code":"K7QX-4M2P"}'

{ "data": { "person": { "id": "opaque-person-id", "name": "Katie Smith" },
  "linkedAccount": { "product": "sessions", "displayName": "Katie Smith" } }, "meta": {} }

POST/api/v1/connect/sessions/codes

To start in Sessions, send { "externalAccountId": "sessions-athlete-id", "displayName": "Katie Smith" } with the same scope and first-party key. Returns code, expiresAt, and a server-only receipt. The user enters the code in FullOut for their selected profile; a parent may select a child they manage.

GET/api/v1/connect/sessions

Poll a Sessions-issued code using the issuing key and X-Sessions-Receipt. Returns { "status": "pending" } or status: linked with person and linkedAccount. Poll before the ten-minute expiry; the receipt is not a reusable credential. No caching.

Codes contain eight characters displayed as XXXX-XXXX, are hashed at rest, expire after ten minutes, and work once. Connection attempts have an additional durable 30-per-minute budget per key/account (FullOut code generation: 10). A conflicting existing link returns 409 already_linked; an invalid, expired or consumed code returns 400 invalid_code. Links confer no posting or person-write permission and do not unlock private profiles. Contact FullOut support to unlink.

Use x-api-key for CDN caching; Vercel bypasses its CDN for requests with an Authorization header. Cached responses vary by both credential headers, with no stale serving. Revocation and profile-privacy changes may take up to ten minutes to affect an already cached response. Lookup and connect responses, including errors, use Cache-Control: no-store.

Data & fair use

  • All data is public, non-confidential competition data. Gated producer data is never served.
  • Responses are CDN-cached 1–10 minutes depending on endpoint; poll accordingly.
  • Attribution ("Powered by FullOut" with a link) is required per your partner agreement.
  • Admins can rotate or revoke keys; already cached public responses expire at their stated TTL. Billing is monthly per your agreement.