Kanorio

Get started

Authentication

Which credential each Kanorio API accepts, how permissions are calculated, and how to rotate and revoke tokens safely.

Each Kanorio API is built for a different caller, and each accepts its own credential. Pick the credential by asking who the caller acts for.

CredentialPrefixActs asAccepted byUse it for
Personal access tokenknr_pat_You, limited to the sites and permissions you choseManagement API, MCPYour scripts, the CLI, coding assistants that take a key
Service account tokenknr_sa_The site itself, not a personManagement API, MCPCI, schedulers and partner back ends that must keep running when people leave
OAuth access tokenknr_at_You, through an app you approvedMCP onlyAssistants with built-in connectors, such as Claude or ChatGPT
Preview tokenknr_pv_Read-only access to one site's draftsContent Delivery APIDraft mode in your own front end
Customer tokenknr_cat_One signed-in customer of one siteCustomer API, gated Content Delivery API readsSign-in, purchased content and orders in your front end

The Content Delivery API needs no credential for published content.

Management API

Send the token as a Bearer credential on every request to https://app.kanorio.com/api/v1.

curl https://app.kanorio.com/api/v1/sites \
  -H "Authorization: Bearer knr_pat_..."

Personal access tokens

Create them under Account settings › API access. When you create one you choose:

  • Sites. Specific sites, or all sites including ones you create later. Creating new sites needs all sites.
  • Permissions. A preset (read only, edit content, full access) or individual permissions.
  • Expiry. Tokens always expire. You get an email and an inbox notice before they do.

A token's effective permission on a site is the intersection of what the token allows and what your role on that site allows. A full-access token still cannot edit a site where you are a viewer, and only the site owner can unpublish.

Some permissions are never granted to tokens, whatever preset you pick. These include sending or scheduling newsletters, exporting data, refunds, deleting contacts, and managing members or billing. An agent can draft a newsletter, but a person sends it from the dashboard.

Service accounts

A service account belongs to a site, not to a person. It keeps working when the person who created it leaves the team, and revoking it revokes every token it issued at once.

  1. Open Site settings › Developer and add a service account. You can grant only permissions you have yourself.
  2. Open it and issue a token. Name the token after where it will live, such as "GitHub Actions". The knr_sa_ value is shown once.

Service accounts work inside their own site only. Account-level operations, such as creating sites or listing all your sites, return 403 FORBIDDEN. Each operation in the OpenAPI document lists the callers it accepts in x-kanorio-principals; operations that include SERVICE_ACCOUNT accept service account tokens.

Narrowing a service account's permissions narrows its existing tokens immediately. Widening applies only to tokens issued afterwards.

Scopes

Each operation in the Management API reference shows the permission it needs. The OpenAPI document carries the same value as x-kanorio-required-scope. A token without it gets 403 FORBIDDEN. Call GET /whoami to see what the current token can do.

MCP

The MCP server at https://app.kanorio.com/api/mcp accepts the same personal access and service account tokens, plus OAuth 2.1 access tokens. Assistants with built-in connectors discover the authorization server automatically and ask you to approve access in the browser. OAuth access tokens are bound to the MCP server and are rejected by the REST endpoints. See MCP.

Content Delivery API

Published content is public and edge-cached, so browsers can call it directly.

  • Browser calls from another origin need that origin in Allowed origins under Site settings › Developer. localhost and 127.0.0.1 on any port are always allowed. CORS controls what browsers may read. It is not an authorization boundary, and drafts are never served without a preview token.
  • Draft preview. Create a knr_pv_ preview token in the same settings page, or with POST /sites/{id}/preview-tokens. Send it from your server as X-Kanorio-Preview: knr_pv_.... Preview responses bypass the cache and are never stored.

Customer API

Customers sign in without a password. The site owner chooses which methods are on under Site settings › Customer accounts; the site document's customerAccess.methods lists the enabled ones in display order. Every method ends in the same knr_cat_ session token.

  • Email code (email_code, always on) and magic link (email_link): POST /api/v1/customer/auth/challenge with the email address sends the code. First get the bot check from GET /api/v1/customer/auth/protection: with the built-in check (provider: "kanorio") solve it with solveProtectionChallenge from @kanorio/sdk and send the fields with the request; with the owner's Turnstile, reCAPTCHA or hCaptcha keys, render that widget with siteKey and action and send its token as captchaToken. Then POST /api/v1/customer/auth/verify with { "method": "code", "email", "code" } or { "method": "link", "token" }.
  • Google (google): POST /api/v1/customer/auth/oauth/start with { "method": "google", "baseUrl": <your page's origin> } returns the provider URL; redirect the browser there. Kanorio hosts the consent screen and sends the browser back to baseUrl with ?handoff=. Exchange it within 60 seconds: POST /api/v1/customer/auth/verify with { "method": "handoff", "token" }. If the Google account's email is not verified, the customer gets an email code instead and lands on your page with ?email=&verify=1.
  • Passkeys (passkey): POST /api/v1/customer/auth/passkey/options, run navigator.credentials.get() with the options, then POST /api/v1/customer/auth/passkey/verify with the assertion and challengeId. Signed-in customers manage their passkeys under /api/v1/customer/passkeys. Passkeys are bound to the site's primary domain, so the ceremony must run on that origin.

Handle these responses from POST /api/v1/customer/auth/challenge in your sign-in UI:

CodeWhat to do
429 RATE_LIMITEDWait retryAfter seconds, then let the customer try again
403 BOT_PROTECTION_FAILEDFetch a new challenge (or reset the widget) and resend
503 SERVICE_UNAVAILABLESign-in is briefly unavailable; show a retry
503 SHARED_SENDER_PAUSEDEmail sign-in is paused on this site for now; offer passkeys or Google, or ask the customer to try later

A 200 never reveals whether an email was sent. Kanorio adjusts the bot check with the site's sign-in volume: the challenge from /auth/protection may ask for a visible widget (visible: true) or a harder built-in puzzle, so always render from the challenge you fetched rather than assuming the invisible flow.

Send the token as Authorization: Bearer knr_cat_... on Customer API calls and on gated Content Delivery API reads.

A customer token only ever represents that customer on that site. It cannot read anyone else's data or call the Management API. The <kanorio-login> element runs this flow for you.

Rotate and revoke

  • Rotate a personal access token from its menu. Kanorio issues a new token with the same settings and keeps the old one working for a grace period you choose: none, one hour or one day. Choose none if you suspect a leak.
  • Revoke a token to stop it immediately. The next request with it gets 401 UNAUTHORIZED. Work it already completed is not rolled back.
  • Activity performed with any token appears in the site's activity log under that token's owner, or under the service account's name.

Keep tokens safe

  • Store tokens in environment variables or a secrets manager on the server. Never prefix them with NEXT_PUBLIC_ or ship them in a mobile app.
  • Never paste a token into an AI chat. Real tools read it from configuration.
  • Use one token per tool and one service account per integration, so you can revoke exactly one.
  • Give each token the narrowest sites and permissions that work.