API Reference

REST API endpoints and integration patterns.

Overview

The LokkoLabs API uses Next.js API routes with a consistent response format. Authentication varies by endpoint type.

Base URL

https://lokkolabs.com/api

Response Format

// Success
{
  "success": true,
  "data": { ... }
}

// Error
{
  "success": false,
  "error": "Error message"
}

Authentication

Two authentication modes are used:

Session Auth

For organizers, admins, and company members. Uses Supabase Auth cookies.

Cookie: sb-xxx-auth-token

Event Code

For attendee-facing endpoints. Event code in URL path.

/api/events/{code}/...

Event Endpoints

Get Event by Code

GET/api/events/{code}

Get event details by access code. Public endpoint for attendees.

Response:
{
  "success": true,
  "data": {
    "id": "uuid",
    "code": "FALCON-42",
    "name": "Team Building Event",
    "phase": "training",
    "startedAt": "2024-01-15T10:00:00Z"
  }
}

Join Event

POST/api/events/{code}/join

Register as an attendee for an event.

Request:
{
  "name": "John Smith",
  "email": "john@example.com",
  "experienceLevel": "beginner"
}
Response:
{
  "success": true,
  "data": {
    "attendeeId": "uuid",
    "codename": "Shadow Falcon",
    "agentNumber": 42,
    "coverJob": "Artisanal Cheese Whisperer",
    "teamColor": "red",
    "teamTable": 1
  }
}

Get Attendee State

GET/api/events/{code}/attendees/{id}

Get current attendee state including phase progress.

Response:
{
  "success": true,
  "data": {
    "id": "uuid",
    "phaseStatus": "training",
    "progress": 0.65,
    "teamId": "uuid",
    "lastActivityAt": "2024-01-15T10:30:00Z"
  }
}

Submit Help Request

POST/api/events/{code}/help-request

Submit a help request from an attendee.

Request:
{
  "attendeeId": "uuid",
  "message": "Lock is stuck"
}

Organizer Endpoints

Require organizer role or higher.

Advance Phase

POST/api/organizer/events/{id}/phase

Advance the event to the next phase.

Request:
{
  "targetPhase": "training"
}

Record Team Completion

POST/api/organizer/events/{id}/teams/{teamId}/complete

Record a team's mission completion time.

Request:
{
  "completionTime": 127.5
}

Get Event Dashboard

GET/api/organizer/events/{id}/dashboard

Get comprehensive event state for control center.

Response includes:
  • • Event details and current phase
  • • All teams with attendee lists
  • • Pending help requests
  • • Phase timing information

Admin Endpoints

Require admin role or higher.

Generate Audio

POST/api/admin/audio/generate

Generate TTS audio for scripts.

Request:
{
  "scripts": ["briefing-intro", "training-start"],
  "generateSegments": true
}

Create Company

POST/api/admin/companies

Create a new company.

Request:
{
  "name": "Acme Corp",
  "slug": "acme-corp",
  "ownerEmail": "owner@acme.com"
}

Content Endpoints

Get Phase Content

GET/api/events/{code}/content/{phase}

Get content segments for a phase.

Response:
{
  "success": true,
  "data": {
    "segments": [
      {
        "id": "uuid",
        "type": "intro",
        "title": "Welcome to Training",
        "audio": {
          "url": "https://...",
          "duration": 45.2,
          "pauseAfter": 3
        }
      }
    ]
  }
}

Real-Time Events

Real-time updates use Supabase Realtime channels:

EventChannelPayload
phase_changeevent:{code}newPhase, timestamp
team_completeevent:{code}teamId, completionTime, rank
help_requestorganizer:{eventId}attendeeId, message, team
audio_playevent:{code}clipId, timestamp

Subscribing

const channel = supabase
  .channel(`event:${eventCode}`)
  .on('broadcast', { event: 'phase_change' }, (payload) => {
    setCurrentPhase(payload.newPhase);
  })
  .subscribe();

// Cleanup
return () => {
  supabase.removeChannel(channel);
};

Error Codes

StatusErrorMeaning
400INVALID_REQUESTMissing or invalid parameters
401UNAUTHORIZEDNot authenticated
403FORBIDDENInsufficient permissions
404NOT_FOUNDResource doesn't exist
409CONFLICTState conflict (e.g., already joined)
500SERVER_ERRORInternal server error

Rate Limits

API endpoints have rate limits to prevent abuse:

Endpoint TypeLimitWindow
Public (event join)10 requestsper minute
Authenticated100 requestsper minute
Audio generation50 requestsper hour

Next Steps