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.
Pick a protocol — your product looks the same
REST
Idiomatic resources under /api/{entity}. OpenAPI 3.1 spec at /api/openapi.json. Cursor pagination by default.
GraphQL
Compiled SDL with connection-style pagination, typed inputs, subscription channels.
gRPC
Proto contracts with server reflection. Streaming change events. Standard status codes.
Realtime
WebSocket and SSE subscriptions. Same predicate AST as queries. Field names only — never values.
Webhooks
Inbound + outbound. HMAC-signed. 5-state delivery machine. Idempotent under at-least-once.
MCP
Model Context Protocol projection. tools/list filtered by capability grants. tools/call dispatches through the same pipeline as REST.
Installed project surfaces
Provider projects publish capability manifests; consumer projects install them as first-class API, SDK, CLI, MCP, realtime, webhook, and dashboard surface.
Exact contracts for every API surface
The overview explains the model; the references are the authoritative contract pages for endpoints, protocol metadata, schemas, errors, and examples.
REST controller atlas
Every controller-backed endpoint with parameters, request examples, responses, errors, and samples.
REST API model
Base URLs, resource conventions, pagination, idempotency, error envelopes, OpenAPI discovery, and examples.
OpenAPI & Swagger
Spec discovery, operation IDs, schema projection, Swagger UI behavior, and client generation.
GraphQL reference
Compiled SDL, query and mutation shapes, pagination, filters, subscriptions, errors, and examples.
gRPC reference
Proto services, metadata, streaming, status mapping, deadlines, reflection, and generated clients.
Realtime & events
WebSocket, SSE, event envelopes, subscription filters, replay, and field-name-only delivery.
Webhooks reference
Inbound and outbound delivery, signatures, retries, replay, idempotency, and receiver contracts.
MCP reference
JSON-RPC methods, resource metadata, token model, tools, resources, prompts, errors, and observability.
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();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);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}`,
});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);
}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;
}
}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.