Server and app platform
App handoff

App handoff

Requires: A secret key with APP_HANDOFF to exchange a code; APP_MINT_MEMBER_TOKEN to mint member tokens.

How an app on its own origin learns who the member is.

Cobuntu's session cookie is host-scoped and httpOnly, so it never reaches another origin and nothing can forward it. An app linked from Cobuntu would otherwise meet every member as a stranger. The handoff closes that: Cobuntu mints a short-lived, single-use code, redirects to the app with it, and the app exchanges it server side for a session.

Use it to sign members into your own web or mobile app via your backend.

Exchange a code

Endpoint: POST /api/v1/apps/handoff/exchange

Scope APP_HANDOFF

Note the path: this one is not under /communities/:tag. The code identifies the community.

const res = await fetch("https://api.cobuntu.com/api/v1/apps/handoff/exchange", {
  method: "POST",
  headers: {
    "X-API-Key": process.env.COBUNTU_API_KEY!,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ code }),
});

Server side only. The code arrives in a URL, so it is already exposed in history, referrers and access logs. It is worth nothing without the API key, and that is the whole reason it is safe to put in a redirect. Putting the key in the browser removes the protection.

The code is single-use and short-lived. Exchange it once, immediately, and store your own session.

Both halves of the handoff

Endpoints:

The two halves of signing a member into an installed app on its own origin.

  1. Mint (/apps/:appKey/handoff) is called by the community app itself, with the signed-in member's own Cobuntu session and no API key. It answers 201 { code, expiresIn: 60 }. Optional PKCE: send { codeChallenge, codeChallengeMethod: "S256" }. Your app receives the code on its redirect URL. You do not call this route from your server.
  2. Exchange (/apps/handoff/exchange, scope APP_HANDOFF) is called by your server with { code, appKey, codeVerifier? }. See Exchange a code above.

Member tokens for apps

Endpoint: POST /apps/mint-member-token

Scope APP_MINT_MEMBER_TOKEN

For an app that already knows a member's userId (from its own handoff exchange) and later needs to act for that member on the member-token routes (attendance status, RSVP, leave) without sending them through a redirect again.

{ "userId": "usr_123" }
{ "token": "eyJhbGciOi...", "expiresInSeconds": 300 }

Send the token as X-Cobuntu-Member-Token. It lives 5 minutes: mint a fresh one per task rather than storing it. Accepted membership is re-checked on every mint, so a member who left stops being mintable at once.

StatusCodeMeaning
400INVALID_INPUTuserId missing.
403SECRET_KEY_REQUIREDCalled with the publishable key.
403NOT_A_MEMBERNot an accepted member of this community.