Skip to main content

Key-Value Storage Functions

A key-value bucket stores small values under string keys. Use it for state a flow needs to keep between runs — a cursor, a counter, a cached lookup, a per-customer setting. Five functions are available to a Function step: Buckets are per-account. There is no delete function — remove a bucket or a key from the platform UI.
For anything larger than a small JSON document — a file, a PDF, an export — use Object Storage instead.

Names and limits

  • Bucket names must match [a-zA-Z0-9_-]+. No dots, no spaces.
  • Keys must match [-/_=.a-zA-Z0-9]+ and may not begin or end with a dot. A key built from user input needs sanitising first.
  • ttl is in nanoseconds. It is a Go duration on the wire: one hour is 3600000000000.
  • history defaults to 1 and caps at 64.
Do not point these functions at the account’s secrets store. get-kv-bucket-item, put-kv-item and list-kv-bucket-items refuse it and return {"error": "…"} explaining why — a listing in particular would return every key and its plaintext value at once. Read one secret with secret-key-get-node, or put SECRET::<name>:: in any node’s configuration and let the platform resolve it before the run starts.

create-key-value-bucket

Creates a bucket. Creating one that already exists returns an error in the body rather than replacing it.
string
required
Bucket name. Must be unique in the account and match [a-zA-Z0-9_-]+.
string
Free text shown alongside the bucket.
integer
Revisions kept per key. Default 1, maximum 64.
integer
Key expiry in nanoseconds. Omitted means keys never expire.
integer
Maximum total size of the bucket in bytes. Default -1 (unlimited).
integer
Maximum size of a single value in bytes. Default -1 (unlimited).
string
"file" or "memory". Default "file". Lower case — a capitalised value is rejected.
integer
Copies kept across the cluster. Default 1, maximum 5.
boolean
Compress the underlying storage.
Payload
Returns
A bucket that already exists comes back as {"status_code": 409, "body": {"error": "..."}}.

put-kv-item

Writes a value. Writing an existing key overwrites it; the previous value is kept only if the bucket’s history is above 1.
string
required
Bucket to write into. The bucket must already exist.
string
required
Key to write. Must match [-/_=.a-zA-Z0-9]+.
string | object
required
The value. An object is stored as JSON; a string is stored as text.
Payload
Returns

get-kv-bucket-item

Reads one key.
string
required
Bucket to read from.
string
required
Key to read.
boolean
Return the value as it is rather than re-serialising it. Defaults to false — see the warning below.
Payload
Returns
Set json: true whenever the value is an object. The storage layer already returns JSON values parsed. Leaving json off then runs the parsed value back through JSON.stringify, so an object comes back as a JSON string and a plain string comes back wrapped in quotes. With json: true the value is left as it is.
Reference the value as $.STEP_ID.body.body.value.

list-key-value-buckets

Lists every key-value bucket in the account. Takes no parameters — an empty payload {} is correct. Returns

list-kv-bucket-items

Lists the keys in one bucket, with their values. A bucket holding anything sensitive should not be listed from a flow.
string
required
Bucket to list.
integer
Maximum entries in one page. Defaults to 100.
integer
Sequence to start from.
Payload
Returns
A value that is valid JSON comes back parsed; anything else comes back as a string. So the shape of value varies from row to row, and code reading a listing has to cope with both. results_total counts the rows in this page, not the bucket. When a page is cut short the body also carries truncated: true and a next_cursor string; send that string back as cursor to continue. Treat the cursor as opaque.

Failure

Every function on this page catches its own errors and returns {"error": "<message>"}. That is a successful step — the run continues and the next step reads an object with an error key where it expected data. If a later step depends on the read succeeding, branch on it:
The final cell has no condition, so it always matches. Leave it out and a run where the read succeeded ends with failed to determine next steps. See Building Reliable Flows for what a part-completed run leaves behind.

Object Storage

For files and anything large

Streams

For an append-only history rather than a current value

Utilities

Secrets, encoding, templating, format conversion

Functions Overview

The full catalogue