nemi / developers / v1

Sign in with
Nemi.

OAuth 2.1 and OpenID Connect for the account people already use for their files, photos and documents. Then one REST API for exactly the parts they agree to.

fig. 1 sign in with nemi01 / 08
Your appNemiThe personGET /oauth/authorize01consent screen02Allow03302 ?code&state&iss04POST /api/oauth/token05200 tokens06GET /api/v1/me07200 { sub, name }08

Your app to Nemi

Your app sends the person to Nemi

GET https://nemilab.com/oauth/authorize
  ?client_id=nemi_app_8Fq2...
  &redirect_uri=https://acme.app/callback
  &scope=openid profile docs.read
  &state=k9Xw...  &nonce=Q2ra...
  &code_challenge=E9Mel...  (S256)
web, node, reactnpm i @guuslab/nemi
react nativenpm i @guuslab/nemi-react-native
ios, androidswift package, jitpack

02One API, every app in the account.

Base nemilab.com/api/v1, a bearer token, JSON in and out. Each path answers only for the scopes the person granted, inside their own role.

api reference
fig. 2 /api/v1
/mewho signed inopenid profile email
/workspacesand their role in eachany data scope
/filesbrowse, download, uploadfiles.read files.write
/gallery/photosphotos and albumsgallery.read gallery.write
/docsdocuments as Markdowndocs.read docs.write
/sheetscells, A1 keyedsheets.read sheets.write
/formsquestions and responsesforms.read forms.write
/canvasboards as datacanvas.read canvas.write
/calendar/eventscalendars made in Nemicalendar.read calendar.write

03Secure by default, not by configuration.

The careful choices are made on the server, so an app cannot get them wrong. Every token is checked again on every call: a suspended app stops on the next request.

security notes
fig. 3 spec sheet
pkceS256, required for every app
authorization code60 s, single use
access token1 h, nemi_oat_
refresh token90 d, rotates on every use
refresh reuseends the whole login
id tokenES256, nonce and at_hash
user idpairwise per developer
secretsSHA-256, shown once
rate limit600 / min per app per person
reachthe person's own role, never their Vault

04Every platform, the same few lines.

Official SDKs do PKCE, token storage and refresh. Or skip them: it is standard OAuth and OpenID Connect, and any library that speaks it works.

fig. 4 sign in
app.tsx
import { NemiAuth } from "@guuslab/nemi";
import { NemiProvider, SignInWithNemiButton, useNemi } from "@guuslab/nemi/react";

const auth = new NemiAuth({ clientId: "nemi_app_..." });

export function App() {
  return (
    <NemiProvider auth={auth} scopes={["openid", "profile", "gallery.read"]}>
      <Home />
    </NemiProvider>
  );
}

function Home() {
  const { user, client } = useNemi();
  if (!user) return <SignInWithNemiButton />;
  return <p>Hi {user.name}</p>;
}

05Packages.

WebRedirect or popup
npm i @guuslab/nemi
NodeServers, Deno, Bun, Workers
npm i @guuslab/nemi
ReactNemiProvider and useNemi
npm i @guuslab/nemi
React NativeiOS and Android
npm i @guuslab/nemi-react-native
SwiftiOS and macOS, via SPM
https://github.com/GuusLab/nemi-swift
KotlinAndroid, via JitPack
com.github.GuusLab:nemi-android:0.1.1
for agents

Building with an AI agent? The docs download as Markdown with an AGENTS.md and llms.txt, ready for Claude Code, Cursor or Codex.

open the docs

Your first sign-in is
ten minutes away.