App handoff
Requires: A secret key with
APP_HANDOFFto exchange a code;APP_MINT_MEMBER_TOKENto 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.
- 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 answers201 { 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. - Exchange (
/apps/handoff/exchange, scopeAPP_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.
| Status | Code | Meaning |
|---|---|---|
400 | INVALID_INPUT | userId missing. |
403 | SECRET_KEY_REQUIRED | Called with the publishable key. |
403 | NOT_A_MEMBER | Not an accepted member of this community. |