standards
Workspaces and API keysConcepts

Workspaces and API keys

Authenticate every call with one key, and know exactly what that key may read and write.


One Bearer header authenticates everything. The key names its workspace, so no request ever carries a tenant parameter, and the key's roles decide what it may touch. A workspace holds your objects, records, files and people; in the SDK and the API it is called a tenant.

The Authorization header

Send the key as a Bearer token on every request:

curl https://api.standards.new/v1/records/contacts \
  -H "Authorization: Bearer stndrds_your_api_key"

Keys are read from the Authorization header only. A key in a cookie or query string is ignored.

Two refusals cover authentication and authorization:

StatusCodeMeaning
401noneInvalid, expired, or revoked API key. One message for all three cases.
403SCHEMA_FORBIDDENThe key is valid but its roles do not grant the action. The message never names the object or the action.

Creating keys

POST /api-keys creates a key. The caller needs api-keys:create, which the built-in Owner role holds.

curl -X POST https://api.standards.new/v1/api-keys \
  -H "Authorization: Bearer stndrds_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "name": "status-page", "roleId": "role-uuid", "expiresAt": "2027-01-01T00:00:00Z" }'

The plaintext secret is returned once, in this response. Store it in a secrets manager. Afterwards the API exposes the key's metadata only (name, prefix, creation date, last use).

What a key may do is decided at creation:

  • Without roleId, the key inherits every role of the actor that created it. Create a key from an Owner and you get an Owner key.
  • With roleId, the key holds that role and nothing else. This is the shape for automations: one dedicated role per integration, granting only the objects and actions it touches.
  • The permissions array in the body is accepted and ignored. Keys are role-driven only.
  • standards keys create has no role option. A CLI-created key inherits the roles of the key you ran it with. Give it a narrower role from the People area of the app if it needs less.

Personal keys

A key is either a workspace key or a personal key. Passing userProfileId makes it personal, and it may name only your own profile:

  • Only a signed-in user can create a personal key. An API key or an agent owns no profile, so the request is refused with 403 SCHEMA_FORBIDDEN.
  • A personal key acts with its owner's roles, and only its owner can revoke it. No colleague and no administrator can withdraw it.

A workspace key names no profile and is governed by the api-keys permission alone.

Permissions

A permission grants a set of actions on one target, within one of two scopes. On the wire:

{ "scope": "object", "target": "contacts", "actions": ["read", "update"] }

In prose, this documentation writes resource:action, so architect:update means the update action on the architect system resource.

  • object scope is business data. The target is an object name, or * for every object.
  • system scope is the platform itself. The target is one of the thirteen resources below, or * for all of them.

Actions

ActionGrants
readFetching data.
createCreating records or resources.
updateModifying records or resources.
deleteSoft-deleting and restoring.
manageAdministrative operations, such as purging records for good.
observeRead-only visibility on agent session timelines. Only meaningful on the session resource.

Actions are independent, not tiers: manage does not imply read, and delete does not imply update. * in an actions list means the five CRUD actions and never observe.

System resources

ResourceControls
peopleUser profiles, invitations, roles and permissions. people:read unlocks the list_workspace_users MCP tool.
workspaceWorkspace settings, including reading the schema and listing schema sources.
architectChanging the schema. architect:update syncs a schema source; architect:delete removes one.
documentsDocuments, folders and drives.
api-keysCreating, listing and revoking API keys.
connectorsConnected accounts and outbound MCP servers.
env-varsEnvironment variables for agents.
sessionAgent sessions. Pairs with observe.

files, views, forms, feature-flags and audit each control the resource their name says.

Record routes check an object-scope permission on the object they touch: read to list, search and get, create to create, update to update and attach documents, delete to delete and restore, manage to purge. Every other route checks the matching CRUD action on its own system resource.

Built-in roles

Every workspace starts with three roles you will meet:

RoleObject accessSystem access
ownerAll actions on all objects.All actions on all resources.
memberAll actions on all objects.read on people and workspace; read, create, update, delete on connectors, files and documents.
agent_defaultread, create, update, delete on all objects.read, create, update on documents and files; read on env-vars; observe on session.

A Member cannot change the schema, mint keys or administer people. Those stay with Owner unless a custom role grants them. Built-in roles cannot be edited or deleted.

Only an actor that already holds Owner can grant the Owner role. Custom roles, and their assignment to keys and people, are managed from the People area of the app.

Expiry and revocation

  • Expiry: expiresAt is optional. An expired key is refused like an invalid one.
  • Revocation: DELETE /api-keys/:id, or standards keys revoke <id> --yes. The next request with that key gets a 401.
  • The last owner is protected: revoking the only usable Owner credential the workspace has left is refused with 400 SCHEMA_VALIDATION_FAILED, Cannot revoke the last owner role. Assign another owner first.
  • Auditing: each key records when it was last used, so stale keys are easy to spot.

Keys are server-side secrets

Never commit a key or ship it in browser code. The SDK refuses to run with an API key in a browser. Rotate a key you suspect has leaked: create the replacement, switch, then revoke the old one.

Next steps

  • Errors: what a 401, a 403 and every other refusal looks like on each door.
  • SDK: createStandards({ baseUrl, apiKey }) and the server-only rule.
  • MCP OAuth: sign an agent in with scopes instead of a pasted key.
  • CLI: standards login stores a key per instance profile.