How to use the CLI
Install the standards CLI, log in to the hosted API, and script your workspace with JSON, table or CSV output.
The standards CLI (@standards/cli) talks to the Standards API over HTTP. It is the shortest path from a terminal to your records, documents, schema and MCP servers.
Install and log in
npm i -g @standards/cliSave an instance profile, then select it. Omit --key to be prompted for it.
standards login --url https://api.standards.new/v1 --name prod --key stndrds_your_api_keyAlways pass --url for the hosted API
The compiled default URL is http://localhost:4100/v1. Without --url, login stores a profile that points at a local server and every command answers with a connection error.
login validates the key against the API before it saves anything. Confirm the profile is usable:
standards auth whoamiProfiles
Profiles live in ~/.standards/config.json, written with mode 0600. Set STANDARDS_CONFIG_DIR to move the whole directory, for example in CI.
standards instancesstandards use prodstandards currentstandards logout prodlogout without a name removes the active profile.
The environment profile
STANDARDS_API_URL and STANDARDS_API_KEY form a profile of their own. standards instances lists it as sandbox with source: "env". It is active only while no profile is selected in the config file.
STANDARDS_API_URL=https://api.standards.new/v1 STANDARDS_API_KEY=stndrds_ci_key standards records list contactsResolution order
--api-urlor--api-keyon the command line. Either flag bypasses every profile; the other value falls back to the environment, then to the compiled default.--instance <name>, then the profile selected withuse.STANDARDS_API_URL/STANDARDS_API_KEY.- The compiled default URL, with no key.
Global flags
| Flag | Description |
|---|---|
--format <fmt> | json (default), table or csv. |
--api-url <url> | API base URL. Bypasses the profile. |
--api-key <key> | API key. Bypasses the profile. |
--instance <name> | Use a named profile for this call. |
--tenant <id> | The tenant you are authenticated in. A confirmation of intent, not a selector: the API refuses any other value. |
Output formats
json prints the response as-is. table and csv read the first row's keys as columns; a scalar or object response becomes a one-row table. Nested values are serialised as JSON. Table cells are truncated at 50 characters.
standards keys list --format tablerecords list and records search return { data, page }, so the table shows two columns. Pipe the JSON through jq instead:
standards records list contacts --limit 20 | jq .dataRecord saves are acknowledged after the database write. Search indexing runs through durable batches, so a newly saved record can appear in records search shortly after the save response. The CLI has no job producer mode setting.
Exit codes
| Code | Meaning |
|---|---|
0 | Success. For diff, no differences. |
1 | The API refused the request or the command failed. The message reads ✗ Error (status): message, for example ✗ Error (404): Record not found. |
2 | No instance is configured: no profile, no --api-key, no STANDARDS_API_KEY. pull and diff also exit with code 2 on transport or schema errors. |
diff uses exit code 1 to report differences, not a failure. See Schema and bundles.
Every command except login, use, instances, current, logout and help needs a key. Without one the CLI prints ✗ Error: No Standards instance configured and stops with exit code 2.
API keys
standards keys liststandards keys create --name laptop --yes # personal: acts with your access
standards keys create --name ci-bot --workspace --role ci --yes
standards keys detach <keyId> --yes
standards keys revoke <keyId> --yescreate, detach and revoke refuse to run without --yes. create makes a personal key (it acts for the person behind the key you run it with); --workspace makes an integration key that acts with its own roles; --role <name> binds that role instead of member. See Workspaces and API keys.
Tenant invitations
Manage the current tenant's explicit invitation lifecycle. Creating an invitation sends an email; the person becomes a member only after accepting it with their verified identity.
standards invitations list --format tablestandards invitations create --email [email protected] --role <roleId> --yesstandards invitations resend <invitationId>standards invitations revoke <invitationId> --yescreate requires --email and --role (an existing role ID). Both create and revoke require --yes: omitting it prints a message asking you to confirm and exits 1, before any API request. resend sends another email without a confirmation flag, and invalidates the link in the previous email. Use an invitation ID from list for resend and revoke: anything that is not an invitation ID is refused the same way, before any request, so the ID can only ever address its own route segment.
| Command | Required system permission |
|---|---|
list | people:read |
create | people:create |
resend | people:update |
revoke | people:delete |
The API refuses callers without the required permission (SCHEMA_FORBIDDEN). Creating an invitation for an address already in this tenant, including a deactivated member, fails with SCHEMA_DUPLICATE_OBJECT; an unknown role fails with SCHEMA_ROLE_NOT_FOUND. Resending the same invitation twice inside a minute fails with SCHEMA_STATE_GATE: the API allows one resend per minute per invitation. An address already invited and still pending returns its existing invitation unchanged. These commands require the server's tenant invitation capability to be configured. The people permission group is described in Workspaces and API keys.
There is deliberately no invitations accept command: an API key cannot accept on someone else's behalf. Acceptance requires the invitee's verified bearer identity and the invitation proof.
Rebuild record search
If record search misses records or shows outdated ones, rebuild the tenant's record search index:
standards search reindex --tenant <tenantId> --yesThe command requires workspace update permission and --yes: without it, it exits before any API request. It starts a background rebuild and returns when the API accepts it. The new index is built beside the current one, which keeps answering searches, and replaces it in one step once every record is in it. Records saved during the rebuild are included. Nothing is cleared first. If a rebuild is already running for the tenant, the API refuses a second one (HTTP 409).
Reindex email search
If existing email messages are missing from search, hand the tenant's stored messages back to the email indexer:
standards search reindex --emails --tenant <tenantId>The command requires workspace update permission. It starts a background job and returns when the API accepts it; follow the server logs for completion or failure. The job writes nothing to the email search index itself: it hands every stored message back to the email indexer, which a worker process runs and which delivers them in the background. Messages already waiting or in delivery keep their place. The job does not clear the index or alter the records search index.
The logs report how many messages were handed back and the last email ID processed. If the job fails, resume after that ID with --after-id:
standards search reindex --emails --tenant <tenantId> --after-id <last completed id>Omit --after-id to start at the beginning. --after-id only applies to an email reindex: without --emails the command refuses it before any API request. The same resume is available directly as POST /admin/search/email-reindex with { "tenantId": "<tenantId>", "afterId": "<last completed id>" }. Use the tenant you are authenticated in; the API rejects a different tenant.
Messages reappear in email search as the indexer delivers them; until it has delivered them all, email search is incomplete.
To rebuild the email search index itself from the stored messages, add --rebuild and --yes:
standards search reindex --emails --rebuild --tenant <tenantId> --yesThe new index is built beside the current one, which keeps answering searches, and replaces it in one step once every stored message is in it. Messages received meanwhile appear a few minutes late. Without --yes the command exits before any API request, and --rebuild refuses --after-id. The same rebuild is POST /admin/search/email-reindex with { "tenantId": "<tenantId>", "rebuild": true }. The rebuild only recovers a mail index that is not built or whose indexer stopped on an uncertain write: on a healthy one the API refuses it (HTTP 409), as it does while a rebuild is running for the tenant.
Recompute meeting grants
Private meetings are shared with the members their calendar invite names. Each workspace recomputes these shares once, in the background, after the deploy that introduced them. To run the recompute again, as a retry or a repair:
standards --tenant <tenantId> meetings grants-recomputeThe command requires the settings update permission and refuses to run without --tenant, before any request. It starts a background job and returns when the API accepts it (202); the job is idempotent and deletes nothing. Use the tenant you are authenticated in; the API rejects a different tenant. A server without a calendar service answers 404. A server with a calendar but without the meeting attendee tables answers 503 with CONFIGURATION_REQUIRED. The shares themselves are described in Record access.
Backfill agent memory
Agent memory is rebuilt from evidence. To feed it the workspace's last 30 days of conversations and meeting transcripts:
standards --tenant <tenantId> memory backfill --yesThe command requires the settings update permission, and refuses to run without --tenant or without --yes, before any request. It starts a background job and returns when the API accepts it (202); follow the server logs for progress. Sources are read oldest first and pass the same checks as live evidence: a one-message conversation that asks nothing to be remembered, or a meeting with no linked record, adds nothing. Memory records cannot be written through standards records; see Skills and memories. Each source is read once, however often the command runs. The job stops at 200 memory passes or 2,000,000 model tokens for the workspace; running it again resumes where it stopped. The same job is available directly as POST /admin/memory/backfill with { "tenantId": "<tenantId>" }. Use the tenant you are authenticated in; the API rejects a different tenant.
Shell pitfalls
- Single-quote JSON so the shell keeps the double quotes:
--data '{"name":"Alice"}'. --filtertakes the raw filter tree as JSON, exactly as the API expects it.--sorttakes one rule,attribute:direction. Pass it once.--fields ""hydrates no reference attribute. Omit the flag to hydrate all of them.- Wrap
--queryin quotes when it contains spaces.
Next steps
- Records: list, search, create, update, attach a file and share a private record.
- Documents and files: manage packs and read OCR text.
- Schema and bundles: inspect the deployed schema and sync its bundles.
- MCP servers: connect outbound servers from a terminal.
- Device fleet: enroll a machine your agents run commands on, with the
standards-deviceworker. - Usage and limits:
standards ai usage,standards ai walletandstandards quotas list. - Book a demo
Connectors
List configured providers and workspace connections:
standards connectors providers
standards connectors listStart authorization with standards connectors connect --provider github and open the returned URL. Supported provider IDs are github, slack, gmail, outlook, google-calendar and outlook-calendar; availability depends on the instance configuration shown by connectors providers. A mailbox or calendar provider first prints what the connection allows and refuses to run, before any request, until you add --yes: see Connected mailboxes and calendars.
Disconnect a connection with --yes; the command refuses to run without it, before any request:
standards connectors disconnect <connectionId> --yes
standards connectors disconnect <connectionId> --yes --remove-importedBy default the mail and meetings a mailbox or calendar connection imported stay. With --remove-imported they are deleted too, for everyone, the owner included. Only the owner of a personal connection can ask it: on a connection made for the whole workspace, what it imported is the workspace's shared history, and the API refuses it (403, SCHEMA_WORKSPACE_INVARIANT) with nothing deleted. A GitHub or Slack connection imports neither, so the flag changes nothing there. What is kept and what goes is described in Record access.
Connected mailboxes and calendars
How to connect Gmail, Outlook, Google Calendar or Outlook Calendar, what Standards reads, what each access level allows, and how to change it, disconnect and delete what was synced.
Records
Read, search, write, move and delete records of any object, and attach a local file to one of them, from a terminal.