Skip to main content
LambdaDB data versioning provides named histories for the knowledge or memory stored in a collection. Every collection starts with a default branch named main. Refs are scoped to one collection. Branch merge, direct branch reset, ref rename, and cross-collection snapshot sharing are not part of this API. Branch, tag, and alias names must contain 3 to 52 letters, numbers, underscores, or hyphens.

Use the SDKs

Install a supported SDK version and use your project’s connection details from LambdaDB Cloud. These examples assume an existing knowledge-base collection with a title text field and no branch named candidate. Run one language example or the REST alternative below, not both against the same branch name. The Go function accepts a client configured as shown in the Quickstart.
This fetch includes eligible pending writes on candidate; it does not prove that a snapshot has committed. Before creating a tag, verify the intended committed data with consistentRead: false. See Consistent reads for limits and the bulk-import exclusion. The SDK functions below take an initialized client and use the same knowledge-base collection. Call Python functions inside the client’s with LambdaDB(...) as client: block, before it closes. Each example states its required refs and data; they are not an automatic sequence after the write above.

Create and list branches

Create a branch from main:
Omit source to use main. A branch can be created only from another branch in the same collection; tag and alias sources return 400 BadRequest. A branch created from an empty source has explicitly null headSnapshot and parentSnapshot, but parentBranch still identifies the source branch. Branch creation copies the source’s committed state. It does not copy pending writes. Schema and retention updates remain collection-scoped; tag reads use their pinned schema.
List branches:
The response contains a branches array with the same fields as the create response: When created from a nonempty source, a branch initially has matching head and parent snapshots. The head can advance while the parent stays fixed. Parent metadata does not guarantee that the original snapshot remains available beyond retention. Branch responses do not have a top-level snapshotId. parentBranch records the requested source branch, not the branch where the selected snapshot originated. For example, a branch created from dev records dev even if its snapshot originated on main, including when selected through asOf. This historical metadata does not prevent deleting the parent branch. Deleting the parent or recreating its name does not change the recorded identity.

Point-in-time branches

Set source.asOf to select the latest committed snapshot at or before that Unix epoch-millisecond timestamp:
asOf is valid only when source.kind is branch. Missing or no-longer-retained history returns 400 BadRequest. It selects committed history, so it cannot recover a write that was still pending at the requested time. There is no public snapshot-history-list API. Pass a cutoff within your collection’s retained history. The new recovery-check branch must not already exist. Python takes epoch milliseconds; TypeScript accepts a Date, and Go accepts time.Time through its source helper:

Create and list tags

A tag pins one committed snapshot and cannot be retargeted:
Omit source to pin the current main snapshot. The create response wraps the ref in tag; GET .../tags returns a tags array. A tag source can be a branch or another tag in the same collection, but not an alias. Creating a tag from a tag pins the same snapshot; it does not create a chain of tags. source.asOf is allowed only for a branch source. Tag responses contain name, snapshotId, snapshotCommittedAt, and createdAt. Unlike branch responses, the snapshot fields are at the top level of the tag object. snapshotCommittedAt is the pinned snapshot’s commit time, while createdAt is the tag’s creation time; both use Unix epoch milliseconds.
A tag cannot be created from an empty head. Verify the intended committed data with consistentRead: false before creating a release tag; a read that includes pending writes does not prove those writes will be captured by the tag. Ref lists are unpaginated, and there are no individual branch, tag, or alias GET routes.

Create, retarget, and list aliases

An alias points to a branch or tag:
Retarget it without changing the alias name used by readers:
GET .../aliases returns an aliases array. Alias objects include aliasId, aliasName, targetKind, targetName, targetId, aliasRevision, dangling, and epoch-millisecond createdAt. Request kind values are lowercase; response targetKind values are BRANCH or TAG. Deleting a non-default branch or a tag that is referenced by any alias returns 409 Conflict. Delete or retarget every referencing alias before deleting the target; retrying the same deletion without changing those references will not resolve the conflict. Deleting an alias does not delete its target. Aliases bind to the target’s identity, not just its name. The response retains a dangling field for a missing target; if such a state is encountered, reads return 400 BadRequest. It is not the normal result of target deletion, which is blocked while aliases reference it. Recreating a target name does not repair the old identity binding. Selecting a ref that does not exist returns 404 ResourceNotFound.

Publish a tag through an alias with the SDKs

First verify that candidate contains the intended committed data using a fetch or query with consistentRead: false. The following example assumes that verification is complete and that neither validated-2026-09 nor production-read exists. It pins a tag, creates an alias initially targeting main, switches that alias to the tag, and reads through the alias. For an existing alias, use only the retarget call instead of creating it again.

Read from a ref

Query, fetch, and extended list request bodies accept:
ref.kind accepts branch, tag, or alias. Add this object alongside the endpoint’s normal fields. Omitting ref reads from main. The GET list endpoint has no request body. Supply refKind and refName together:
Supplying only one of refKind or refName is invalid.

Consistent reads

Query and fetch requests support consistentRead: true only when they directly select a branch. Tag and alias reads reject it, including an alias that currently targets a branch. Consistent reads overlay eligible pending writes on committed data. They can return 429 when that pending payload exceeds the limit, independently of request rate limits. Pending bulk imports are excluded and become visible only after indexing commits them. List requests do not support consistentRead. Page tokens record a search position, not a fixed snapshot. Branches can advance and aliases can move between pages. Use the same immutable tag on every page for a stable export, keeping filters and projection options unchanged. Query responses do not include a resolved snapshot ID.

Iterate over a tag with the SDKs

These examples assume validated-2026-09 already exists. Each pagination helper keeps the same tag on subsequent requests. Python pages contain document dictionaries; TypeScript and Go pages contain result items whose doc or Doc field holds the document.

Write to a branch

Upsert, update, delete, and bulk-upsert request bodies accept an optional branch string. Omitting it writes to main.
The value is resolved as a branch name. A tag or alias is not a valid write target. For bulk upsert, use the same branch for both control calls:
Set Content-Type to the response’s type value and send every entry in its headers map unchanged with the presigned PUT.

Delete a ref

Delete a named ref with its type-specific route:
The default main branch cannot be deleted independently from its collection; an attempt returns 400 BadRequest. Other branches and tags cannot be deleted while any alias references them (409 Conflict). Delete or retarget those aliases first. Deleting a ref does not delete the collection. The default branch cannot be changed. Deleting an already absent ref can return 404.