Build with Dots
Connect your app to Dots.
Sign-in, notes, files, and context that follow the user. Choose what your app does to see the credentials, permissions, and code you need.
01 / Install code
An SDK is optional.
npm install gives you a library. You can also use OAuth and HTTP directly.
02 / Register your app
A client ID identifies it.
Public apps use PKCE. Apps with a confidential server exchange also use a server secret.
03 / Ask the user
A token grants access.
The user signs in and consents to scopes. Installing a package never grants data access.
What are you building?
Your setup
Client ID · no secret
Register a public OAuth client. Use Authorization Code + PKCE S256 in the browser.
Optional: npm install @wrldbld/dots@0.1.0-alpha.0. You can also use an OAuth library and HTTP.
Request these scopes
openid profileEnable them on the client, then request user consent. Registration alone grants no access.
Access-token resource
https://www.dots.id/apiAn app calling both surfaces requests both resources during OAuth. The published browser SDK defaults to API access.
Browser app setup example
npm install @wrldbld/dots@0.1.0-alpha.0
// Run in browser code. Register redirectUri before sign-in.
import { createDots } from "@wrldbld/dots";
const issuer = "https://www.dots.id";
export const dots = createDots({
issuer,
apiKey: "YOUR_PUBLIC_CLIENT_ID", // legacy SDK name for the public client_id
redirectUri: "https://your-app.example/dots/callback",
scopes: ["openid","profile"],
storage: window.sessionStorage,
transactionStorage: window.sessionStorage,
});
// Bind this to the sign-in button.
export async function signIn() {
await dots.signIn();
}
// Call once on the callback page and display any error.
export async function finishSignIn() {
await dots.handleCallback(window.location.href);
const accessToken = await dots.getAccessToken();
if (!accessToken) throw new Error("Sign in again");
const response = await fetch(issuer + "/api/oauth/userinfo", {
headers: { Authorization: "Bearer " + accessToken },
});
if (!response.ok) throw new Error("Dots userinfo failed: " + response.status);
const userinfo = await response.json();
// Account key: (issuer, userinfo.sub).
// A backend must verify identity itself; never trust a browser-supplied sub.
return userinfo;
}
export async function signOut() {
await dots.signOut();
}The browser example shows separate sign-in, callback, and sign-out handlers. Run the callback once, handle failures, and initialize only in browser code. sessionStorage is accessible to JavaScript; use a server session with HttpOnly cookies when your app has a backend.
Package versions & the newer core SDK
Verified September 11, 2026: @wrldbld/dots@0.1.0-alpha.0 is published. It exports createDots({ apiKey }). It has no /react export. @wrldbld/dots-core@0.2.0-alpha.0 and the matching dots-cli are local release candidates. The core uses createDotsClient({ clientId, storage, transactionStorage }) and supports public clients. These APIs are different.
Use HTTP for newer notes/grants APIs, or build and pack the core from an existing trusted Dots checkout. The agent guide includes those commands. Check the exact package version before relying on a future npm release.
Register once. Configure each environment.
- Open your OAuth clients. Reuse the app's existing registration or create one. Select its client type, platform, framework, callbacks, and allowed scopes.
- Copy the public
client_id. Confidential apps also get aclient_secret, shown once, for server environment variables. Neither value replaces the user's access token. - Register the exact callback for production and development. Locally, use the full HTTPS origin emitted by Portless, including its proxy port. HTTP subdomains such as
my-app.localhostare not currently accepted callbacks. - Download the client's install spec from its dashboard for the exact configuration and Expo example. This owner-only file is available at
/api/oauth/clients/{clientId}/llms-install.txt.
Agents can register a public client through /api/oauth/register, registerDotsApp(), or dots app register in the published SDK/CLI alpha release. Check missingScopes and save the client ID. Unowned dynamic registrations cannot be edited in your dashboard; create an owned client there when you need restricted scopes or ongoing management. Device-only registrations need no callback. Dots' service credentials stay with Dots.
For agents
One guide for building and querying.
Give your agent the install guide before it edits your app. The reusable skill explains how to choose credentials, map functions to scopes, connect MCP, and verify the integration.
Connected MCP hosts can read dots://docs/install through resources/list and resources/read. Hosts that do not expose resources can read /install/llms.txt over HTTPS. Save the skill in your agent's supported skill directory as dots-integrate/SKILL.md; connecting MCP does not automatically install it.
Check the integration.
- Sign in, validate the callback state, and exchange the code once with the original PKCE verifier. If consuming ID tokens, validate signature via JWKS, issuer, client audience, expiry, and nonce using an OIDC library.
- Call userinfo with the access token, then bootstrap for context. Store accounts by the immutable (issuer, sub), with a unique constraint. Never merge by email, wallet, or username.
- Verify the returned scope includes each feature's permissions. Client registration sets a ceiling; the user still has to consent. Handle 401 by refreshing or reconnecting, and 403 by checking scopes and grants.
- Confirm context:read cannot retrieve another app's private context. Test cross-app reads only with explicit context:read:all consent and shared notes only after grant acceptance.
- If offline_access was requested, refresh and save the rotated token. Sign out, revoke server tokens, clear local state, and confirm protected access fails.