Skip to content

KV operations

POST /v1/disks/{disk}/kv/{namespace}

Send Content-Type: application/json and the server Bearer key. Both names follow the name rules. The namespace is created on use.

A key is a UTF-8 JSON string or {"base64":"..."} for raw bytes. Its decoded size is limited to 16 KiB. Identical string/byte encodings identify the same key. Empty keys are valid.

Values carry a type:

Value JSON representation
Text {"type":"text","value":"dark"}
JSON {"type":"json","value":{"enabled":true}}
Bytes {"type":"bytes","value":"AP8="}

Values are limited to 1 MiB of stored payload. Text and JSON count stored UTF-8 bytes. Binary values count decoded bytes. Unknown fields, including TTL options, are rejected.

Request
curl --fail-with-body "https://api.wabe.sh/v1/disks/demo/kv/app" \
-H "Authorization: Bearer YOUR_PROJECT_API_KEY" \
--json '{"op":"put","key":"theme","value":{"type":"text","value":"dark"}}'

Response: 200, {"success":true}. Put replaces the value and type.

Request
curl --fail-with-body "https://api.wabe.sh/v1/disks/demo/kv/app" \
-H "Authorization: Bearer YOUR_PROJECT_API_KEY" \
--json '{"op":"get","key":"theme"}'
Found: 200
{"found":true,"entry":{"key":"theme","value":{"type":"text","value":"dark"},"revision":"7"}}
Missing: 200
{"found":false}

Revision values vary. Treat them as opaque decimal strings. Stored JSON null is returned as a found entry with {"type":"json","value":null}.

Check a key
curl --fail-with-body "https://api.wabe.sh/v1/disks/demo/kv/app" \
-H "Authorization: Bearer YOUR_PROJECT_API_KEY" \
--json '{"op":"exists","key":"theme"}'

Response: 200, {"exists":true} or {"exists":false}.

Delete a key
curl --fail-with-body "https://api.wabe.sh/v1/disks/demo/kv/app" \
-H "Authorization: Bearer YOUR_PROJECT_API_KEY" \
--json '{"op":"delete","key":"theme"}'

Response: 200, {"success":true}, including for an absent key.

Request
curl --fail-with-body --no-buffer "https://api.wabe.sh/v1/disks/demo/kv/app" \
-H "Authorization: Bearer YOUR_PROJECT_API_KEY" \
--json '{"op":"scan","prefix":"user:","limit":100,"reverse":false}'
Field Default Meaning
prefix Empty key Restrict returned keys to a byte prefix.
after Absent Exclusive key cursor; must share the prefix.
limit Unbounded Maximum rows; zero returns no rows.
reverse false Descending byte order.

Response: 200, application/x-ndjson. Each line has the same entry shape as get’s entry field. Empty scans have no records. The last key can be used as the next after cursor. Pages do not share one snapshot. Invalid UTF-8 keys return base64 objects; UTF-8 keys return strings.

Request
curl --fail-with-body "https://api.wabe.sh/v1/disks/demo/kv/jobs" \
-H "Authorization: Bearer YOUR_PROJECT_API_KEY" \
--json '{"op":"batch","operations":[{"op":"put","key":"42:result","value":{"type":"json","value":{"files":3}}},{"op":"put","key":"42:status","value":{"type":"text","value":"done"}},{"op":"delete","key":"42:pending"}]}'

Response: 200, {"success":true}. The ordered list of put/delete mutations publishes atomically within this namespace. The encoded mutation budget is 8 MiB, including keys and operation metadata. Request bodies also have an 8 MiB limit, including JSON/base64 encoding.

KV mutations acknowledge according to the server’s durability mode. They do not trigger a flush. Read operations and scans never request persistence.

Status Scenario
400 Invalid namespace, base64, cursor or stored-value input.
401 Authentication failed.
413 Key, value, batch or request body exceeds its limit.
422 Invalid JSON shape, unsupported op/type/field or TTL option.
500 Storage failure or corrupt stored data.

Errors use text bodies. A scan failure after headers terminates its stream. See the JS KV reference and KV guide for the other interfaces.