| name | my-database-api |
| version | 1.0.0 |
| description | Per-org KV store with named namespaces, JSON values up to 256 KB, prefix-scan listing, and compare-and-swap via etag. The substrate for any stateful agent-built app on MyAPI — user tables, session stores, idempotency keys, per-user lookup maps.
|
| triggers | ["database","kv","key value","namespace","store","state","etag","cas","session","idempotency"] |
| checksum | sha256-pending |
MyDatabaseAPI
A small KV primitive scoped to your MyAPI org. Two resources: namespaces (containers) and keys (the actual values). Values are JSON; binary belongs in myapi storage. Compare-and-swap via etags is supported on day one.
Capabilities
Use this when you need state behind a workflow or a function — the user table for a SaaS the agent is building on MyAPI primitives, a per-customer settings store, idempotency keys for webhook handlers, a session cache. Anything where Redis is overkill but raw env-var configuration isn't enough.
Model
- An organization owns many namespaces
- A namespace owns many keys
- A key points to one JSON value (≤ 256 KB serialized)
- Every value has an opaque etag that changes on every successful write
Limits
- Key ≤ 512 bytes (UTF-8)
- Value ≤ 256 KB serialized JSON. For blobs/binary, use
myapi storage.
- Namespace name matches
^[a-z0-9][a-z0-9_-]{0,62}$; the __myapi_ prefix is reserved.
Compare-and-swap
Pass --if-match <etag> from a previous get to make set or del conditional. Returns an error if another writer changed the value between your read and write. Without --if-match, last-write-wins.
Listing
- Default: keys only, one per line
--values adds inline values + etags (cost: a bigger response payload)
--prefix foo for prefix-scoped listing
--limit N (1–1000, default 50)
- Paginates via
--cursor — the previous response's next_cursor
Failure modes
412 ETAG_MISMATCH on CAS conflict (CLI surfaces it as a friendly error)
404 NAMESPACE_NOT_FOUND / KEY_NOT_FOUND
409 NAMESPACE_EXISTS on re-create
400 VALUE_NOT_JSON if the body's value isn't valid JSON
413 VALUE_TOO_LARGE if you exceed 256 KB (CLI also pre-flight checks)
Commands
| Command | What it does |
|---|
myapi database namespaces [--json] | List namespaces in the org |
myapi database create <name> | Create a namespace |
myapi database delete-namespace <name> | Delete namespace AND all its keys (irreversible) |
myapi database keys --ns <ns> [--prefix <p>] [--limit N] [--values] [--cursor <c>] | List keys, optionally with inline values |
myapi database get <key> --ns <ns> | Get value + etag (etag printed to stderr) |
myapi database set <key> <value-json> --ns <ns> [--if-match <etag>] [--file <path>] | Set key. CAS via --if-match |
myapi database del <key> --ns <ns> [--if-match <etag>] | Delete key. CAS via --if-match |
Pass - as <value-json> to read the value from stdin, or --file <path> to read from a file.
Examples
myapi database create my-app
myapi database set user:alice '{"plan":"pro","trial_ends":"2026-06-01"}' --ns my-app
myapi database get user:alice --ns my-app
myapi database keys --ns my-app --prefix user: --values
ETAG=$(myapi database get user:alice --ns my-app --json | jq -r .etag)
myapi database set user:alice '{"plan":"enterprise"}' --ns my-app --if-match "$ETAG"
myapi database set "delivery:$DELIVERY_ID" 'true' --ns idempotency --if-match '"00000000"' \
|| { echo "already processed"; exit 0; }
End-to-end recipe — user table for an agent-built SaaS
myapi database create users
myapi database set "by-email:$EMAIL" "$(jq -nc --arg n "$NAME" '{name:$n, plan:"trial"}')" \
--ns users
myapi database get "by-email:$EMAIL" --ns users --json | jq -r .value
Notes
- No transactions across keys. Each key is independently atomic; multi-key updates aren't atomic. Use a single composite-JSON value if you need joint atomicity.
- No secondary indexes today. Prefix scans are the only query primitive. Design your keys for the access pattern (
user:by-email:alice@x.com, user:by-plan:pro:alice@x.com, etc.).
- No TTL today. Keys live until deleted. If you need expiry, store
expires_at in the value and let your reader drop stale rows.
- Eventual
key_count. The keys field on a namespace is approximate; don't use it for strict pagination math.
- Free in v1. Metered later if usage shows a need. Cost discipline still applies — store data, not blobs.
Run myapi database --help for inline reference.