Authentication
How to authenticate API requests with a PlayaOS API key.
API Keys
All API requests must include a Bearer token in the Authorization header:
Authorization: Bearer pk_live_YOUR_KEYAPI keys are camp-scoped — a key from Camp A cannot access Camp B's data. Each key is also scope-limited to only the resources you explicitly grant at creation time.
Member tokens
An API key identifies the camp, not a person, so on its own it cannot tell the API which member is asking. Endpoints that return a single member's own data — dues, payments, application, shelter assignment, tickets, vehicle passes, scholarships, onboarding progress, check-ins, referrals, notifications, shift signup, and the full profile at GET /members/{id} — also require the acting member's PlayaOS session JWT:
Authorization: Bearer pk_live_YOUR_KEY
X-PlayaOS-Member-Token: <the member's session JWT from auth.playaos.app>The API verifies the JWT, takes the org from the key, and resolves the member's profile in that org. Then:
| Caller | Behaviour |
|---|---|
| No member token | 401 AUTH_REQUIRED — the unscoped call fails rather than returning the whole camp |
| Token does not verify | 401 AUTH_REQUIRED |
| Verified, but no profile in this camp | 403 FORBIDDEN |
member / applicant | Pinned to their own records; naming another member is 403, a foreign row id is 404 |
admin / super_admin | May pass any member id, or none to see the whole camp |
Endpoints that act on one member (/members/{id}, /members/{memberId}/shelter, /members/{memberId}/tags, POST /payments/page, shift/shelter/bike assignment, check-in, referral) accept me as the id, and a non-admin may omit the memberId body field altogether — both mean the acting member. An admin must name the member (omitting it is 400). So a member-facing app never needs to know its user's PlayaOS profile id: GET /members/me returns it.
Org-level endpoints (the schedule, documents, contacts, reports, settings, …) do not require the header, and machine integrations — cron, webhooks, admin batch jobs — keep using the key alone on them. A header that is sent must still verify, though: an expired or invalid token is 401 on any route that installs the member middleware, whether or not that route is member-scoped. Send a valid token or none.
Generating a Key
- Log into the PlayaOS platform console at
https://app.playaos.app - Open your org and navigate to Developer → API Keys
- Click New Key, enter a description, and select the scopes you need
- Copy the key — it's only shown once
REST API keys use pk_live_* with 48 hex characters. The separate public camp keys used by embeds also start with pk_live_*, with 32 hex characters; select the key by its purpose, not its prefix. Do not use an embed key for the REST API.
Security Best Practices
API keys grant access to real camp data. Treat them like passwords.
- Never commit keys to source control — use environment variables
- Use the minimum scopes required for your use case
- Rotate keys if they may have been exposed
- Set a description so you can identify and revoke keys later
Revoking a Key
On your org's Developer → API Keys page, click the trash icon next to any key to revoke it immediately. Requests using that key will return 401 Unauthorized.
Error Responses
| Status | Code | Meaning |
|---|---|---|
401 | AUTH_REQUIRED | Key is missing, malformed, or revoked |
403 | FORBIDDEN | Key exists but lacks the required scope, or a non-admin member named another member |