Authentication
Every API call carries Authorization: Bearer <token>. There are two kinds of token.
API keys (for integrations)
An API key is made in Settings → API keys by a signed-in person. It looks like nsk_AbCdEfGh_ followed by 43 more characters.
- Shown once. The full key appears only when it is created or rotated. We store only a SHA-256 hash of it, so we cannot show it again.
- Acts as you. A key works in the one company it was made in, as the person who made it, with that person's current role. If your role changes, the key's rights change with it. If you leave the company, the key stops working.
- Personal or company. A personal key is seen and managed only by its maker. A company key is made by an owner or CFO, and every owner and CFO of the company can see and revoke it.
- Scopes narrow what the key may do:
| Scope | Allows |
|---|---|
read | every read (GET) your role allows |
write | every read and change your role allows |
read:<area> | reads in one area only, for example read:documents |
write:<area> | reads and changes in one area only |
mcp | the MCP endpoint; each tool it calls is checked again against the other scopes |
The list of areas is returned by GET /api/api-keys/scopes. Areas are the groups of the API reference.
- Never through a key, whatever its scopes: signing in, managing API keys, platform administration, confirming the assistant's prepared actions, and the money steps approve, post and reverse. A person does those in the app.
- Expiry. Every key expires after 1 to 365 days (90 by default).
- Rotation. Rotating gives a new secret with the same name and scopes; the old secret stops working at once.
- Revocation is immediate and permanent.
- Rate limit. Each key has a limit of calls per minute (60 by default, up to 600). Over the limit the API answers
429withRetry-After: 60. - Last used time is shown on the API keys screen.
- Creating, rotating and revoking keys are recorded in the company's activity log.
With a key you may leave out X-Company-Id; the key's company is used. Sending another company's id is refused with 403. Routes that span all of a person's companies (such as the list of your companies) are not available to keys.
curl -H "Authorization: Bearer $ISOERP_KEY" https://nrerp.khanwco.net/api/accounts
Sign-in tokens (for the screens)
The screens sign in with POST /api/auth/signin (or a code, a link, or Google) and receive an access token that lasts 15 minutes and a refresh token that rotates on every use. Calls that act in a company send X-Company-Id; the server checks it against your memberships and reads your role from there. Integrations should use API keys instead.
OAuth
OAuth sign-in for third-party apps and AI connectors is not available yet for this product. Use an API key with the mcp scope for the MCP endpoint.
Errors
Errors always have one shape: {"error": "a sentence a person can read"}. Business refusals are 422, permission 403, not found 404, duplicates 409, an invalid, expired or revoked token 401, too many calls 429.