Six commands sit at the top level rather than inside a noun group. They cover identity, the raw API escape hatch, opening the dashboard, diagnostics, version information and shell completion.
surrealctl whoami
Show who the API thinks you are.
surrealctl whoami [OPTIONS]This command takes no arguments and no options of its own.
surrealctl whoamiEmail ana@acme.example
User Id 67upif0m8sh1cn1p2c8t
Name Ana Silva
Default Org acmewhoami spends a request on the API's own profile route, which makes it the counterpart to auth status: that one reports what is on this machine, without touching the network; this one reports what the API believes. When they disagree, the API is right.
In text modes the default organisation is shown by name, which costs a second request. That lookup is skipped under --json, where the payload is the profile exactly as the API sent it.
surrealctl api
Call the API directly.
surrealctl api [OPTIONS] <METHOD> <PATH>This is the escape hatch. It signs a request with whatever credential the profile holds, applies the same retries and the same error classification as every other command, and prints the body — so a route that has no dedicated command is still reachable without rebuilding authentication by hand.
surrealctl api get /api/cloud/v0/organizationssurrealctl api get /api/cloud/v0/organizations --query limit=5 --includesurrealctl api post /api/cloud/v0/organizations --data @org.json --forceecho '{"name":"acme"}' | surrealctl api post /api/cloud/v0/organizations -d - --force-d follows curl's spellings: - and @- mean standard input, @path means a file, and anything else is treated as an inline body.
Confirmation. Any write method — POST, PUT, PATCH or DELETE — confirms first unless --force or the global --yes is given. Declining prints Nothing was sent. and exits 0. In a non-interactive session with neither, it exits 2 having sent nothing.
Refusals, all exit 2:
An unknown method:
Ensure the method is one of get, post, put, patch or delete (got `HEAD`)A URL where a path was expected:
Ensure the path is a path and not a URL; the host comes from --apiA malformed
--queryor--header. Both split on their first separator only, so a value containing=or:survives intact.A reserved header.
Authorization,X-Cloud-TokenandX-Request-Idcome from the credential in use:
`authorization` is set from the credential in use and cannot be overridden here. Pass --token or --token-file to change what is sent.A body on a
GET:A GET takes no body. Use --query for parameters, or pick another method.A body that is not valid JSON, naming where it came from.
Notes. A path on neither the Cloud nor the accounts surface is sent without credentials, and says so first. Retries follow the method: a GET is retried freely, a POST never, and PUT, PATCH and DELETE only when the connection failed before anything was sent.
--raw writes the bytes verbatim, control characters included, which is safe only because it is opt-in. --json is unaffected by --raw: it always emits one parseable document, turning a non-JSON body into a JSON string and an empty body into null. In text mode an empty body prints nothing, and a note on stderr reports the status that answered with none.
surrealctl open
Open a dashboard page in a browser.
surrealctl open [OPTIONS] [SUBJECT] [REF]This command has no options of its own — only the global flags.
[SUBJECT] | Opens |
|---|---|
dashboard | The account's overview page |
org | An organisation's overview |
instance | One instance, by id, slug or name |
context | One Spectron context, by id or name |
billing | An organisation's billing and invoices |
terms | The terms and privacy policy, which this CLI links to and never accepts |
surrealctl opensurrealctl open instance productionsurrealctl open billingThe URL is always printed; it is only sometimes opened. A browser is attempted when a person is present — which includes a --json invocation, since a human may well want machine output and a browser window at the same time — and a failure to open is a warning rather than an error. So the command is still useful over SSH: you get the link, and you paste it yourself.
Refusals, exit 2:
A
[REF]alongsidedashboardorterms, which take none:
That subject takes no reference. Try `surrealctl open org <name>` or `surrealctl open instance <name>`.instanceorcontextwith no reference:
`open instance` needs to know which one.
Try: surrealctl open instance <name>open terms links to the legal documents and lists the others as notes. This CLI never accepts terms on your behalf.
surrealctl status
Check that everything is configured and reachable. Also spelled surrealctl doctor.
surrealctl status [OPTIONS]surrealctl doctor [OPTIONS]This command takes no positional arguments and no options of its own.
Accepts the list presentation flags. Column ids are check, ok and detail.
Seven checks run in dependency order, one row each. No check can abort the command, so you always get the whole picture:
| Check | What it covers |
|---|---|
credential | Which credential this profile holds, and when it expires. Local only. A failure here is fatal |
api | A version request against the API. An authentication error skips this rather than failing it |
version | The client version the API expects. Reported, never enforced |
cloud session | The Cloud session token. A personal access token is reported as skipped, not passed or failed |
organization | The full precedence chain, picker included. Never fatal |
surreal binary | Which surreal would be used. Purely local, so it runs offline. Never fatal |
system message | A platform banner, when a session is available and the API has one. No verdict |
surrealctl statussurrealctl status --json | jq -r '.[] | select(.ok == false) | .check + ": " + .detail'The ok column is a tri-state. A check either passed, failed, or never ran because something it depended on had already failed — the third case renders as a dash, and under --json the ok field is null rather than false.
This is the one command that prints its table even when it exits non-zero, because the table is the diagnosis and a doctor command that goes silent when things break is useless in the one situation it exists for. The exit code comes from the first fatal check — 3 for a credential problem, 9 for an unreachable API — rather than a flat 1.
The surreal binary check reports which copy is in use and does not offer to download one; a diagnostic should not fetch a binary. See the surreal handoff.
surrealctl version
Output version information.
surrealctl version [OPTIONS]This command takes no positional arguments.
surrealctl versionsurrealctl 0.1.0
Commit 9f3c1ab
Built 2026-08-11
Target aarch64-apple-darwin{
"version": "0.1.0",
"commit": "9f3c1ab",
"build_date": "2026-08-11",
"target": "aarch64-apple-darwin"
}version reports the build in front of you. It needs no credential and no organisation, so it works before you have signed in and inside a container with no egress. The two flag forms surrealctl -V and surrealctl --version print the version string alone.
For the API's own version and the client version floor it expects, use status.
surrealctl completion
Generate shell completions.
surrealctl completion [OPTIONS] <SHELL>This command has no options of its own.
surrealctl completion zsh > "${fpath[1]}/_surrealctl"surrealctl completion bash > /etc/bash_completion.d/surrealctlsurrealctl completion fish > ~/.config/fish/completions/surrealctl.fishsurrealctl completion powershell | Out-String | Invoke-ExpressionThis is the one command whose payload is not a view: it emits a shell script, so --json does not wrap it. The script is buffered before it is written, so surrealctl completion bash | head -1 exits 0 rather than failing on the closed pipe.
See Installation for where each shell expects the file to live.
Related pages
Output and exit codes — the
--jsoncontract and the full exit-code tableAuthentication — what
whoamiandstatusare reporting onInstallation — completion setup and the
surrealhandoffOverview — the rest of the reference
SurrealDB CLI — for queries, imports, exports and running a server