Authentication

JWT-based authentication, securing your requests, and rate limits.

Overview

The Foil Engine API uses JWT Bearer tokens issued by Supabase for authentication. Some endpoints require authentication (creating, saving, deleting personas), while others are publicly accessible (browsing public personas, chatting with published characters).

Note
You can obtain a JWT token by authenticating through Supabase Auth. The token should be included in the Authorization header of every authenticated request.

Authentication Header

Include your JWT token as a Bearer token in the Authorization header:

Authorization: Bearer <your_jwt_token>

Requests to protected endpoints without a valid token will return a 401 Unauthorized response.

Auth Endpoints

GET /api/v1/auth/me

Returns the currently authenticated user. Requires auth.

FieldTypeDescription
idstringUnique user ID (UUID)
emailstringUser's email address
display_namestringUser's display name

Example request:

curl /api/v1/auth/me \
  -H "Authorization: Bearer <your_jwt_token>"

Example response:

{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "email": "developer@example.com",
  "display_name": "Dev User"
}

POST /api/v1/auth/migrate-progress

Migrates anonymous play progress to the authenticated user's account. Call this after a user signs in to preserve any chat history or scores accumulated before authentication. Requires auth.

Example request:

curl -X POST /api/v1/auth/migrate-progress \
  -H "Authorization: Bearer <your_jwt_token>"

Game SDK Authentication

For game integrations, the Game SDK uses API key authentication instead of JWT tokens. Include your key in the X-API-Key header:

X-API-Key: pk_live_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6

API keys are scoped to your account and can only access your own published personas. Create and manage keys from the API Keys dashboard or via the POST /api/v1/sdk/api-keys endpoint (requires JWT auth).

Which Endpoints Require Auth?

ActionAuth Required
Browse public personasNo
Chat with published personas (web)No
Chat via Game SDKAPI Key
List your own personasJWT
Create / save a personaJWT
Publish a personaJWT
Delete a personaJWT
Manage API keysJWT

Rate Limits

Rate limits are applied per IP address. When a limit is exceeded, the API returns a 429 Too Many Requests response with a Retry-After header indicating seconds until the next request can be made.

CategoryLimitScope
Generation (AI content creation)10 requests / minutePer IP
Chat (sending messages)60 requests / minutePer IP
General (all other endpoints)120 requests / minutePer IP
SDK Chat (sending messages)30 requests / minutePer API key
SDK General (init, history, reset)60 requests / minutePer API key

Example rate-limited response:

HTTP/1.1 429 Too Many Requests
Retry-After: 12

{
  "error": "Rate limit exceeded. Try again in 12 seconds."
}