monoesdocs
Menu

Quickstart

Add "Connect to monoes" to your site

A worked example in JavaScript. See Authentication for the full flow reference.

1. Register your client once

register-client.js
const res = await fetch("https://monoes.me/api/auth/oauth2/register", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    redirect_uris: ["https://your-app.example/callback"],
    token_endpoint_auth_method: "none",
    grant_types: ["authorization_code", "refresh_token"],
  }),
});
const { client_id } = await res.json();
// Save client_id — you only need to do this once per app.

2. Build the "Connect" link

Generate a PKCE code verifier/challenge pair, stash the verifier (session, cookie), and send the user to the authorize URL.

connect-button.js
function base64url(buffer) {
  return btoa(String.fromCharCode(...new Uint8Array(buffer)))
    .replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
}

const verifier = base64url(crypto.getRandomValues(new Uint8Array(32)));
const challenge = base64url(
  await crypto.subtle.digest("SHA-256", new TextEncoder().encode(verifier))
);
sessionStorage.setItem("pkce_verifier", verifier);

const url = new URL("https://monoes.me/api/auth/oauth2/authorize");
url.searchParams.set("client_id", CLIENT_ID);
url.searchParams.set("redirect_uri", "https://your-app.example/callback");
url.searchParams.set("response_type", "code");
url.searchParams.set("scope", "community:read community:write offline_access");
url.searchParams.set("code_challenge", challenge);
url.searchParams.set("code_challenge_method", "S256");

window.location.href = url.toString();

3. Handle the callback

callback.js
const code = new URL(window.location.href).searchParams.get("code");
const verifier = sessionStorage.getItem("pkce_verifier");

const res = await fetch("https://monoes.me/api/auth/oauth2/token", {
  method: "POST",
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
  body: new URLSearchParams({
    grant_type: "authorization_code",
    code,
    redirect_uri: "https://your-app.example/callback",
    client_id: CLIENT_ID,
    code_verifier: verifier,
  }),
});
const { access_token, refresh_token } = await res.json();
// refresh_token is only present because the authorize URL above requested
// the offline_access scope — omit it and this field comes back undefined.
// Store access_token server-side, tied to your own user session.
// It's a bearer credential — treat it like a password.

4. Call the API

whoami.js
const me = await fetch("https://monoes.me/api/community/me", {
  headers: { Authorization: `Bearer ${access_token}` },
}).then((r) => r.json());

// { id, username, name, avatarUrl }

No browser available? See the headless agent flow instead. Full endpoint list: API reference.