Skip to main content
A delta is a reviewable set of staged changes. Every write to the graph goes through one. You build it up with entities and relationships, preview the diff, then commit it. If a commit was a mistake, you revert it. pb.capture and pb.extract are conveniences over this primitive: they open a delta, stage into it, and (by default) apply it in a single call. Reach for pb.deltas.* when you want to assemble a change across several calls, inspect it before it lands, or undo one that already landed.

Create a client

import { createPenumbra } from "@penumbra-systems/platform";

const pb = createPenumbra({ apiKey: process.env.PENUMBRA_API_KEY! });

Methods

MethodDescription
pb.deltas.create(input)Open a new delta.
pb.deltas.get(id)Read a delta and its staged contents.
pb.deltas.addEntities(id, entities)Stage entities.
pb.deltas.addRelationships(id, rels)Stage relationships.
pb.deltas.submit(id)Mark the delta ready.
pb.deltas.plan(id)Preview how applying it would change the graph.
pb.deltas.apply(id)Commit the delta to the graph.
pb.deltas.revertPreview(id)Preview undoing an applied delta.
pb.deltas.revert(id)Revert an applied delta.

Build, plan, and apply

Open a delta, stage entities and relationships into it, mark it ready, preview the diff, then commit.
1

Create

const delta = await pb.deltas.create({ name: "Q3 deal notes" });
2

Stage entities

await pb.deltas.addEntities(delta.id, [
  { type: "Account", name: "Acme", properties: { tier: "enterprise" } },
  { type: "Contact", name: "Dana Reyes", properties: { role: "CFO" } },
]);
3

Stage relationships

Address endpoints by staged-entity position: from_entity_index / to_entity_index refer to the order entities were staged (here: Acme 0, Dana Reyes 1). To connect to nodes already committed in the graph, use from_node_id / to_node_id instead.
await pb.deltas.addRelationships(delta.id, [
  { type: "WORKS_AT", from_entity_index: 1, to_entity_index: 0 },
]);
4

Submit and plan

Mark the delta ready, then preview how applying it would change the graph before anything commits.
await pb.deltas.submit(delta.id);
const plan = await pb.deltas.plan(delta.id);
5

Apply

await pb.deltas.apply(delta.id);
Always plan before you apply when the delta was assembled from several calls. The plan shows what will be created or changed so you can catch mistakes while they are still cheap to undo.

Revert

An applied delta can be undone. Preview the revert first, then run it.
const undo = await pb.deltas.revertPreview(delta.id);
// inspect undo, then commit the reversal
await pb.deltas.revert(delta.id);
revertPreview only previews; nothing changes until you call revert. Revert applies to a delta that was already committed with apply.

Relationship to capture and extract

The same staging happens whether you go through the primitive or the conveniences:
  • pb.capture({ ..., apply: false }) opens a delta, stages one entity, and leaves it for you to inspect.
  • pb.extract({ ..., apply: false }) runs text through a shape and stages the extracted entities and relationships into a delta.
  • Passing apply: false on either stages without committing; the returned receipt carries the deltaId, which you can then plan, apply, or revert here.
See Capture and extract for the wrapper surface.