DocsAPI Reference

All REST API endpoints and usage

API Reference

All API routes live under src/app/api/. They are Next.js App Router route handlers using the standard GET, POST, etc. export convention.

Authentication

Frame.io OAuth

GET /api/auth/frameio

Initiates the Frame.io OAuth flow by redirecting to Adobe IMS with the configured client ID and scopes.

GET /api/auth/frameio/callback

Handles the OAuth callback. Exchanges the authorization code for access/refresh tokens and stores them in HTTP-only cookies.


Video Processing & Storage

POST /api/clips/store

Fetches a processed clip from the Modal API (with retry logic), uploads the video to Supabase Storage (session-videos bucket), and saves the stats JSON to the clip record. Requires authentication -- verifies the caller owns the clip via coach_id.

Body:

{
  "clipId": "uuid"
}

POST /api/sessions/store

Similar to clip store but operates at the session level. Fetches the processed session video from Modal, uploads to Supabase Storage, and saves stats. Requires authentication -- verifies the caller owns the session via coach_id.

Body:

{
  "sessionId": "uuid"
}

GET /api/video/sign

Generates an HMAC-signed stream URL for a given upstream video URL. Requires authentication. The signed URL has a 1-hour TTL.

Query params:

ParamDescription
urlThe upstream video URL to sign for streaming

Response: { "url": "/api/video/stream?url=...&expires=...&token=..." }

GET /api/video/stream

Video stream proxy with byte-range support. Proxies video from allowlisted hosts (Modal, Supabase, Frame.io) to the client. Handles Range headers for seeking. Requires a valid HMAC token (obtained from /api/video/sign).

Query params:

ParamDescription
urlThe source video URL to proxy
tokenHMAC signature (from /api/video/sign)
expiresToken expiry timestamp in ms

Frame.io Integration

All Frame.io endpoints require a valid OAuth token stored in the frameio_token cookie. Returns 401 if the token is missing or expired.

GET /api/frameio/me

Returns the current Frame.io user profile.

GET /api/frameio/projects

Lists workspaces or projects for an account.

Query params:

ParamDescription
accountIdThe Frame.io account ID

GET /api/frameio/assets

Lists children (files and folders) of a given folder.

Query params:

ParamDescription
folderIdThe Frame.io folder/asset ID

POST /api/frameio/import

Imports files from Frame.io into Surflink. Downloads assets, creates a session with clips, and sends each clip to Modal for AI analysis.

Body:

{
  "assets": [{ "id": "asset-id", "name": "clip.mp4" }],
  "sessionTitle": "Morning Session"
}

Limits: Max 10 clips per import, 5-minute timeout.


Surf Conditions

GET /api/surf/forecast

Returns surf conditions for all Barbados spots.

Query params:

ParamDescription
detailIf true, fetches individual spot data (slower, more detailed)
coastFilter by coast (e.g., west, south)
minWaveMinimum wave height filter (feet)

GET /api/surf/spot/[slug]

Returns detailed forecast for a single surf spot.

Query params:

ParamDescription
daysNumber of forecast days (1-6, default 1)

Response includes: wave height/period/direction, wind speed/direction/gusts, surf rating, tide data.


Achievements

POST /api/achievements/check

Evaluates 20+ achievement rules for a student and awards any newly earned badges.

Body:

{
  "studentId": "uuid"
}

POST /api/achievements/seed

Seeds the achievements table with all achievement definitions. Idempotent -- safe to call multiple times.


Notifications

POST /api/notifications/send

Creates a notification record in the database and optionally sends:

  • APNs push to registered iOS/watchOS devices
  • Email via Resend for critical notification types (lesson reminders, achievements)

Body:

{
  "userId": "uuid",
  "type": "lesson_reminder",
  "title": "Lesson Tomorrow",
  "body": "You have a lesson scheduled for 9am at Freights."
}

Invitations

POST /api/invite

Generates an invite token for a student and optionally sends an email invitation via Resend.

Body:

{
  "studentId": "uuid",
  "coachId": "uuid"
}

Returns the invite URL that the student can use to accept and create their account.

POST /api/invite/parent

Generates a parent invite token and optionally sends an email. Tokens are stored in the parent_invite_tokens table with a 7-day expiry.

Body:

{
  "studentId": "uuid",
  "coachId": "uuid",
  "parentEmail": "parent@email.com",
  "parentName": "Jane Doe"
}

Billing (Stripe)

POST /api/stripe/checkout

Creates a Stripe Checkout Session for a coaching package. Automatically creates a Stripe Product and Price if the package doesn't have one yet. Requires authentication.

Body:

{
  "packageId": "uuid",
  "studentId": "uuid"
}

Response: { "url": "https://checkout.stripe.com/..." }

POST /api/stripe/portal

Creates a Stripe Customer Portal session for managing an existing subscription. Requires authentication.

Body:

{
  "subscriptionId": "sub_..."
}

Response: { "url": "https://billing.stripe.com/..." }

POST /api/stripe/webhook

Stripe webhook endpoint. Verifies the webhook signature and processes events:

  • checkout.session.completed -- Creates subscription and payment records
  • customer.subscription.updated -- Updates subscription status and billing period
  • customer.subscription.deleted -- Marks subscription as cancelled
  • invoice.payment_failed -- Marks subscription as past due

Note: This endpoint must be configured in the Stripe Dashboard under Webhooks with the events listed above.