Skip to main content

Configuration and scripting

Global flags​

These work with every command, before or after the command name.

FlagDescription
--profile <name>Credential profile to use. Default: the current profile
--url <url>Override the install URL for this command. Default https://dashboard.skry.be
--output <format>table (default), json or text
--jsonShorthand for --output json
-v, --versionPrint the CLI version
-h, --helpHelp for any command, e.g. skrybe campaigns send --help

There is deliberately no --api-key flag. See Authentication for how the key is supplied.

Config file​

Profiles live in ~/.skrybe/config.json, or $XDG_CONFIG_HOME/skrybe/config.json, or wherever SKRYBE_CONFIG points. The file and its format are described under Where credentials are stored. It holds only profiles; there are no other settings in it.

Environment variables​

VariableDescription
SKRYBE_API_KEYAPI key; overrides any profile
SKRYBE_API_URLInstall URL; overrides any profile
SKRYBE_PROFILEProfile to use when --profile is not given
SKRYBE_CONFIGPath of the config file
SKRYBE_OUTPUTDefault output format: table, json or text
XDG_CONFIG_HOMEConfig file goes in $XDG_CONFIG_HOME/skrybe/
NO_COLORAny value turns colour off

Colour is also off when stdout is not a terminal or TERM=dumb.

Output formats​

--output picks the shape. Data goes to stdout and messages go to stderr, so pipes and redirects stay clean.

FormatFor
tableReading. Aligned columns with a header. The default
jsonjq. The full record, with numbers and nulls intact
textcut, awk, while read. Tab-separated, no header, no padding

The format is chosen in this order: --json, then --output, then SKRYBE_OUTPUT, then table. An unknown value is an error (exit code 2) rather than a silent fallback.

skrybe lists --output json | jq -r '.[].id'
skrybe lists --output text | cut -f2

How each kind of command uses the format:

  • Collections (skrybe lists, skrybe campaigns): json prints an array; text prints one tab-separated line per row, in the same columns as the table.
  • Single records (campaigns get, lists get): json prints the object; text prints key<TAB>value lines, with nested keys dotted (subscribers.active) and arrays of objects indexed (links.0.url).
  • Single values (lists count, subscribers status): under table and text the bare value, so $(skrybe lists count ID) captures a number; under json an object.
  • Actions (subscribers add, campaigns send): under table a sentence goes to stderr and stdout stays empty. Under json and text the result record goes to stdout.
$ skrybe subscribers add ada@example.com --list l7763lkC1Ld892Ty4p3pvxw --output json
{
"email": "ada@example.com",
"list_id": "l7763lkC1Ld892Ty4p3pvxw",
"outcome": "subscribed"
}

A few commands that create something (lists create, campaigns duplicate, templates create) print the new ID to stdout even under table, so a script can capture it:

LIST=$(skrybe lists create 'Beta testers')

Empty results​

An empty collection is a success: the command exits 0, --output json prints [], text prints nothing, and table prints a note to stderr.

Errors​

Errors always go to stderr. Under table and text they read:

Error [list_not_found]: List does not exist
Run `skrybe lists` to see the IDs available to this API key.

The code in brackets is a stable slug a script can match on. The second line, when present, is a hint.

Under --output json the error is JSON too, so a script parses one shape on success and failure:

$ skrybe subscribers status nobody@example.com --list bogus --output json
{
"error": {
"code": "list_id_invalid",
"message": "List ID not passed",
"hint": "A list ID is the encrypted value `skrybe lists` prints, not the integer in the UI URL."
}
}

hint is null when there is none.

Exit codes​

CodeMeaning
0Success, including an empty result
1API error: the request reached Skrybe and failed, or the server could not be reached
2Usage error: bad flag or argument, missing configuration, refused without --yes, or a command that is not available yet
3Authentication failure: missing or invalid API key
4Quota exceeded or rate limited

--help and --version exit 0.

skrybe campaigns send 42 --list "$LIST" --yes
case $? in
0) echo sent ;;
4) echo "over quota" ;;
*) echo failed ;;
esac

Confirmation prompts​

Commands that send, schedule or delete ask first, defaulting to no:

Send campaign 42 to 1,204 recipients? [y/N]

The prompt is written to stderr. When stdin is not a terminal (a script, CI, a pipe) there is no one to answer, so these commands refuse with exit code 2 unless you pass --yes (-y):

CommandAsks before
lists deletedeleting the list and its subscribers
lists fields deletedeleting the field and its values
campaigns sendsending
campaigns schedulescheduling
campaigns deletedeleting
templates deletedeleting

campaigns send and campaigns schedule also take --dry-run, which checks everything and counts the recipients without changing anything.

Passing values from files​

Any flag that takes a message body accepts file:// followed by a path, the same convention as the AWS CLI:

skrybe templates create 'Welcome' --html-text file://welcome.html
skrybe campaigns update 42 --html-text file:///home/ada/emails/q4.html

The path after file:// is resolved against the current directory, so both file://body.html and file:///absolute/path.html work. A value without the prefix is used as it is. A missing or unreadable file is a usage error (exit code 2).

The flags that accept file://:

CommandFlags
campaigns create, campaigns update--html-text, --plain-text
templates create, templates update--html-text, --plain-text
emails send--html-text, --plain-text, --recipient-variables
emails send-transactional--html-body, --plain-body

Reading from stdin​

Two commands read secrets from stdin, so they never appear in ps or shell history:

  • skrybe auth login reads the API key (prompted at a terminal, or piped in).
  • skrybe brands transport ... --password-stdin reads the relay password.

No other command reads stdin, apart from the yes/no confirmation prompts.

Pagination​

Commands that page through large results share three flags:

FlagDescription
--page <n>Page to show. Default 1
--limit <n>Rows per page
--allFetch every page and print them together

--all cannot be combined with --page or --limit.

CommandDefault --limitMaximum
campaigns / campaigns ls10100
subscribers ls1001000
campaigns activity1001000

Under table, when there are more rows than shown, a line such as Showing 1-100 of 4,210. Use --page, or --all. goes to stderr (subscribers ls and campaigns activity).

Retries and timeouts​

Each request times out after 30 seconds. Read-only requests are retried up to 3 times on HTTP 429, 502, 503 and 504 or a dropped connection, honouring Retry-After. Requests that create, send or change something are never retried, because the API has no idempotency keys and a retry could send twice.

Pipes​

skrybe lists | head -3 stops quietly with exit code 0 when head closes the pipe, so set -o pipefail scripts are not tripped by it.

Shell completion​

eval "$(skrybe completion bash)"    # add to ~/.bashrc
eval "$(skrybe completion zsh)" # add to ~/.zshrc
skrybe completion fish > ~/.config/fish/completions/skrybe.fish

See completion.