Reference
gRPC
Compiled proto contracts with server reflection. Same canonical operations as REST and GraphQL.
RESTREST controller atlasEvery controller-backed endpoint with parameters, request examples, responses, errors, and samples.GraphQLGraphQL referenceCompiled SDL, query and mutation shapes, pagination, filters, subscriptions, errors, and examples.RealtimeRealtime & eventsWebSocket, SSE, event envelopes, subscription filters, replay, and field-name-only delivery.SDKSDK method referenceEvery client method across TypeScript, Python, C#, Go, and Rust with inputs, returns, and errors.ErrorsErrors referenceCanonical error envelopes, HTTP status mapping, machine-readable codes, reason codes, and correlation IDs.
Vadyl exposes every entity through gRPC with proto contracts compiled from the canonical entity model. Server reflection is enabled — clients can discover service shape at runtime.
Endpoint
grpc://api.vadyl.app:443
# or self-hosted gRPC portGenerated proto
For an entity Order:
syntax = "proto3";
package vadyl.app.v1;
service OrderService {
rpc Get (GetOrderRequest) returns (Order);
rpc List (ListOrderRequest) returns (ListOrderResponse);
rpc Create (CreateOrderRequest) returns (Order);
rpc Update (UpdateOrderRequest) returns (Order);
rpc Delete (DeleteOrderRequest) returns (DeleteResult);
// Streaming change events
rpc Watch (WatchOrderRequest) returns (stream OrderEvent);
}
message Order {
string id = 1;
string total = 2; // decimal as string
string currency = 3;
OrderStatus status = 4;
string customer_id = 5;
google.protobuf.Timestamp created_at = 6;
}
enum OrderStatus {
ORDER_STATUS_UNSPECIFIED = 0;
ORDER_STATUS_PENDING = 1;
ORDER_STATUS_PAID = 2;
ORDER_STATUS_FULFILLED = 3;
ORDER_STATUS_REFUNDED = 4;
}Authentication
Bearer tokens via metadata, in any language:
import { createGrpcTransport } from "@connectrpc/connect-node";
import { createClient } from "@connectrpc/connect";
import { OrderService } from "./vadyl_app_v1/order_pb_connect";
const transport = createGrpcTransport({
baseUrl: "https://api.vadyl.app",
interceptors: [(next) => async (req) => {
req.header.set("authorization", `Bearer ${process.env.VADYL_TOKEN}`);
req.header.set("x-vadyl-tenant", "acme");
req.header.set("x-vadyl-project", "billing");
return next(req);
}],
});
const orders = createClient(OrderService, transport);Calling unary RPCs
// rpc List(ListOrderRequest) returns (ListOrderResponse)
ListOrderResponse resp = stub.List(ListOrderRequest.newBuilder()
.setFilter(OrderFilter.newBuilder()
.addAllStatus(List.of(OrderStatus.ORDER_STATUS_PAID))
.setTotal(NumericFilter.newBuilder().setGt("100")))
.addSort(Sort.newBuilder().setField("createdAt").setDirection(SORT_DESC))
.setPageSize(50)
.addInclude("customer")
.build());Streaming change events
// rpc Watch(WatchOrderRequest) returns (stream OrderEvent)
Error model
Errors use standard gRPC status codes plus typed details:
Status code: PERMISSION_DENIED
Message: Access denied for read on Order
Details:
- vadyl.app.v1.ErrorDetail
code: "ACCESS_DENIED"
reason_code: "Access.DeniedByMissingClaim"
correlation_id:"01HXY..."Reflection
Server reflection is enabled out of the box. Discover services with grpcurl:
grpcurl api.vadyl.app:443 list
grpcurl api.vadyl.app:443 describe vadyl.app.v1.OrderServicePull the proto
# Download the proto bundle
curl https://api.vadyl.app/grpc/proto/vadyl-app.proto > vadyl.proto
# Generate clients yourself
protoc --go_out=. --go-grpc_out=. vadyl.proto
protoc --plugin=protoc-gen-ts_proto --ts_proto_out=. vadyl.proto