# spectron

Reference for surrealctl spectron — managing Spectron contexts, API keys, scoped keys, access tokens, principals and grants, packages, and the scope and provider catalogues.

`surrealctl spectron` manages [Spectron](/docs/spectron.md): contexts, the API keys and access tokens that reach them, and the principals and grants that decide what those credentials may do.

<Synopsis>
surrealctl spectron <COMMAND> [OPTIONS]
</Synopsis>

| Sub-command | Purpose |
| --- | --- |
| [`context`](#spectron-context-list) | Manage Spectron contexts |
| [`key`](#spectron-key-list) | Manage a context's API keys |
| [`scoped-key`](#spectron-scoped-key-create) | Mint keys attenuated below a principal |
| [`access-token`](#spectron-access-token-create) | Mint short-lived access tokens |
| [`principal`](#spectron-principal-list) | Manage principals and their grants |
| [`package`](#spectron-package-list) | Manage context packages |
| [`scopes`](#spectron-scopes) | List a context's scope tree |
| [`verbs`](#spectron-verbs) | List the verbs a grant can name |
| [`providers`](#spectron-providers) | List the model providers a context can use |
| [`usage`](#spectron-usage) | Show a context's token usage |
| [`config`](#spectron-config) | Show a context's configuration |

> [!NOTE]
> Every route in this group answers `501` on a deployment that does not have Spectron. That is reported as `not_available` and exits `9` — deliberately not a failure, because nothing is broken. It cannot be predicted locally, so the first Spectron command you run is how you find out.

## Naming a context

Every context-scoped route needs both an organisation and a context, and no route accepts a context by name — contexts have no slug, so a name costs one lookup. Commands whose noun lives *inside* a context take `--context <REF>`; the [`spectron context`](#spectron-context-list) verbs take a positional instead.

The inference chain is deliberately shorter than the organisation chain: there is no `spectron context use`, no server default and nothing persisted.

1. No contexts at all is an error naming `--context`.
2. Exactly one context is used silently.
3. Several, in a non-interactive session, is a usage error, exit `2`:

```text
Several Spectron contexts are available and none was chosen.
Pass --context.

Available:
  research
  production
```

4. Several, on a terminal, opens a picker.

[`spectron context list`](#spectron-context-list) is the one command in the group that needs no context of its own, so it is what to run when `--context` has just failed to resolve.

## Grant syntax

Grants are written `<noun>:<verb>=<pattern>[,<pattern>]` and `--grant` is repeatable. Repeats **merge** rather than overwrite, so `--grant memory:read=/a --grant memory:read=/b` grants both patterns.

```bash
--grant memory:read=/projects/acme
--grant memory:read=/projects/acme,/projects/shared
--grant memory:write=/projects/acme --grant memory:read=/
```

A malformed grant is a usage error, exit `2`, and the message repeats the expected shape. Run [`spectron verbs`](#spectron-verbs) for the verbs a grant may name and [`spectron scopes`](#spectron-scopes) for the paths a pattern may match.

## surrealctl spectron context list {#spectron-context-list}

List the Spectron contexts in an organisation.

<Synopsis>
surrealctl spectron context list [OPTIONS]
</Synopsis>

This command takes no positional arguments and no options of its own.

Accepts the [list presentation flags](/docs/reference/cli/surrealctl/output-and-exit-codes.md#list-presentation-flags). Column ids are `name`, `state`, `region` and `id`, with `host` and `organization_id` under `--wide`.

```bash
surrealctl spectron context list
```

```text title="Output"
NAME        STATE   REGION    ID
research    ready   aws-euw1  67upif0m8sh1cn1p2c8t
production  ready   aws-use1  6a2k9lqzt4v8bn3m1x5c
```

## surrealctl spectron context get {#spectron-context-get}

Show one Spectron context.

<Synopsis>
surrealctl spectron context get [OPTIONS] [CONTEXT]
</Synopsis>

<OptionsTable
    title="Arguments"
    options={[
        {
            "name": "[CONTEXT]",
            "description": "The context, by id or name. Defaults to the only one."
        }
    ]}
/>

This command has no options of its own.

```bash
surrealctl spectron context get research
```

## surrealctl spectron context create {#spectron-context-create}

Create a Spectron context.

<Synopsis>
surrealctl spectron context create [OPTIONS] --region <REGION> <NAME>
</Synopsis>

<OptionsTable
    title="Arguments"
    options={[
        {
            "name": "<NAME>",
            "required": true,
            "description": "A name for the context."
        }
    ]}
/>

<OptionsTable
    title="Options"
    options={[
        {
            "name": "--region",
            "value": "<REGION>",
            "required": true,
            "description": "The region to create the context in."
        }
    ]}
/>

```bash
surrealctl spectron context create research --region aws-euw1
```

Region slugs come from [`catalog regions`](/docs/reference/cli/surrealctl/commands/catalog.md#catalog-regions).

## surrealctl spectron context update {#spectron-context-update}

Rename a Spectron context.

<Synopsis>
surrealctl spectron context update [OPTIONS] --name <NAME> [CONTEXT]
</Synopsis>

<OptionsTable
    title="Arguments"
    options={[
        {
            "name": "[CONTEXT]",
            "description": "The context, by id or name. Defaults to the only one."
        }
    ]}
/>

<OptionsTable
    title="Options"
    options={[
        {
            "name": "--name",
            "value": "<NAME>",
            "required": true,
            "description": "The new name."
        }
    ]}
/>

```bash
surrealctl spectron context update research --name "Research and development"
```

## surrealctl spectron context delete {#spectron-context-delete}

Delete a Spectron context.

<Synopsis>
surrealctl spectron context delete [OPTIONS] [CONTEXT]
</Synopsis>

<OptionsTable
    title="Arguments"
    options={[
        {
            "name": "[CONTEXT]",
            "description": "The context, by id or name."
        }
    ]}
/>

<OptionsTable
    title="Options"
    options={[
        {
            "name": "--force",
            "description": "Delete without confirming."
        }
    ]}
/>

```bash
surrealctl spectron context delete research
```

Note that this positional does not fall back to "the only one" the way the read verbs do. A delete that infers its target is a delete in the wrong terminal tab.

**Refusals.** The confirmation names the context. Declining exits `0`. In a non-interactive session without `--force` or `--yes`, it exits `2` having sent nothing.

## surrealctl spectron key list {#spectron-key-list}

List a context's API keys.

<Synopsis>
surrealctl spectron key list [OPTIONS]
</Synopsis>

This command takes no positional arguments.

<OptionsTable
    title="Options"
    options={[
        {
            "name": "--context",
            "value": "<REF>",
            "description": "The Spectron context, by id or name. Defaults to the only one."
        }
    ]}
/>

Also accepts the [list presentation flags](/docs/reference/cli/surrealctl/output-and-exit-codes.md#list-presentation-flags). Column ids are `name` and `id`, with `spectron_context_id` and `organization_id` under `--wide`.

```bash
surrealctl spectron key list --context research
```

Only the name and the id are stored. The secret exists once, at creation.

## surrealctl spectron key create {#spectron-key-create}

Create an API key.

<Synopsis>
surrealctl spectron key create [OPTIONS] <NAME>
</Synopsis>

<OptionsTable
    title="Arguments"
    options={[
        {
            "name": "<NAME>",
            "required": true,
            "description": "A name for the key."
        }
    ]}
/>

<OptionsTable
    title="Options"
    options={[
        {
            "name": "--reveal",
            "description": "Print the key even when stdout is a terminal."
        },
        {
            "name": "--context",
            "value": "<REF>",
            "description": "The Spectron context, by id or name. Defaults to the only one."
        }
    ]}
/>

```bash title="Capture the key"
surrealctl spectron key create "agent runtime" --context research > /run/secrets/spectron-key
```

```bash title="Keep the id and name alongside the secret"
surrealctl spectron key create "agent runtime" --json > key.json
```

Output is the bare key on stdout in text modes, and the whole body under `--json` so the id and name survive for a later revoke. It is never a table — a secret in a table is a secret in a screenshot.

**Refusals.** The [secret guard](/docs/reference/cli/surrealctl/output-and-exit-codes.md#the-secret-guard) fires *before* the request, so a forgotten `--reveal` never costs a key nobody can recover.

## surrealctl spectron key delete {#spectron-key-delete}

Delete an API key.

<Synopsis>
surrealctl spectron key delete [OPTIONS] <KEY>
</Synopsis>

<OptionsTable
    title="Arguments"
    options={[
        {
            "name": "<KEY>",
            "required": true,
            "description": "The key, by id or name."
        }
    ]}
/>

<OptionsTable
    title="Options"
    options={[
        {
            "name": "--force",
            "description": "Delete without confirming."
        },
        {
            "name": "--context",
            "value": "<REF>",
            "description": "The Spectron context, by id or name. Defaults to the only one."
        }
    ]}
/>

```bash
surrealctl spectron key delete "agent runtime" --context research --force
```

## surrealctl spectron key rotate {#spectron-key-rotate}

Replace an API key's secret, keeping its id and name.

<Synopsis>
surrealctl spectron key rotate [OPTIONS] <KEY>
</Synopsis>

<OptionsTable
    title="Arguments"
    options={[
        {
            "name": "<KEY>",
            "required": true,
            "description": "The key, by id or name."
        }
    ]}
/>

<OptionsTable
    title="Options"
    options={[
        {
            "name": "--reveal",
            "description": "Print the new key even when stdout is a terminal."
        },
        {
            "name": "--force",
            "description": "Rotate without confirming."
        },
        {
            "name": "--context",
            "value": "<REF>",
            "description": "The Spectron context, by id or name. Defaults to the only one."
        }
    ]}
/>

```bash
surrealctl spectron key rotate "agent runtime" --force > /run/secrets/spectron-key
```

Rotation invalidates the previous secret, so redeploy whatever holds it. Like `create`, the secret guard fires before the request.

## surrealctl spectron scoped-key create {#spectron-scoped-key-create}

Mint a scoped key for a principal — a key attenuated below what that principal itself may do.

<Synopsis>
surrealctl spectron scoped-key create [OPTIONS] --principal <REF> <NAME>
</Synopsis>

<OptionsTable
    title="Arguments"
    options={[
        {
            "name": "<NAME>",
            "required": true,
            "description": "A name for the key."
        }
    ]}
/>

<OptionsTable
    title="Options"
    options={[
        {
            "name": "--principal",
            "value": "<REF>",
            "required": true,
            "description": "The principal to bind the key to, by id or name."
        },
        {
            "name": "--grant",
            "value": "<GRANT>",
            "description": "Attenuate to this grant, as `<noun>:<verb>=<pattern>[,<pattern>]`. Repeatable."
        },
        {
            "name": "--reveal",
            "description": "Print the key even when stdout is a terminal."
        },
        {
            "name": "--context",
            "value": "<REF>",
            "description": "The Spectron context, by id or name. Defaults to the only one."
        }
    ]}
/>

```bash title="A read-only key below an agent principal"
surrealctl spectron scoped-key create "read-only worker" \
    --principal "research agent" \
    --grant memory:read=/projects/acme \
    --context research \
    > /run/secrets/worker-key
```

This group has one verb on purpose. A renamed command is a broken script, so `scoped-key` stays a group even with nothing to sit beside `create`.

## surrealctl spectron access-token create {#spectron-access-token-create}

Mint a short-lived access token.

<Synopsis>
surrealctl spectron access-token create [OPTIONS]
</Synopsis>

This command takes no positional arguments.

<OptionsTable
    title="Options"
    options={[
        {
            "name": "--ttl",
            "value": "<DURATION>",
            "description": "How long the token should live, such as `15m` or `2h`. The server clamps it."
        },
        {
            "name": "--reveal",
            "description": "Print the token even when stdout is a terminal."
        },
        {
            "name": "--context",
            "value": "<REF>",
            "description": "The Spectron context, by id or name. Defaults to the only one."
        }
    ]}
/>

```bash
TOKEN=$(surrealctl spectron access-token create --ttl 15m --context research)
```

`--ttl` uses the standard [duration syntax](/docs/reference/cli/surrealctl/global-flags.md#duration-syntax). The server clamps whatever you ask for to its own maximum, so read the expiry from the answer rather than assuming your value was taken.

## surrealctl spectron principal list {#spectron-principal-list}

List a context's principals.

<Synopsis>
surrealctl spectron principal list [OPTIONS]
</Synopsis>

This command takes no positional arguments.

<OptionsTable
    title="Options"
    options={[
        {
            "name": "--context",
            "value": "<REF>",
            "description": "The Spectron context, by id or name. Defaults to the only one."
        }
    ]}
/>

Also accepts the [list presentation flags](/docs/reference/cli/surrealctl/output-and-exit-codes.md#list-presentation-flags). Column ids are `display_name`, `kind`, `id` and `verbs`, with `grants` under `--wide`.

```bash
surrealctl spectron principal list --context research --wide
```

## surrealctl spectron principal create {#spectron-principal-create}

Create a principal.

<Synopsis>
surrealctl spectron principal create [OPTIONS] --kind <KIND> <NAME>
</Synopsis>

<OptionsTable
    title="Arguments"
    options={[
        {
            "name": "<NAME>",
            "required": true,
            "description": "A display name for the principal."
        }
    ]}
/>

<OptionsTable
    title="Options"
    options={[
        {
            "name": "--kind",
            "value": "<KIND>",
            "required": true,
            "description": "What the principal is: `human`, `agent`, `service` or `unknown`."
        },
        {
            "name": "--grant",
            "value": "<GRANT>",
            "description": "Grant this authority, as `<noun>:<verb>=<pattern>[,<pattern>]`. Repeatable."
        },
        {
            "name": "--context",
            "value": "<REF>",
            "description": "The Spectron context, by id or name. Defaults to the only one."
        }
    ]}
/>

```bash
surrealctl spectron principal create "research agent" \
    --kind agent \
    --grant memory:read=/projects \
    --grant memory:write=/projects/acme \
    --context research
```

`--kind` is a free-form string rather than a closed set, because the four values above are a convention and a closed set would need a new release before anyone could use a kind Cloud added.

## surrealctl spectron principal update {#spectron-principal-update}

Rename a principal or change its kind.

<Synopsis>
surrealctl spectron principal update [OPTIONS] <PRINCIPAL>
</Synopsis>

<OptionsTable
    title="Arguments"
    options={[
        {
            "name": "<PRINCIPAL>",
            "required": true,
            "description": "The principal, by id or name."
        }
    ]}
/>

<OptionsTable
    title="Options"
    options={[
        {
            "name": "--name",
            "value": "<NAME>",
            "description": "A new display name."
        },
        {
            "name": "--kind",
            "value": "<KIND>",
            "description": "A new kind."
        },
        {
            "name": "--context",
            "value": "<REF>",
            "description": "The Spectron context, by id or name. Defaults to the only one."
        }
    ]}
/>

```bash
surrealctl spectron principal update "research agent" --kind service
```

Grants are not changed here. Use [`principal grants set`](#spectron-principal-grants-set) for those.

## surrealctl spectron principal delete {#spectron-principal-delete}

Delete a principal.

<Synopsis>
surrealctl spectron principal delete [OPTIONS] <PRINCIPAL>
</Synopsis>

<OptionsTable
    title="Arguments"
    options={[
        {
            "name": "<PRINCIPAL>",
            "required": true,
            "description": "The principal, by id or name."
        }
    ]}
/>

<OptionsTable
    title="Options"
    options={[
        {
            "name": "--force",
            "description": "Delete without confirming."
        },
        {
            "name": "--context",
            "value": "<REF>",
            "description": "The Spectron context, by id or name. Defaults to the only one."
        }
    ]}
/>

```bash
surrealctl spectron principal delete "research agent" --force
```

## surrealctl spectron principal grants set {#spectron-principal-grants-set}

Replace a principal's grants.

<Synopsis>
surrealctl spectron principal grants set [OPTIONS] <PRINCIPAL>
</Synopsis>

<OptionsTable
    title="Arguments"
    options={[
        {
            "name": "<PRINCIPAL>",
            "required": true,
            "description": "The principal, by id or name."
        }
    ]}
/>

<OptionsTable
    title="Options"
    options={[
        {
            "name": "--grant",
            "value": "<GRANT>",
            "description": "Grant this authority, as `<noun>:<verb>=<pattern>[,<pattern>]`. Repeatable."
        },
        {
            "name": "--revoke",
            "value": "<VERB>",
            "description": "Remove every pattern granted for this verb. Repeatable."
        },
        {
            "name": "--clear",
            "description": "Start from nothing, so `--grant` describes the whole result. Conflicts with `--revoke`."
        },
        {
            "name": "--force",
            "description": "Replace without confirming."
        },
        {
            "name": "--context",
            "value": "<REF>",
            "description": "The Spectron context, by id or name. Defaults to the only one."
        }
    ]}
/>

The grants route is a full replacement, so this command reads the current set, applies your flags, and confirms the result before writing.

```bash title="Add a pattern to an existing verb"
surrealctl spectron principal grants set "research agent" \
    --grant memory:read=/projects/contoso
```

```bash title="Drop write access entirely"
surrealctl spectron principal grants set "research agent" --revoke memory:write
```

```bash title="Declare the whole grant set, ignoring what was there"
surrealctl spectron principal grants set "research agent" \
    --clear \
    --grant memory:read=/projects \
    --force
```

`--clear` is what makes this command declarative: with it, the flags describe the complete result rather than a change to what exists. Without it, `--grant` merges and `--revoke` subtracts.

## surrealctl spectron package list {#spectron-package-list}

List every context package this deployment offers.

<Synopsis>
surrealctl spectron package list [OPTIONS]
</Synopsis>

This command takes no positional arguments and no options of its own — not even `--context`. The catalogue is a property of the deployment, so it answers even when nothing else is resolvable.

Accepts the [list presentation flags](/docs/reference/cli/surrealctl/output-and-exit-codes.md#list-presentation-flags). Column ids are `name`, `cost`, `billing_period`, `token_limit`, `storage_gb`, `contexts_limit` and `trial_days`, with `id`, `public` and `description` under `--wide`.

```bash
surrealctl spectron package list
```

## surrealctl spectron package org-list {#spectron-package-org-list}

List the packages an organisation has enabled.

<Synopsis>
surrealctl spectron package org-list [OPTIONS]
</Synopsis>

This command takes no positional arguments and no options of its own.

Accepts the [list presentation flags](/docs/reference/cli/surrealctl/output-and-exit-codes.md#list-presentation-flags). Column ids are `package_id`, `enabled_at`, `trial_ends_at` and `subscription_ends_at`, with `disabled_at` and `organization_id` under `--wide`.

```bash
surrealctl spectron package org-list --org acme
```

## surrealctl spectron package enable {#spectron-package-enable}

Enable a package for an organisation.

<Synopsis>
surrealctl spectron package enable [OPTIONS] <PACKAGE>
</Synopsis>

<OptionsTable
    title="Arguments"
    options={[
        {
            "name": "<PACKAGE>",
            "required": true,
            "description": "The package, by id or name."
        }
    ]}
/>

<OptionsTable
    title="Options"
    options={[
        {
            "name": "--coupon",
            "value": "<CODE>",
            "description": "A coupon code to apply to the subscription."
        }
    ]}
/>

```bash
surrealctl spectron package enable "scale" --coupon LAUNCH2026
```

Enabling a package starts a subscription and affects billing. Check [`package list`](#spectron-package-list) for what each one includes first.

## surrealctl spectron package cancel {#spectron-package-cancel}

Cancel an organisation's package subscription.

<Synopsis>
surrealctl spectron package cancel [OPTIONS] <PACKAGE>
</Synopsis>

<OptionsTable
    title="Arguments"
    options={[
        {
            "name": "<PACKAGE>",
            "required": true,
            "description": "The package, by id or name."
        }
    ]}
/>

<OptionsTable
    title="Options"
    options={[
        {
            "name": "--force",
            "description": "Cancel without confirming."
        }
    ]}
/>

```bash
surrealctl spectron package cancel "scale"
```

**Refusals.** The confirmation names the package. Declining exits `0`. In a non-interactive session without `--force` or `--yes`, it exits `2` having sent nothing.

## surrealctl spectron scopes {#spectron-scopes}

List a context's scope tree.

<Synopsis>
surrealctl spectron scopes [OPTIONS]
</Synopsis>

This command takes no positional arguments.

<OptionsTable
    title="Options"
    options={[
        {
            "name": "--context",
            "value": "<REF>",
            "description": "The Spectron context, by id or name. Defaults to the only one."
        }
    ]}
/>

Also accepts the [list presentation flags](/docs/reference/cli/surrealctl/output-and-exit-codes.md#list-presentation-flags). Column ids are `path`, `name`, `depth`, `children` and `value_policy`, with `created_at`, `parent` and `tombstoned_at` under `--wide`.

```bash
surrealctl spectron scopes --context research --sort path
```

These paths are what a [grant pattern](#grant-syntax) matches.

## surrealctl spectron verbs {#spectron-verbs}

List the verbs a grant can name.

<Synopsis>
surrealctl spectron verbs [OPTIONS]
</Synopsis>

This command takes no positional arguments.

<OptionsTable
    title="Options"
    options={[
        {
            "name": "--context",
            "value": "<REF>",
            "description": "The Spectron context, by id or name. Defaults to the only one."
        }
    ]}
/>

Also accepts the [list presentation flags](/docs/reference/cli/surrealctl/output-and-exit-codes.md#list-presentation-flags). Column ids are `name`, `noun` and `description`.

```bash
surrealctl spectron verbs --context research
```

The `noun` and `name` columns are the two halves of the `<noun>:<verb>` prefix in a grant.

## surrealctl spectron providers {#spectron-providers}

List the model providers a context can use.

<Synopsis>
surrealctl spectron providers [OPTIONS]
</Synopsis>

This command takes no positional arguments.

<OptionsTable
    title="Options"
    options={[
        {
            "name": "--context",
            "value": "<REF>",
            "description": "The Spectron context, by id or name. Defaults to the only one."
        }
    ]}
/>

Also accepts the [list presentation flags](/docs/reference/cli/surrealctl/output-and-exit-codes.md#list-presentation-flags). Column ids are `provider` and `models`, with `count` under `--wide`.

```bash
surrealctl spectron providers --context research
```

## surrealctl spectron usage {#spectron-usage}

Show a context's token usage.

<Synopsis>
surrealctl spectron usage [OPTIONS]
</Synopsis>

This command takes no positional arguments.

<OptionsTable
    title="Options"
    options={[
        {
            "name": "--context",
            "value": "<REF>",
            "description": "The Spectron context, by id or name. Defaults to the only one."
        }
    ]}
/>

Also accepts the [list presentation flags](/docs/reference/cli/surrealctl/output-and-exit-codes.md#list-presentation-flags). Column ids are `model`, `token_kind`, `origin` and `tokens`.

```bash title="Heaviest models first"
surrealctl spectron usage --context research --sort tokens --reverse
```

A one-line total is printed on stderr in text modes, computed before `--limit` is applied. A context with no ceiling gets its own sentence rather than a hole where the limit would be.

## surrealctl spectron config {#spectron-config}

Show a context's configuration.

<Synopsis>
surrealctl spectron config [OPTIONS]
</Synopsis>

This command takes no positional arguments.

<OptionsTable
    title="Options"
    options={[
        {
            "name": "--context",
            "value": "<REF>",
            "description": "The Spectron context, by id or name. Defaults to the only one."
        }
    ]}
/>

This command carries no list presentation flags — its answer is a detail view, not a table.

```bash
surrealctl spectron config --context research
```

Not to be confused with [`surrealctl config`](/docs/reference/cli/surrealctl/commands/config.md), which reads and writes the CLI's own configuration file on this machine.

## Related pages

- [Spectron documentation](/docs/spectron.md) — what contexts, principals and grants are for
- [`org` commands](/docs/reference/cli/surrealctl/commands/org.md) — the organisation that owns a context
- [Output and exit codes](/docs/reference/cli/surrealctl/output-and-exit-codes.md#the-secret-guard) — the secret guard every minting command applies
- [Overview](/docs/reference/cli/surrealctl/overview.md) — the rest of the reference
- [SurrealDB CLI](/docs/reference/cli/surrealdb-cli/overview.md) — for working with the data inside an instance
