Sportfolio

Sportfolio API

Welcome to the Sportfolio API. The base URL is https://api.sportfolio.app/v1. All requests are JSON, all responses are JSON, and every resource is REST-ful.

Quickstart

Grab a test-mode API key from Settings → API Keys, then make your first request:

curl https://api.sportfolio.app/v1/athletes \
  -H "Authorization: Bearer sk_test_•••" \
  --data-urlencode "limit=10"

You'll get back a list of verified athletes from your test workspace.

Authentication

Every request must carry an Authorization: Bearer <key> header. Test-mode keys are prefixed sk_test_; live keys are sk_live_. Rotate keys at any time from the dashboard — old keys keep working for 24 hours before invalidation.

OAuth 2.0 (for third-party apps)

Three-legged OAuth with PKCE is supported on all plans. Read the full flow in the OAuth guide.

REST API

GET /v1/athletes

Lists verified athletes. Supports sport, state, level, min_score, available, limit, and cursor query parameters.

POST /v1/briefs

Create a new campaign brief. Returns a brief object with id, status, and a shortlist array of athletes RightMatch™ surfaced.

POST /v1/offers

Send an offer to a specific athlete. Payload includes brief_id, athlete_id, amount, deliverables, terms.

GET /v1/deals/:id

Returns the full lifecycle of a single deal, including contract URL, compliance state, deliverable timeline, and payouts.

Webhooks

Subscribe to events from Settings → Webhooks. Every payload is signed with HMAC-SHA256; verify with the Sportfolio-Signature header. Available events:

  • deal.created, deal.accepted, deal.cancelled, deal.delivered, deal.paid
  • athlete.verified, athlete.score_changed
  • brief.published, brief.applied
  • payout.completed, compliance.filed, report.ready

SDKs

  • Node.js / TypeScriptnpm i @sportfolio/node
  • Pythonpip install sportfolio
  • Rubygem install sportfolio
  • PHPcomposer require sportfolio/sdk

Rate limits

Default: 600 requests/minute on Starter, 10,000/minute on Pro, custom on Enterprise. Burst windows are 60s. Exceed and you get a 429 with a Retry-After header.

Errors

Standard HTTP status codes. Every error returns a JSON body with error.code, error.message, and error.request_id — include that request_id when contacting support.