Documents storage

Per-account private JSON key/value storage. Your app can persist state server-side — surviving across devices and browsers — instead of relying on localStorage. It shares the same pipeline as every other service: rate limit → quota → bill.

Endpoints

Method & pathBehavior
PUT /api/v1/documents/:keyUpsert — the request body is the JSON value. → {key, created, chars}
POST /api/v1/documentsCreate with a generated key (d_<20hex>). → {key, created:true, chars}
GET /api/v1/documents/:keyReturns the stored JSON verbatim.
DELETE /api/v1/documents/:key→ {deleted:true}

Key rules

  • Keys match ^[a-zA-Z0-9._-]{1,128}$. The literals . and .. are rejected (400 bad_key).
  • The kb- prefix is reserved: writes/deletes to kb-* → 403 reserved_key; reads are allowed.
  • A missing document on GET/DELETE → 404 document_not_found (not billed — only successful operations bill).

Per-key document filter

An API key scoped to the Documents service can also be restricted to a subset of document keys, set in Dashboard → API Keys. Anything outside the filter returns 403 document_key_not_allowed — on reads, writes and deletes alike.

  • The filter is a comma-separated list of patterns; the default * allows every key.
  • A trailing * matches a prefix; anything else is an exact key. Example: xxx-*, kb-*, some-specific-key.
  • Include kb-usage (or kb-*) if the key should be able to read the usage document described below — that's a normal read, and the filter applies to it too.
  • Include d_* if the key uses POST /api/v1/documents, whose generated keys always start with d_ — without that coverage the create is refused.

The filter only ever subtracts: it can't reach anything your account couldn't already reach, and it doesn't lift the kb- write/delete reservation.

Limits & billing

  • Value size is measured in characters (JSON.stringify(value).length) and must not exceed the configured max (400 document_too_large).
  • Max documents per account is enforced when creating a new (non-kb-) document → 403 document_limit_reached. Updates to existing keys are always allowed.
  • Each successful op bills one unit: doc-read, doc-write, or doc-delete.

The kb-usage document

A read-only system document maintained per account. It lists your non-kb- documents:

{ "total": 12, "keys": ["notes", "app-state", "…"], "updated_at": "…" }

It reads like any kb- doc (billed as a read); users can't write or delete it, and it's exempt from the size and count caps.

Examples

# Create with your own key
curl -X PUT https://khabot.com/api/v1/documents/app-state \
  -H "Authorization: Bearer kb_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"theme":"dark","lastOpened":"c_42"}'

# Read it back
curl https://khabot.com/api/v1/documents/app-state \
  -H "Authorization: Bearer kb_YOUR_KEY"

# List your documents
curl https://khabot.com/api/v1/documents/kb-usage \
  -H "Authorization: Bearer kb_YOUR_KEY"

# Delete
curl -X DELETE https://khabot.com/api/v1/documents/app-state \
  -H "Authorization: Bearer kb_YOUR_KEY"