Documentation Index
Fetch the complete documentation index at: https://mintlify.com/middleapi/orpc/llms.txt
Use this file to discover all available pages before exploring further.
Install @orpc/contract:
npm install @orpc/contract
The oc builder
@orpc/contract exports a pre-configured oc builder (ContractBuilder) that mirrors the os builder API but only defines the contract shape — no handlers, no middleware.
import { oc } from '@orpc/contract'
Procedure contracts
Defines the input schema:
import { oc } from '@orpc/contract'
import * as z from 'zod'
const listPlanets = oc
.input(
z.object({
limit: z.number().int().min(1).max(100).optional(),
cursor: z.number().int().min(0).default(0),
}),
)
.output(schema)
Defines the output schema:
const listPlanets = oc
.input(z.object({ limit: z.number().optional() }))
.output(z.array(z.object({ id: z.number(), name: z.string() })))
.errors(map)
Declares typed errors the procedure can return:
const findPlanet = oc
.input(z.object({ id: z.number() }))
.output(z.object({ id: z.number(), name: z.string() }))
.errors({
NOT_FOUND: {
status: 404,
message: 'Planet not found',
},
})
.route(options)
Attaches HTTP route information for OpenAPI generation:
const findPlanet = oc
.route({
method: 'GET',
path: '/planets/{id}',
summary: 'Find a planet by ID',
tags: ['planets'],
})
.input(z.object({ id: z.number() }))
.output(z.object({ id: z.number(), name: z.string() }))
Attaches arbitrary metadata (useful for authorization annotations, etc.):
const createPlanet = oc
.$meta<{ authRequired: boolean }>({})
.meta({ authRequired: true })
.input(z.object({ name: z.string() }))
.output(z.object({ id: z.number(), name: z.string() }))
Contract routers
Group procedure contracts into a nested object using oc.router():
import { oc } from '@orpc/contract'
import * as z from 'zod'
export const contract = oc.router({
planet: {
list: oc
.input(z.object({ limit: z.number().optional() }))
.output(z.array(z.object({ id: z.number(), name: z.string() }))),
find: oc
.route({ method: 'GET', path: '/planets/{id}' })
.input(z.object({ id: z.number() }))
.output(z.object({ id: z.number(), name: z.string() }))
.errors({ NOT_FOUND: { status: 404 } }),
create: oc
.route({ method: 'POST', path: '/planets' })
.input(z.object({ name: z.string() }))
.output(z.object({ id: z.number(), name: z.string() })),
},
})
export type AppContract = typeof contract
const planetContract = oc
.prefix('/planets')
.tag('planets')
.router({
list: oc.input(z.object({ limit: z.number().optional() })),
find: oc.input(z.object({ id: z.number() })),
})
Type utilities
import type {
InferContractRouterInputs,
InferContractRouterOutputs,
} from '@orpc/contract'
type Inputs = InferContractRouterInputs<typeof contract>
type Outputs = InferContractRouterOutputs<typeof contract>