ServicesLive JSON

Live JSON

A real-time collaborative JSON document store: documents carry arbitrary JSON content plus metadata, support full replacement and JSONPath patching, cooperative locks with expiry, and a per-document WebSocket that streams changes at subscribed paths.

When to reach for it: shared application state that several clients edit and watch - collaborative settings panels, live dashboards, game or agent blackboards, any JSON blob where "someone changed it" must reach other clients instantly.

When not to: ephemeral broadcast with no document behind it belongs to Pub/Sub; plain JSON storage with TTL, tags, and search - but no change feed - belongs to the KV Store.

Concepts

  • A document is content plus metadata. Content is any JSON value; metadata is the name, description, tags, TTL, size, owner, and lock state. IDs are auto-generated (doc_...) unless you pass --id.
  • Reads have three views - meta (the default), content, and full. A bare get returns metadata only, not your JSON; this is the most common surprise.
  • Two write granularities - replace the entire content, or patch a single JSONPath with set, delete, append, or insert.
  • The document ID is the capability. Any authenticated user who has the ID can read the document and patch its content. Owner-only operations are delete, metadata updates, and put of an existing document. list shows only your own documents, so handing out an ID is how you share one.
  • Locks are cooperative write exclusivity - while one user holds a lock, other users' content writes fail with 409; the lock expires on its own.
  • Realtime is per-document - each document has its own WebSocket endpoint, and subscriptions watch a JSONPath within it. See Real-time subscriptions.

Create and read

snug live-json create -c '{"count":0,"theme":"light"}' -n "My Counter"
snug live-json create -c '{"a":1}' --id build-status --ttl 300

snug live-json get -d doc_vgDjAtvHYhar                 # metadata only (default)
snug live-json content -d doc_vgDjAtvHYhar             # JSON body only
snug live-json full -d doc_vgDjAtvHYhar                # both
snug live-json get -d doc_vgDjAtvHYhar --view content  # same as the shortcut

The create response returns only id and created_at - fetch metadata (owner, size, lock state, TTL) with get. Over HTTP the same create is POST /api/v1/live-json/documents:

curl -X POST -H "Authorization: Bearer $SNUG_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"content": {"count": 0}, "name": "My Counter"}' \
  http://localhost:4000/api/v1/live-json/documents
{
  "status": 201,
  "msg": "Created",
  "data": {
    "id": "doc_jbnMLXXKbDYP",
    "created_at": "2026-08-28T04:33:59.074801Z"
  }
}

Reading a missing document is 404 NOT_FOUND.

Updating content

patch edits one JSONPath; replace swaps the whole content; put creates-or-replaces the document itself at a chosen ID (and is owner-only when the document already exists):

snug live-json patch -d doc_vgDjAtvHYhar -p '$.count' -v '5'            # set (default)
snug live-json patch -d doc_vgDjAtvHYhar -p '$.items' -v '"b"' -o append
snug live-json patch -d doc_vgDjAtvHYhar -p '$.theme' -v 'null' -o delete
snug live-json replace -d doc_vgDjAtvHYhar -c '{"count":5,"items":["a"]}'
snug live-json metadata -d doc_vgDjAtvHYhar -n "Renamed"                # metadata only

All patch operations were verified live: set overwrites the value at the path, append pushes onto an array, delete removes the field (-v is still required but ignored). Sibling fields survive a patch; only replace and put are destructive to the rest of the document.

Locking

A lock grants its holder exclusive write access until it expires (default 60 seconds). The full conflict matrix, reproduced live:

snug live-json lock -d doc_vgDjAtvHYhar --duration 120
  • Another user's patch/replace while locked: 409 CONFLICT "Document is locked by another user". The holder's own writes succeed.
  • Another user's lock attempt: 409 document_locked.
  • unlock by anyone but the holder: 400 lock_not_held.
  • unlock by the holder releases immediately; otherwise the lock simply expires.

Locks gate content writes only - they do not block reads. For locks not tied to a document, use Distributed State.

Finding documents

snug live-json list --limit 50 --search counter
snug live-json stats

list returns metadata (no content) plus the standard pagination object (20 per page by default), and only ever your own documents - --search matches names. stats reports live subscription counts: total_subscriptions, documents_watched, connections_active.

Behaviors and gotchas

  • get is metadata by default. Reach for the content or full shortcuts when you want your JSON.
  • Cross-user writes are allowed by design. A second user with the ID can patch your document (verified live); use a lock when you need exclusivity. Delete, put of an existing document, and metadata updates by a non-owner fail with 403.
  • --shared is a metadata flag only. It sets is_shared on the document but does not change visibility today: any user with the ID can already read, and list never shows other users' documents.
  • TTL is set at create time (--ttl, seconds) or via metadata; the document expires as a whole.

Real-time change feeds

The WebSocket endpoint, the socket message protocol, the CLI watch command, and the HTTP subscribe API have their own page: Real-time subscriptions.

Reference

On this page