Authentication
Every request requires a ppk_live_… API key in one of two headers:
X-API-Key: ppk_live_…
or
Authorization: Bearer ppk_live_…
X-API-Key is the preferred form — it’s what onboarding instructs users to copy and what Cowork’s config snippet emits. Authorization: Bearer is supported for backwards compatibility with older integrations.
How it’s enforced
All ProPresence edge functions share a single auth helper (_shared/bearer-api-key-auth.ts) that:
- Looks for
X-API-Keyfirst (case-insensitive). - Falls back to
Authorization: Bearer …if absent. - Looks the key up in
user_api_keyswhereis_active = true. - Rejects if the key is missing, revoked, or past
expires_at. - Updates
last_used_at(fire-and-forget). - Returns the resolved
userIdto the calling function.
Scope enforcement happens after authentication, per endpoint.
CORS
The functions return the standard preflight headers and accept authorization, x-api-key, x-client-info, apikey, content-type.
Errors
| Status | Meaning |
|---|---|
401 |
Missing, malformed, revoked, or expired key |
403 |
Key authenticated but lacks the scope the endpoint requires |
Example
curl https://<project>.supabase.co/functions/v1/articles-api \
-H "X-API-Key: ppk_live_..." \
-H "Content-Type: application/json"
await fetch(`${baseUrl}/articles-api`, {
headers: { 'X-API-Key': process.env.PROPRESENCE_KEY }
});
Related: API keys, Error codes