Concepts
API keys and scopes

API keys and scopes

Every community route is authenticated with a community API key and gated on a scope. Each endpoint in the REST API reference lists the scope it requires, taken from the route definition rather than from documentation that could drift. A key holding ADMIN satisfies every scope.

Create keys in the community admin (Integrations → API keys). Community keys start with ck_.

The header

X-API-Key: <your key>

Send the key in the X-API-Key header on every request (Authorization: Bearer <key> is accepted too). The JavaScript client does this for you.

Publishable vs. secret keys

Publishable (ck_…, public)Secret (ck_…, server-only)
Where it livesBrowser bundles. Treat it as public.Your server's environment. Never in a front end.
ScopesREAD_PUBLIC, WRITE_APPLICATIONS, WRITE_CART onlyWhatever was granted to it
Member sign-in (MEMBER_AUTH)Refused (403 SECRET_KEY_REQUIRED)Allowed
Operator writes (approve members, refunds, tier changes, finance reads)Refused, scope or no scopeAllowed with the scope

A publishable key is fetched by an unauthenticated endpoint and ships in browser bundles. It carries READ_PUBLIC, WRITE_APPLICATIONS and WRITE_CART only.

It deliberately does not carry WRITE_MEMBERS. That scope lets the caller name any email in the body, so a browser-exposed key holding it would let anyone record a membership action against any address. A test pins the 403.

Anything marked WRITE_MEMBERS, MEMBERS_ADMIN, ADMIN, APP_*, WRITE_FEED, WRITE_NOTIFICATIONS or READ_FINANCE* is a server-side call. Do not put those keys in a front end. The finance reads enforce this: a publishable key is refused outright, scope or no scope.

On the finance API a publishable key is accepted only on browser buyer flows (checkout, checkout status, the guest order link and receipt, buyer refunds, donations, apply checkout). Host-initiated actions (refund a sale, cancel a member's subscription, change a member's tier) need a secret key and answer 403 SECRET_KEY_REQUIRED otherwise. The default publishable key does not carry WRITE_SALES, so call those buyer flows from your server unless the community granted its publishable key that scope.

A key with an expiresAt in the past is 401 everywhere.

Tenant binding

Every key belongs to exactly one community. The :communityTag in the URL must be that community:

  • A key from another community is 403 WRONG_COMMUNITY.
  • A tag that does not exist is 404. There is no fallback that looks a resource up by id alone, so a guessed tier, form or event id from another community is never served.

Scopes

ScopeUsed by
READ_PUBLICbranding, members, events, articles, products, segment forms
WRITE_APPLICATIONSsegment submit, paid apply checkout
WRITE_CARTthe whole cart surface
MEMBER_AUTHmember sign-in, sign-up and recovery, and every /me route (secret keys only)
WRITE_SALESticket and marketplace checkout, quotes, buyer and host refunds, donations, guest order links
WRITE_SUBSCRIPTIONScancelling a member's paid membership, moving them to another tier
WRITE_MEMBERSapprove / reject an application, rules acceptance by email
MEMBERS_ADMINthe full member roster for admin integrations, including members hidden from the directory (secret keys only; never on publishable keys, never granted to apps)
WRITE_SEGMENTSchanging a membership tier's name, pricing or active status
WRITE_EVENTSthe event bridge (create / update events by key), editing an event
WRITE_ARTICLEScreating, editing, publishing and unpublishing articles
WRITE_BROADCASTSsending an email broadcast
WRITE_FEED · WRITE_NOTIFICATIONSposting to the feed, sending notifications
APP_HANDOFFexchanging a handoff code
APP_MINT_MEMBER_TOKENminting a short-lived member token for a known member
APP_IDENTITY_EMAIL · APP_IDENTITY_PROFILEidentity fields returned by the handoff exchange
APP_ONBOARDINGreading and satisfying a member's onboarding
APP_DATAper-app member key/value storage
APP_IDENTITY_LOCALE_WRITEwriting a member's language
READ_FINANCEthe community's ledger, settlements and totals (secret keys only)
READ_FINANCE_PIIadds buyer identity to those reads; a separate grant on purpose
ADMINwildcard: satisfies every scope above

WRITE_ARTICLES and WRITE_SEGMENTS used to be covered by ADMIN, which is a wildcard: an integration that only needed to publish articles was being handed member management and tier pricing as well. Ask for the narrow scope. Keys already holding ADMIN keep working, since it still satisfies any required scope.

Personal user keys (uk_) are a different credential with one scope, READ_OWN. See Member sessions and user keys.

To filter the reference by what a key can call, use the Key type and Scope filters on the REST API reference.