Skip to main content

API Authentication

All authenticated API endpoints expect a Supabase JWT in the Authorization header.

Obtaining a Token

Tokens are obtained through Supabase Auth on the frontend. The supabase.ts library provides helper functions:

import { supabase, getAuthHeaders } from '../lib/supabase';

// Get the current session
const { data: { session } } = await supabase.auth.getSession();
const token = session?.access_token;

// Or use the helper
const headers = await getAuthHeaders();
// Returns: { Authorization: 'Bearer <token>', 'Content-Type': 'application/json' }

Making Authenticated Requests

const response = await fetch('/api/generate', {
method: 'POST',
headers: await getAuthHeaders(),
body: JSON.stringify({ prompt: 'Create a tabbed email...' }),
});

Auth Levels

User Auth (verifyUser)

Any logged-in user with a valid JWT passes. Used for:

  • Email generation
  • Email sending
  • AMP validation
  • Delivery status checks

Admin Auth (verifyAdmin)

Valid JWT + email must be in the admin_users table. Used for:

  • RAG content management
  • QA evaluations
  • System statistics

Token Gating (spendTokensServer)

After user auth passes, premium actions also require sufficient token balance. The server calls the spend_tokens RPC function atomically.

Error Responses

401 — Invalid or Missing Token

{
"error": "Authentication required"
}

403 — Not an Admin

{
"error": "Forbidden: admin access required"
}

402 — Insufficient Tokens

{
"error": "Insufficient tokens",
"message": "Not enough tokens for this action"
}