API Reference
Core
initSegment
Creates Next.js App Route handlers for the main Optional Catch-all Segment .
The function accepts:
segmentName?: string– the segment name used in the route. Defaults to an empty string (the root segment).controllers: Record<string, Function>– a record of controllers.exposeValidation?: boolean– set tofalseto hide validation logic from client-side code. Defaults totrue.emitSchema?: boolean– set tofalseto skip emitting the schema for the segment. Defaults totrue.onError?: (err: Error, req: VovkRequest) => void | Promise<void>– called when a controller throws. Can be used for logging. The second argument can be used to access the request URL, authorization data, and other request details.
JSONLinesResponder
JSONLinesResponder is a utility class for creating responses in the JSON Lines format. It provides methods to send individual JSON objects as lines in the response stream.
const responder = new JSONLinesResponder<IterationType>(req, ({ readableStream, headers }) => new Response(readableStream, { headers }));
await responder.send({ message: 'Hello' });
await responder.send({ message: 'World' });Accepts:
req?: Request– the incoming request object.getResponse?: (responder: JSONLinesResponder<T>) => Response– optional factory function to create a customResponseobject.
Provides the following methods and properties:
send(item: T): Promise<void>– Sends a single JSON object as a line in the response stream.close(): Promise<void>– Closes the response stream, indicating that no more data will be sent.throw(err: Error): Promise<void>– Sends an error message to the client and closes the stream.response: Response– The underlyingResponseobject that will be returned from the Next.js route handler.headers: Record<string, string>– Thecontent-typefor the response.readableStream: ReadableStream<Uint8Array>– The readable stream used as the response body.
See the JSON Lines documentation for more details.
toDownloadResponse
Utility for constructing a Response that returns binary content (for example, audio, images, or arbitrary files) with appropriate headers. It can be used directly in controllers and is also compatible with MCP tool output formatting when returning Response objects.
Example (serving audio):
import { get, toDownloadResponse } from 'vovk';
export default class MediaController {
@get('audio')
static getAudio() {
return toDownloadResponse(buffer, { contentType: 'audio/mpeg' });
}
}Decorators
@get, @post, @put, @patch, @del, @head, @options
HTTP method decorators define the HTTP method for a handler. They accept two optional arguments:
path? = ''– the path segment for the route.opts?: { cors?: boolean, headers?: Record<string, string>, staticParams?: Record<string, string>[] }– route options:- If
corsistrue, CORS headers are added to the response, and theOPTIONSmethod is handled automatically. headersis an object with headers that will be added to the response.staticParams(@getdecorator only) is an array of objects with static parameters that can be used in the route path, for example[{ id: '123' }].
- If
import { get } from 'vovk';
export default class HelloController {
@get('world', { cors: true, headers: { 'x-hello': 'world' }, staticParams: [{ id: '123' }] })
static getHelloWorld(req, { id }: { id: string }) {
return { hello: 'world', id };
}
}Each HTTP method decorator has an .auto() helper that can be used to generate the path automatically based on the controller and method names. It accepts the same options as the decorator itself.
import { get } from 'vovk';
export default class HelloController {
@get.auto({ cors: true, headers: { 'x-hello': 'world' }, staticParams: [{ id: '123' }] })
static getHelloWorld(req, { id }: { id: string }) {
return { hello: 'world', id };
}
}@prefix
The @prefix(p: string) decorator is used to prepend a sub-path to all endpoints of a controller. Its use is optional.
import { prefix, get } from 'vovk';
@prefix('hello')
export default class HelloController {
@get('world')
static getHelloWorld() {
return { hello: 'world' };
}
}@operation
The @operation(openAPIOperationObject) decorator attaches OpenAPI documentation to a procedure. It accepts an object with summary, description, and any other OpenAPI Operation Object properties.
It also exposes a tool helper that can be used to add AI tool–related metadata, stored under the x-tool key of the operation object. Read more on the Deriving AI Tools page.
import { operation } from 'vovk';
export default class HelloController {
@operation.tool({
title: 'Get Hello World',
})
@operation({
summary: 'Get Hello World',
description: 'Returns a hello world message',
})
@get('world')
static getHelloWorld() {
return { hello: 'world' };
}
}@cloneControllerMetadata
Each controller belongs to a single segment. If you want to reuse a controller in other segments, you can use the @cloneControllerMetadata decorator on a new class that extends the original controller. This copies all metadata (routes, operations, etc.) from the original controller to the new one. Note that the prefix is not inherited, so you may want to add a new prefix to the cloned controller.
import { prefix, cloneControllerMetadata } from 'vovk';
import UserController from './UserController';
@cloneControllerMetadata()
@prefix('v2')
export default class UserControllerV2 extends UserController {}Utils
createDecorator
createDecorator is a higher-order helper for building procedure decorators. It accepts a middleware function with the following parameters:
req: VovkRequest– the request object.next: () => Promise<any>– a function that calls the next middleware or the actual handler.- Additional arguments – any extra values passed to the decorator factory.
The second argument is a schema modifier function that can be used to adjust the procedure schema based on the decorator arguments.
import { createDecorator, get } from 'vovk';
const myDecorator = createDecorator(
(req, next, a: string, b: number) => {
// do something with the request
},
(a: string, b: number) => {
// modify schema here
}
);
export default class MyController {
@get.auto()
@myDecorator('foo', 1) // Passes 'foo' as 'a', and 1 as 'b'
static doSomething() {
// ...
}
}See the decorator docs for more details.
fetcher
Function that creates a data-fetching layer for the RPC client. It is used by default when the fetcher is not customized. A new fetcher can be created using the createFetcher function.
createFetcher
Function that creates a custom fetcher for the RPC client. It accepts a generic type parameter that defines additional options for the resulting RPC methods. The function returns a fetcher function that will be used in createRPC.
import { createFetcher } from 'vovk';
export const fetcher = createFetcher<{
successMessage?: string; // "Successfully created a new user"
useAuth?: boolean; // if true, Authorization header will be set
someOtherCustomFlag?: boolean; // any custom flag that you want to pass to the RPC method
}>({
prepareRequestInit: async (init, { useAuth, someOtherCustomFlag }) => {
// ...
return {
...init,
headers: {
...init.headers,
...(useAuth ? { Authorization: 'Bearer token' } : {}),
},
};
},
transformResponse: async (data, { someOtherCustomFlag }) => {
// ...
return {
...data,
};
},
onSuccess: async (data, { successMessage }) => {
if (successMessage) {
alert(successMessage);
}
},
onError: async (error) => {
alert(error.message);
},
});See the fetcher docs.
controllersToStaticParams
Function that generates an API surface at build time instead of on-demand at request time. It accepts a record of controllers and an optional slug that is used to build the static API path. The function returns an array of static parameters that can be consumed by generateStaticParams.
// ...
export type Controllers = typeof controllers;
export function generateStaticParams() {
return controllersToStaticParams(controllers);
}
export const { GET } = initSegment({ controllers });See the segment documentation for more details.
multitenant
A Next.js proxy utility that routes subdomains to specific segments.
// ... proxy ...
const { action, destination, message, subdomains } = multitenant({
requestUrl: request.url,
requestHost: request.headers.get('host') ?? '',
targetHost: process.env.VERCEL ? 'multitenant.vovk.dev' : 'localhost:3000',
overrides: {
// ...
},
});
// ...For more information, see the multitenant guide.
deriveTools
Utility that turns RPC modules or controllers into AI tools based on the input schemas of their methods.
The function accepts the following options:
modules: Record<string, object>– key-value object where keys are module names and values are objects with methods. Each method should have aschema: VovkHandlerSchemaproperty and eitherisRPC: true(for RPC modules) or the fn function (for controllers).onExecute?: (result: unknown) => void | Promise<void>– called after each tool execution. Receives the result and an object with additional details.onError?: (e: Error) => void | Promise<void>– called when an error is thrown during tool execution.toModelOutput– function that formats the tool result into a model-friendly output.meta?: Record<string, any>– data attached as themetaproperty of each function (controller handler or RPC method).
import { deriveTools } from 'vovk';
import { UserRPC } from 'vovk-client';
import TaskController from '@/modules/task/TaskController';
const { tools, toolsByName } = deriveTools({
meta: { hello: 'world' },
modules: {
UserRPC,
TaskController,
},
resultFormatter: (result) => `Result: ${JSON.stringify(result, null, 2)}`,
onExecute: (result, { moduleName, handlerName, body, query, params }) =>
console.log(`${moduleName}.${handlerName} executed with`, {
body,
query,
params,
result,
}),
onError: (e) => console.error('Error', e),
});For more details, see the Deriving AI Tools guide.
createTool
Utility for defining standalone (non-derived) tools by implementing the VovkTool shape with optional input/output schemas and optional model-output formatting.
Options:
name: string— tool name.title?: string— optional title (primarily for MCP).description: string.toModelOutput?: ToModelOutputFn<...>— custom formatter or a built-in formatter fromToModelOutput.inputSchema?: StandardSchemaV1 & StandardJSONSchemaV1.outputSchema?: StandardSchemaV1 & StandardJSONSchemaV1.execute: (input) => Promise<output> | output.
Example:
import { createTool, ToModelOutput } from 'vovk';
import { z } from 'zod';
const sumNumbers = createTool({
name: 'sum_numbers',
title: 'Get Sum of two Numbers',
description: 'Returns the sum of two numbers provided as input.',
toModelOutput: ToModelOutput.MCP,
inputSchema: z.object({
a: z.number().description('The first number to sum.'),
b: z.number().description('The second number to sum.'),
}),
outputSchema: z.number().description('The sum of the two numbers.'),
execute({ a, b }) {
return a + b;
},
});ToModelOutput
Collection of built-in toModelOutput formatters used by deriveTools/createTool to shape tool results for LLMs.
Documented built-ins:
ToModelOutput.DEFAULT— default formatting whentoModelOutputis not provided.ToModelOutput.MCP— formats output according to the MCP tool output shape (supports text, JSON, image, and audio). See tools for details and examples.
createValidateOnClient
Creates the validateOnClient function, which controls how client-side validation is performed for RPC methods (globally or per segment). createValidateOnClient accepts a validate function that receives input data, the validation schema, and additional options, and returns the validated data or throws an error if validation fails.
import { validateData } from 'validation-library';
import { createValidateOnClient, HttpException, HttpStatus } from 'vovk';
export const validateOnClient = createValidateOnClient({
validate: async (input, schema, meta) => {
const isValid = validateData(input, schema);
if (!isValid) {
throw new HttpException(HttpStatus.NULL, 'Validation failed');
}
return input;
},
});For more details on client-side validation, see the customization page.
procedure
Higher-level helper for defining procedures that adds validation and schema emission on top of a controller handler.
Key options (all optional, except handle):
handle(req, params)— handler executed after validation.body,query,params— input validation schemas.output— output validation schema for JSON responses.iteration— item schema for JSON Lines streaming responses.isForm— treat the request body asFormDataon the server and in client typings.disableServerSideValidation— disable server-side validation (boolean or granular by parts).skipSchemaEmission— skip JSON Schema emission (boolean or granular by parts).validateEachIteration— validate each streamed item (iteration), not just the first one.operation— provide OAS details when the@operationdecorator isn’t applicable.preferTransformed— choose between transformed vs raw values when usingreq.vovk.*.
Extra capabilities on procedures:
.fn(...)— call the procedure locally (same shape as an RPC call) without HTTP..schema— method JSON schema (mirrors the RPC method JSON schema)..definition— original procedure definition (all options passed toprocedure).
See the full guide on procedure.
progressive
Experimental utility that lets you perform one request and receive multiple responses, each resolved as a separate promise.
const { users: usersPromise, tasks: tasksPromise } = progressive(ProgressiveRPC.streamProgressiveResponse);Read more in the JSONLines documentation.
HttpException
Custom error class that extends the built-in Error. It represents an HTTP error with a status code and a message. It can be thrown from a procedure and is caught by the framework to produce proper HTTP responses.
import { HttpException, HttpStatus } from 'vovk';
throw new HttpException(HttpStatus.BAD_REQUEST, 'Invalid request', { some: 'cause' });The third argument is optional and can be used to pass additional data that is useful for logging or debugging. It is available via the error.cause property on the client side.
Read more in the responses documentation.
Inference Types
VovkBody, VovkQuery, VovkParams
Universal input inference helpers for both RPC methods and controller procedures.
import type { VovkBody, VovkQuery, VovkParams } from 'vovk';
import { UserRPC } from 'vovk-client';
type Body = VovkBody<typeof UserRPC.updateUser>;
type Query = VovkQuery<typeof UserRPC.updateUser>;
type Params = VovkParams<typeof UserRPC.updateUser>;See inference.
VovkOutput, VovkIteration
Output helpers for validated procedures:
VovkOutput<T>infers the JSON return type whenprocedure({ output })is provided.VovkIteration<T>infers the yielded item type for JSON Lines streams whenprocedure({ iteration })is provided.
import type { VovkOutput, VovkIteration } from 'vovk';
import { UserRPC, StreamRPC } from 'vovk-client';
type Output = VovkOutput<typeof UserRPC.updateUser>;
type Iteration = VovkIteration<typeof StreamRPC.streamItems>;See inference.
VovkReturnType, VovkYieldType
Lower-level helpers that infer the actual return/yield types of methods when you don’t use validation schemas (i.e. you are relying on the method implementation’s type).
import type { VovkReturnType, VovkYieldType } from 'vovk';
import { UserRPC, StreamRPC } from 'vovk-client';
type Return = VovkReturnType<typeof UserRPC.updateUser>;
type Yield = VovkYieldType<typeof StreamRPC.streamItems>;See inference.
Other Types and Enums
VovkRequest
Extends the Next.js built-in NextRequest to provide better typing for .json(), .nextUrl.searchParams, and a vovk property with advanced input retrieval helpers.
See the procedure and req.vovk documentation for more information.
HttpStatus enum
Used to throw and catch errors produced by the server. Note the NULL member, which can be used to simulate HTTP errors for client-side validation failures.
export enum HttpStatus {
NULL = 0,
CONTINUE = 100,
SWITCHING_PROTOCOLS = 101,
PROCESSING = 102,
EARLYHINTS = 103,
OK = 200,
CREATED = 201,
ACCEPTED = 202,
NON_AUTHORITATIVE_INFORMATION = 203,
NO_CONTENT = 204,
RESET_CONTENT = 205,
PARTIAL_CONTENT = 206,
AMBIGUOUS = 300,
MOVED_PERMANENTLY = 301,
FOUND = 302,
SEE_OTHER = 303,
NOT_MODIFIED = 304,
TEMPORARY_REDIRECT = 307,
PERMANENT_REDIRECT = 308,
BAD_REQUEST = 400,
UNAUTHORIZED = 401,
PAYMENT_REQUIRED = 402,
FORBIDDEN = 403,
NOT_FOUND = 404,
METHOD_NOT_ALLOWED = 405,
NOT_ACCEPTABLE = 406,
PROXY_AUTHENTICATION_REQUIRED = 407,
REQUEST_TIMEOUT = 408,
CONFLICT = 409,
GONE = 410,
LENGTH_REQUIRED = 411,
PRECONDITION_FAILED = 412,
PAYLOAD_TOO_LARGE = 413,
URI_TOO_LONG = 414,
UNSUPPORTED_MEDIA_TYPE = 415,
REQUESTED_RANGE_NOT_SATISFIABLE = 416,
EXPECTATION_FAILED = 417,
I_AM_A_TEAPOT = 418,
MISDIRECTED = 421,
UNPROCESSABLE_ENTITY = 422,
FAILED_DEPENDENCY = 424,
PRECONDITION_REQUIRED = 428,
TOO_MANY_REQUESTS = 429,
INTERNAL_SERVER_ERROR = 500,
NOT_IMPLEMENTED = 501,
BAD_GATEWAY = 502,
SERVICE_UNAVAILABLE = 503,
GATEWAY_TIMEOUT = 504,
HTTP_VERSION_NOT_SUPPORTED = 505,
}HttpMethod enum
Represents the HTTP methods:
export enum HttpMethod {
GET = 'GET',
POST = 'POST',
PUT = 'PUT',
PATCH = 'PATCH',
DELETE = 'DELETE',
HEAD = 'HEAD',
OPTIONS = 'OPTIONS',
}VovkSchema
The full schema of the composed client or of a single segment in a segmented client. Shape:
{
segments: { [key: string]: VovkSegmentSchema };
meta?: VovkMetaSchema
}See the schema docs for more details.
VovkConfig
The shape of the config file.
VovkTool
The shape of an LLM tool created by the deriveTools function.
See the Deriving AI Tools documentation for more information.
VovkJSONSchemaBase
Basic JSON Schema object with type, properties, and other standard JSON Schema keywords.
VovkFetcher
Object that represents a fetcher function used to make API requests.
See the fetcher docs for more information.
VovkValidateOnClient
Function type that represents the client-side validation function created by createValidateOnClient.
See the client-side validation docs for more details.
System Members (Advanced)
createRPC
This API is experimental and may change in future versions without a major release.
Function that creates an RPC module from the schema and types inferred from controllers. It is imported by the generated TypeScript, ESM, and CJS files.