Developer docs

A Clavocial plugin is a web page you host on your own domain, shown in a sandboxed strip inside the keyboard. It can sign users in with the Clavocial account they already have — so they never make a second account to use what they bought.

Quickstart

  1. Create a developer account in the console (magic link — no password).
  2. Complete your profile. Your name and policy links appear on the consent screen, so they're required.
  3. Verify your domain by publishing a token at /.well-known/clavocial-verification.txt.
  4. Create an app to get a client_id and a client secret (shown once).
  5. Build your plugin page and submit it — it's AI-scanned before listing.

Where plugins live

You host your plugin, on your own domain. Clavocial never serves your code or content. We host only the registry entry that points at you. That means you control releases, your own CDN and caching, and your own backend — and your users' content requests go to you, not us.

Your domain's own Content-Security-Policy applies inside the keyboard. If yours restricts style-src, add your nonce to your inline styles — we won't ask you to weaken your policy.

Plugin manifest

Submitted to POST /plugins/register. Entry-point URLs must be HTTPS on your verified domain.

{
  "pluginId": "yourco-thing",
  "name": "Your Thing",
  "category": "education",
  "description": "What it does, in a sentence.",
  "icon": "https://yourdomain.com/icon.png",
  "publisher": { "name": "Your Co", "domain": "yourdomain.com" },
  "compute": "device",
  "permissions": [],
  "ssoClientId": "cl_...",
  "entryPoints": [
    { "type": "grid-action", "label": "Open", "url": "https://yourdomain.com/plugin/index.html" }
  ],
  "price": { "amount": 499, "currency": "USD", "type": "one-time" },
  "version": "1.0.0"
}

Categories: social, ai-assistant, dictionary, education, game, security, shopping, productivity, other. Entry types: grid-action, compose-addon, text-transform, assistant.

Sign in with Clavocial

Standard OpenID Connect (Authorization Code + PKCE, RS256), so use any OIDC library. Discovery lives at /.well-known/openid-configuration.

SSO modes

autoAfter the first consent, the user is signed in silently on later opens. Best when your plugin needs identity to show anything — e.g. paid content that should just play.
manualNothing happens until the user taps "Sign in with Clavocial".
optionalYou offer Clavocial alongside your own login.

auto never means "no consent" — it means "don't ask again after the first yes."

Scopes

openidA stable pairwise sub. Two publishers can't correlate the same user.
emailemail, email_verified
profilename
entitlementsWhich of your plugins the user owns — so you can gate paid content without running billing.

OIDC reference

GET  /.well-known/openid-configuration
GET  /oauth/jwks                 verify our tokens yourself
POST /oauth/authorize            consent decision or a code
POST /oauth/consent
POST /oauth/token                code -> id_token + access_token (+ refresh)
GET  /oauth/userinfo
POST /oauth/revoke
POST /oauth/logout

An id_token

{
  "iss": "https://clavocial.com",
  "sub": "<pairwise id>",
  "aud": "cl_...",
  "email": "user@example.com",
  "entitlements": ["yourco-thing"],
  "sid": "<session id>",
  "nonce": "...", "iat": 0, "exp": 0
}

Plugin runtime API

Inside the keyboard your page gets exactly one host API. There is no bridge to typed text, the clipboard, or the user's languages — by design.

const auth = await window.CPlugin.signIn({
  clientId: 'cl_...',
  scope: 'openid email entitlements',
});
// { idToken, accessToken, sub, email, entitlements }

window.CPlugin.onSignOut(() => {
  // the Clavocial session ended - drop local state
});

The host runs the OIDC flow and shows consent, so your page never sees the user's Clavocial session — only tokens minted for your client_id. Outside the keyboard window.CPlugin is undefined; fall back to your own sign-in.

Sign-out

When a user signs out of Clavocial we revoke every token from that session and POST a signed logout_token to your registered back-channel logout URI, so you can end your own session server-side. Register it when you create the app.

POST https://yourdomain.com/sso/logout
Content-Type: application/x-www-form-urlencoded

logout_token=<signed JWT: aud=your client_id, sid, backchannel-logout event>

Verify it against our JWKS, then kill the session for that sid.

Security rules

Open the console