REST API
Authentication

Authentication

Every Cobuntu API request authenticates with an API key in the X-API-Key header. There's no OAuth flow yet (planned for v2 — see Versioning below).

curl https://api.cobuntu.com/api/v1/communities/my-community/events \
  -H "X-API-Key: pk_live_..."

Two key types

Per community, you can generate two flavors of keys:

TypePrefixScope capUse from
Publishablepk_live_…READ_PUBLIC onlyBrowser, server, anywhere
Secretsk_live_…Any scope (incl. write + admin)Server only — never ship in browser bundles

Stripe's pk_* / sk_* model, on purpose — the mental model should transfer directly. If you've used Stripe API keys before, you know what to do.

Publishable keys

  • Auto-provisioned per community via GET /api/communities/{tag}/publishable-key (no auth required, the response IS the key).
  • Browser-safe — meant to be embedded in client-side JS, widgets, mobile apps.
  • Capped at READ_PUBLIC scope: list events / articles / products / members / segments, read public details. No write access ever.
  • Rate limit: 100 req/s per key.

Secret keys

  • Generated in cobuntu-admin → Integrations → API Keys (admin permissions required).
  • Server-only. The key is shown once at creation time — store it in a secret manager (Vercel env, AWS Secrets Manager, etc.). If lost, revoke + regenerate.
  • Can carry any scope: READ_PUBLIC, WRITE_MEMBERS, WRITE_SALES, WRITE_BROADCASTS, ADMIN.
  • Pick the narrowest scope set that works for your use case. A webhook receiver that just calls application.approve only needs WRITE_MEMBERS, not ADMIN.
  • Rate limit: 50 req/s per key.

Scopes

Five scopes determine what a key can do:

ScopeGrants
READ_PUBLICList/get public-readable resources: events, articles, products, members, atlas hotspots, segments (the public list + form schema)
WRITE_MEMBERSSubmit segment forms, accept rules, kick/ban members, approve/reject applications
WRITE_SALESRSVP for free events, future checkout flows for paid events
WRITE_BROADCASTSSend one-shot email broadcasts (rate-limited 5 per 24h per community)
ADMINAll of the above + admin-only operations like editing segment pricing

ADMIN satisfies every other scope's check — an admin key can hit any endpoint a narrower key could. Use it sparingly; it bypasses every guardrail.

Key rotation

When (not if) a key leaks:

  1. cobuntu-admin → Integrations → API Keys → Revoke the leaked key. Effective immediately — all subsequent requests with that key return 401.
  2. Generate a new key with the same scopes. Copy it.
  3. Update your secret manager / env vars with the new key.
  4. Redeploy / restart any service holding the old key.

There's no overlap window for rotation — when you revoke, the old key is dead. Plan a deploy with the new key first, then revoke.

Common 401 / 403 mistakes

401 API key required — the X-API-Key header is missing or empty. Some HTTP clients drop custom headers when following redirects; check that.

401 Invalid API key — the key string is wrong (typo, truncated, expired). Compare against what's in cobuntu-admin.

403 API key missing required scope: WRITE_MEMBERS — the key exists and is valid, but doesn't carry the scope this endpoint needs. The response body includes grantedScopes so you can see what the key DOES carry. Either generate a key with the needed scope or use an ADMIN key.

403 API key does not have access to this community — the key belongs to a different community than the URL's :communityTag. Each key is scoped to one community; cross-community calls are blocked.

Buyer identity headers

Some endpoints behave differently when the caller can identify the buyer on whose behalf the request is being made. Member pricing, attendance lookups, buyer self-service (cancel / refund / leave) — all of these need to attribute the action to a specific community member.

The API key alone is not a buyer identity. It's your community-scoped credential; every authenticated buyer hits the same key. To attribute a request to a specific buyer, forward one of two additional headers:

X-Cobuntu-Auth-Token

The value of the cobuntu_auth_<tag> cookie set by Cobuntu's login flow. Use this when your customer apex (belaescala.com, foodieslx.com, etc.) is hosted as a reverse-proxy under Cobuntu's infrastructure and the buyer has logged in through the standard /login round-trip — the cookie sits on the apex host, your server-side code reads document.cookie, and you forward the value as the header.

The backend verifies the JWT and checks for an ACCEPTED membership in the URL's community before trusting it. Without that membership check, an authed member of community A could be silently treated as a buyer on community B's checkout; the bind keeps community boundaries intact.

Silent on failure — invalid / expired / cross-community tokens fall through to anonymous. Member pricing returns null instead of the discount; buyer self-service endpoints return 401.

X-Cobuntu-Member-Token

The SSO-minted member token from Cobuntu's session-bridge handshake. This is the path for fully off-apex integrations (a Lovable / Webflow / Vite SPA hosted on your-own-domain.com with no shared cookie surface). The flow:

  1. Your app calls https://<community-tag>.cobuntu.com/sso/member-check?return=<your-url> when the buyer arrives.
  2. Cobuntu round-trips the buyer through SSO and redirects back with a URL fragment: your-url#cobuntu_session=<token>.
  3. Your client-side code captures the fragment, persists the token in sessionStorage, and forwards it as X-Cobuntu-Member-Token on every authed call until the buyer logs out.

The token's claims include the community id it was minted for — calls against any other community get the silent-anonymous fallback.

Token lifetime is currently 1 hour. Re-handshake when expired (the buyer is bounced through SSO again, fragment captured again).

Bela-escala-hub's cobuntuApi.ts (opens in a new tab) is the canonical reference integration — its captureMemberTokenFromUrl + headers() helper is what every off-apex SPA does in practice.

Which header, when

Integration typeCookie reachable?Use which
Customer apex reverse-proxied through Cobuntuyes (document.cookie)X-Cobuntu-Auth-Token
Customer apex with cobuntu.com SSO subdomainyes (post-login redirect)X-Cobuntu-Auth-Token
Fully off-apex SPA (Vite, Webflow, Lovable)noX-Cobuntu-Member-Token (SSO handshake)
Server-side only (no buyer in the loop)n/aNeither — request is anonymous, member pricing won't apply

You can forward both; the backend tries X-Cobuntu-Auth-Token first, then falls back to X-Cobuntu-Member-Token. Same anonymous-fallback semantics on either failure.

Guest tokens — different mechanism

Guests (email-only, no Cobuntu account) don't have a member identity. For buyer self-service (cancel, refund) on guest attendances, the buyer identifies themselves with a signed MagicLink token that Cobuntu emails them at registration time. See Magic-link tokens for guests in the events reference.

Authorization: Bearer fallback

The legacy Authorization: Bearer <key> header also works, for compatibility with libraries that auto-add it (axios, supertest, some webhook SDKs):

curl https://api.cobuntu.com/api/v1/communities/my-community/events \
  -H "Authorization: Bearer pk_live_..."

Both header names accept the same key. Prefer X-API-Key for new code — it's the documented contract.

Versioning

API keys are forever-stable across /api/v1/*. Even when /api/v2/* ships (a future major version), your v1 keys keep working against v1 indefinitely — both versions coexist for at least 12 months after v2 GA.

Future plans (v2, not landing yet):

  • OAuth 2.0 flow for "Sign in with Cobuntu" + third-party apps
  • Per-user tokens (today's keys are per-community, not per-user)
  • Token introspection endpoint