CLI reference

skrzynka is a noninteractive JSON CLI. Successful commands print one pretty-printed JSON value to stdout and exit 0. Application failures print one compact envelope to stderr and exit 1:

Overview#

skrzynka is a noninteractive JSON CLI. Successful commands print one pretty-printed JSON value to stdout and exit 0. Application failures print one compact envelope to stderr and exit 1:

json
{"error":{"code":"MAILBOX_PROFILE_INVALID","message":"imap_host is required","retryable":false}}

Argument parsing failures are Clap text and exit 2. Logs go to stderr. Every command except serve, version and onboarding acts for the organization named by --organization <ID>; a command without it is refused with ORGANIZATION_REQUIRED, and no organization is assumed. Rows written before organizations existed carry the stored namespace legacy-local; name it to read them.

Global options#

OptionDefaultMeaning
--organization <ID>noneRequired organization scope for data commands; serve, version and onboarding do not require it
--skarbiec-bin <PATH>skarbiecexecutable invoked for credential operations
-h, --help—help; no state or network access
-V, --version—package version text from Clap

Global options may appear with subcommands. skrzynka version instead emits the machine JSON object {product, version, source} and opens no database.

Service and inspection#

skrzynka serve

text
skrzynka serve --bind <SOCKET>
OptionDefaultRule
--bind127.0.0.1:8788address IP must be loopback

Opens the database, reads each enabled mailbox as its provider announces new mail (IMAP IDLE; no polling interval), and serves the HTTP API. It remains in the foreground. Startup readiness is the stderr log Skrzynka API ready address=....

skrzynka status

Returns {product, version, database, schema_version, mailbox_count, enabled_mailbox_count, message_count, skarbiec_available}. The Skarbiec probe runs skarbiec version but resolves no item.

skrzynka version

Returns {product:"skrzynka", version, source}. Source builds report source-build unless the compile-time SKRZYNKA_SOURCE_REVISION was set.

Mailboxes#

mailbox declare

text
skrzynka mailbox declare --skarbiec-item <ID>

Skarbiec owns the mailbox list: an item tagged skrzynka:mailbox is a mailbox. declare validates the item's profile, adds the tag, and imports every INBOX message, one commit each. Only the item reference is an input; profile flags are refused. The canonical mailbox declare reference owns the complete behavior.

Inventory and state

CommandOutput / effect
mailbox listreconcile with Skarbiec, then a JSON array sorted case-insensitively by display name, then email
mailbox show <UUID>one mailbox object
mailbox undeclare <UUID>remove the skrzynka:mailbox tag; the mailbox keeps its mail with enabled:false; return object
mailbox remove <UUID> --confirmcascade-delete the local state of an undeclared mailbox; return {"removed":"<UUID>"}

Removal without --confirm is CONFIRMATION_REQUIRED; removal of a declared mailbox is MAILBOX_STILL_DECLARED. It never deletes provider or Skarbiec state.

Synchronization#

text
skrzynka --organization <ID> sync [--mailbox <UUID>]

With --mailbox, runs one pass that imports everything past the cursor and returns {mailbox_id, received, skipped, last_uid, completed_at}; a dependency failure exits 1, keeping every message committed before it. Without it, processes every enabled mailbox and returns {completed_at, reconciliation, mailboxes:[...]}. Individual failures are embedded as {mailbox_id, ok:false, summary:null, error_code, error_message} and the command still exits 0.

Messages, replies, and outbound mail#

message list

text
skrzynka message list [--mailbox <UUID>] [--limit <N>] [--offset <N>]

Without --limit every message from --offset (default 0) on is listed; with it, a page of that many. Returns newest imported messages first, optionally for one mailbox.

message show

Returns one message object. Invalid UUID syntax is rejected by Clap before the application; an absent UUID returns NOT_FOUND.

message reply

text
skrzynka message reply <MESSAGE-UUID> --body-file <PATH>
  [--idempotency-key <KEY>]

The file must be regular and UTF-8; its size is the SMTP server's to accept or refuse. Omitting the key generates a new UUID. Returns the reply attempt on SMTP acceptance or when an identical key already exists. Provider and validation failures use the standard error envelope; persisted attempt state remains available through the HTTP reply list.

message send

text
skrzynka message send --mailbox <UUID-OR-ADDRESS> --to <ADDRESS> [--to <ADDRESS>]
  [--cc <ADDRESS>] --subject <TEXT> --body-file <PATH>
  [--idempotency-key <KEY>]

Originates mail the mailbox did not receive. --mailbox accepts the mailbox UUID or the mailbox's own address, and an address naming more than one mailbox is refused with MAILBOX_SELECTOR_AMBIGUOUS rather than silently picked. --to and --cc are repeatable bare addresses, comma-splittable, deduplicated in order; a display name is refused. The subject must not be empty and the body file is regular UTF-8; the SMTP server accepts or refuses its size. Returns the stored outbound message; the idempotency key claims the row before anything reaches the provider.

message outbound

text
skrzynka message outbound [--mailbox <UUID-OR-ADDRESS>] [--limit <N>] [--offset <N>]

Without --limit every outbound message from --offset (default 0) on is listed; with it, a page of that many. Returns originated mail newest first, optionally for one mailbox, and resolves no credential.

Gmail connection#

CommandOutput / effect
account connection --provider gmail --bind <SOCKET> [--email <ADDRESS>]{account, mailbox_id, receiving_skarbiec_item_id, usable_paths, paths}; each of app_password, oauth and delegation is measured against Google and reported usable, refused or unproven with its code, the provider's own words, the non-secret facts observed and the exact next step
account authorize --provider gmail --bind <SOCKET> --skarbiec-item <ID>Start the PKCE flow and serve the loopback callback on the required --bind address, which the configured OAuth client must accept. After authorization completes, exit when its mailbox exists. See Gmail connection for prerequisites and measured refusals.
account delegate --provider gmail --email <ADDRESS> [--display-name <TEXT>]prove delegated access, persist the mailbox bundle in Skarbiec, and return a new or existing mailbox
account app-password --provider gmail --email <ADDRESS> [--display-name <TEXT>] [--mailbox <ID-OR-ADDRESS>]read the app-specific password from stdin, prove it against Gmail IMAP, persist its deterministic bundle in Skarbiec, and create or reconnect the Gmail mailbox; with --mailbox, attach it as the selected existing row's receiving credential without changing that row's outgoing identity or SMTP setup

Skrzynka never performs the domain-wide delegation grant. It exists only in the Workspace admin console, so a missing grant is reported as GOOGLE_DELEGATION_NOT_GRANTED with the client ID, the scope and the console URL. See Gmail connection for the OAuth client's measured state.

Command pages#

Every public top-level command and every public leaf subcommand has its own canonical reference page:

Exit and retry contract#

  • 0: command's local contract completed. For all-mailbox sync, inspect each ok.
  • 1: normalized application error. Retry only when retryable:true, and never automatically resend an ambiguous reply.
  • 2: command line could not be parsed.

See runbook for every stable error family.