Sevro

TypeScript Integration

Call the Sevro API from TypeScript with full type safety using Connect-RPC.

Sevro's API is defined with Protocol Buffers and served via Connect-RPC. You can generate fully typed TypeScript clients from the proto definitions and call the API from any frontend or Node.js application.

Prerequisites

  • Node.js 18+
  • The buf CLI (install)

Step 1: Generate TypeScript clients

Create a buf.gen.yaml in your project:

version: v2
plugins:
  - remote: buf.build/bufbuild/es:v2.12.1
    out: src/gen
    include_imports: true

Point buf at Sevro's proto files. Either copy the proto files from the Sevro repo, or reference them via the Buf Schema Registry (if published).

Generate the code:

buf generate

This produces *_pb.js and *_pb.d.ts files — fully typed message constructors and serializers.

Step 2: Install Connect-RPC client

npm install @connectrpc/connect-web

Step 3: Create a transport

import { createConnectTransport } from "@connectrpc/connect-web";

const transport = createConnectTransport({
  baseUrl: "http://localhost:8080",
  interceptors: [authInterceptor],
});

// Inject the API key into every request
const authInterceptor = (next) => async (req) => {
  req.header.set("Authorization", `Bearer ${SEVRO_API_KEY}`);
  return next(req);
};

Step 4: Call the API

import { createClient } from "@connectrpc/connect";
import { PlatformService } from "./gen/platform/v1/platform_pb";
import { CreateModuleRequest } from "./gen/platform/v1/platform_pb";

const client = createClient(PlatformService, transport);

// Create a module
const resp = await client.createModule(
  new CreateModuleRequest({
    name: "todo",
    entities: [{
      ref: "todo",
      label: "Todo",
      attributes: [
        { ref: "description", label: "Description", type: "string", isRequired: true }
      ],
      methods: [{
        ref: "new",
        label: "New",
        isConstructor: true,
        parameters: [
          { ref: "description", label: "Description", type: "string", isRequired: true }
        ],
        actions: [
          { target: "description", expression: "params.description" }
        ]
      }]
    }]
  })
);
console.log("Module created:", resp.id);

// Execute a method (create a todo)
const result = await client.executeMethod({
  moduleId: resp.id,
  entityRef: "todo",
  methodRef: "new",
  arguments: {
    description: "Buy groceries"
  }
});
console.log("Record created:", result.recordId);

// List records
const list = await client.listRecords({
  moduleId: resp.id,
  entityRef: "todo",
  filter: 'record.completed == false'
});
for (const record of list.records) {
  console.log(record.fields?.description);
}

Using with TanStack Query

For React applications, @connectrpc/connect-query provides automatic integration with TanStack Query:

npm install @connectrpc/connect-query @tanstack/react-query
import { useQuery, useMutation } from "@connectrpc/connect-query";
import { PlatformService } from "./gen/platform/v1/platform_pb";

function TodoList({ moduleId }: { moduleId: string }) {
  const { data, isLoading } = useQuery(PlatformService.method.listRecords, {
    moduleId,
    entityRef: "todo",
  });

  if (isLoading) return <p>Loading...</p>;

  return (
    <ul>
      {data?.records?.map((record) => (
        <li key={record.id}>{record.fields?.description}</li>
      ))}
    </ul>
  );
}

function CreateTodo({ moduleId }: { moduleId: string }) {
  const mutation = useMutation(PlatformService.method.executeMethod);

  const handleCreate = async () => {
    await mutation.mutateAsync({
      moduleId,
      entityRef: "todo",
      methodRef: "new",
      arguments: { description: "New todo" },
    });
  };

  return <button onClick={handleCreate}>Create Todo</button>;
}

Environment variables

Store your API key in an environment variable — never commit it to source control:

# .env.local
SEVRO_API_KEY=ply_abc123...
SEVRO_SERVER=http://localhost:8080
const transport = createConnectTransport({
  baseUrl: process.env.SEVRO_SERVER,
  interceptors: [authInterceptor],
});

const authInterceptor = (next) => async (req) => {
  req.header.set("Authorization", `Bearer ${process.env.SEVRO_API_KEY}`);
  return next(req);
};

Reference implementation

The Sevro admin UI (admin/ directory in the Sevro repo) is a complete reference implementation built with:

  • React 19 + TanStack Router + TanStack Query
  • @connectrpc/connect-web for the transport
  • @connectrpc/connect-query for React hooks
  • Tailwind CSS + shadcn/ui for styling

Browse the source at admin/src/lib/transport.ts and admin/src/api/ to see the full pattern.

On this page