APIs

Your product, in five protocols.
One product model.

REST, GraphQL, gRPC, Realtime, and MCP — every surface is compiled from your product model. Project-published capability surfaces use the same projection path, so installed operations, command-backed actions, workflows, analytics, events, and agent skills appear through the same API authority.

Authentication

One token. Every surface.

Bearer tokens come from the identity provider you bound — Auth0, Clerk, WorkOS, custom OIDC, or API keys for machine-to-machine. Same token, same scopes, every surface.

import { createClient } from "@vadyl/sdk";

const vadyl = createClient({
  apiUrl:  "https://api.vadyl.app/v1",
  token:   process.env.VADYL_TOKEN!,
  tenant:  "acme",
  project: "billing",
});

// Every method auto-attaches the bearer + tenant + project headers
const me = await vadyl.identity.me();
Read

List orders — five protocols, one query

Filter, sort, paginate. The same conceptual operation across every surface.

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"],
});

console.log(recent.data, recent.page.next);
Write

Create a customer with idempotency

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

const customer = await vadyl.customers.create({
  email: "ada@example.com",
  name:  "Ada Lovelace",
}, {
  idempotencyKey: `signup:${session.id}`,
});
Realtime

Subscribe to change events

Field names only — never values. Subscribers re-read through CRUD with proper access enforcement to get values.

const sub = vadyl.orders.subscribe({
  filter: { status: { eq: "paid" } },
});

for await (const evt of sub.events()) {
  // evt.kind: "created" | "updated" | "deleted"
  // evt.entityId, evt.changedFields (names only — re-read for values)
  const order = await vadyl.orders.read(evt.entityId);
  console.log("order paid:", order);
}
Errors

One typed error contract — every surface

Stable code, stable reasonCode, correlation ID, explainability link. Build dashboards on reasonCodes, not parsed log strings.

import { VadylError, VadylAccessDeniedError } 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 VadylError) {
    console.error(err.code, err.message);
  } else {
    throw err;
  }
}
Spec discovery

Always-current API specs

Every project publishes its full spec at runtime. Generated from the product model on every publication. Never out of date.

Skip the protocol choice. Use a typed SDK.

The TypeScript, Python, C#, Go, and Rust SDKs sit above every surface. Same product operations, fully typed, branch-aware, manifest-verified.