All SDKs
TS

TypeScript SDK

@vadyl/sdk
Available
The TypeScript SDK is Vadyl's flagship client. Strict types end-to-end, ESM-first, runs on Node.js 18+, Bun, Deno, and edge runtimes.

Install

npm
npm install @vadyl/sdk
yarn
yarn add @vadyl/sdk
pnpm
pnpm add @vadyl/sdk
bun
bun add @vadyl/sdk
Read the documentation
1. Initialize

Create the client

Configure the client once. Same object reaches every product surface — entities, workflows, agents, realtime.

client.tsTypeScript
import { createClient } from "@vadyl/sdk";

export const vadyl = createClient({
  apiUrl:  "https://api.vadyl.app/v1",
  token:   process.env.VADYL_TOKEN!,
  tenant:  "acme",
  project: "billing",
  // optional — pin to a feature branch
  branch:  process.env.VADYL_BRANCH,
});
2. Read

List, filter, paginate

Typed filter expressions, cursor pagination, eager relation loading.

list-orders.tsTypeScript
// Typed filter, sort, pagination, and relation expansion
const recent = await vadyl.orders.list({
  filter: {
    status:    { in: ["paid", "fulfilled"] },
    total:     { gt: 100 },
    createdAt: { gte: "now-30d" },
  },
  sort:     [{ field: "createdAt", direction: "desc" }],
  pageSize: 50,
  include:  ["customer", "items.product"],
});

// recent.data: Order[]
// recent.page: { number, size, totalCount?, next?, prev? }
console.log(recent.data.length, recent.page.next);
3. Write

Create, update, delete with idempotency

Every mutation supports idempotency keys. Retries are safe by default.

create-customer.tsTypeScript
// Idempotent create — safe to retry
const customer = await vadyl.customers.create((
  { email: "ada@example.com", name: "Ada Lovelace" },
  { idempotencyKey: `signup:${session.id}` },
));

// Update with optimistic concurrency
const updated = await vadyl.customers.update(
  customer.id,
  { name: "Ada L." },
  { ifMatch: customer.concurrencyToken },
);

// Delete (soft delete on entities with that lifecycle)
await vadyl.customers.delete(customer.id);
4. Realtime

Subscribe to entity changes

Field names only — never values. Re-read for values through CRUD with proper access enforcement.

subscribe.tsTypeScript
// WebSocket subscription with the same filter AST as queries
const sub = vadyl.orders.subscribe({
  filter: { status: { eq: "paid" } },
  kinds:  ["created", "updated"],
});

for await (const evt of sub.events()) {
  // evt: { kind, entityId, changedFields, occurredAt }
  // Field NAMES only — never values (defense-in-depth)
  const order = await vadyl.orders.read(evt.entityId);
  console.log("paid:", order);
}
5. Workflows

Start and signal durable workflows

Long-running product behavior that survives process restart. Same client interface; canonical durability underneath.

workflow-client.tsTypeScript
// Start a durable workflow
const run = await vadyl.workflows.fulfillOrder.start({
  orderId: "ord_abc",
});

// Send a signal (e.g. from a webhook)
await vadyl.workflows.fulfillOrder.signal(run.id, "shipped", {
  trackingNumber: "1Z...",
});

// Query run state
const state = await vadyl.workflows.fulfillOrder.query(run.id);
6. Agents

Run agents against the product model

Typed plan IR, capability-aware model routing, token accounting — all behind one method.

run-agent.tsTypeScript
// Run an agent — typed plan IR, capability-aware model routing
const run = await vadyl.agents.SupportAgent.run({
  prompt: "Refund order #12345 due to defect",
  userId: session.userId,
  budget: { maxTokens: 50_000, maxToolCalls: 30 },
});

// Stream the run
for await (const step of run.stream()) {
  console.log(step.kind, step.summary);
}

// Recall memory for an agent
const facts = await vadyl.agents.SupportAgent.memory.recall({
  kind: "preference",
  subject: session.userId,
});
7. Errors

Typed error contract

Stable error codes, stable reason codes, correlation IDs, and explainability links.

errors.tsTypeScript
import {
  VadylError,
  VadylAccessDeniedError,
  VadylValidationError,
  VadylConflictError,
  VadylQuotaExceededError,
} from "@vadyl/sdk";

try {
  await vadyl.orders.update(id, { status: "refunded" });
} catch (err) {
  if (err instanceof VadylAccessDeniedError) {
    console.warn(err.reasonCode, err.correlationId);
  } else if (err instanceof VadylConflictError) {
    // optimistic-concurrency mismatch — re-read and retry
  } else if (err instanceof VadylError) {
    console.error(err.code, err.message);
  } else {
    throw err;
  }
}
8. Authoring runtime

Define handlers, workflows, agents

The same package you use as a client also powers your authored runtime — defineCoreHandler, defineWorkflow, defineAgent.

src/handlers/orders/charge.tsTypeScript
import { handler } from "@vadyl/sdk";

export default handler.core(async (ctx, input: { orderId: string }) => {
  const order = await ctx.entities.Order.read(input.orderId);

  const charge = await ctx.connections.stripe.createCharge({
    amount: order.total,
    currency: order.currency,
    idempotencyKey: `charge:${order.id}`,
  });

  await ctx.entities.Order.update(order.id, {
    status: "paid",
    chargeId: charge.id,
  });

  await ctx.events.emit("order.paid", { orderId: order.id });
  return { ok: true, chargeId: charge.id };
});

What you get

Fully typed entities

Every entity, field, relation, enum, and operation is strictly typed. Zero runtime type assertions.

Manifest verification

The SDK refuses to talk to a server whose generated-format version it does not support. Fail closed.

Realtime built-in

WebSocket and SSE subscriptions with the same predicate AST as queries. Reconnect-safe.

Authoring runtime

The same package powers your handlers and workflows. defineCoreHandler, defineWorkflow, defineAgent.

Universal runtime

Run anywhere from Node and Bun to edge runtimes. ESM and CJS. No native deps.

Branch-aware

Work against feature branches by setting branch in your client config. Sandbox testing without leaving prod.

Observability hooks

Hook into the canonical envelope. Emit operational trails from the client when needed.

Agent primitives

vadyl.agents exposes the Agent plane: definitions, runs, memory, MCP.

Connections

Typed governed-connection clients per registered governed connection.

Build with the TypeScript SDK in minutes.

Install the package and work with your product model through typed entities, workflows, agents, and events.