RPC Protocol
The RPC protocol is a lightweight protocol for remote procedure calls. It supports more native types than plain JSON and is used by RPC Handler and RPC Link.
Serializer
Most of the protocol's flexibility comes from its serializer. In addition to JSON-compatible values, it supports native types such as Date, BigInt, RegExp, URL, Set, Map, Blob, File, AsyncIteratorObject, and ReadableStream<Uint8Array>. To learn more, including how to extend it, see RPC Serializer.
WARNING
To better support Blob, File, and ReadableStream<Uint8Array> at the root level in cross-origin scenarios, extend your CORS allowlist to allow clients to send and receive the Content-Disposition and Standard-Server headers. Learn more in the Standard Server documentation. If you use the CORS Plugin, include them in allowHeaders and exposeHeaders:
const cors = new CORSHandlerPlugin({
allowHeaders: ['Content-Disposition', 'Standard-Server'],
exposeHeaders: ['Content-Disposition', 'Standard-Server'],
})Routing
The request pathname identifies which procedure to call.
curl https://example.com/rpc/planet/createThis calls the planet.create procedure when /rpc is the prefix:
const router = {
planet: {
create: os.handler(() => {})
}
}Sending Input
You can use any HTTP method. Send input in the query string or request body, depending on the method.
INFO
Request payloads depend on the serializer and are not plain JSON. Learn more in RPC Serializer Format.
Query String
const url = new URL('https://example.com/rpc/planet/create')
url.searchParams.append('data', JSON.stringify({
json: {
name: 'Earth',
detached_at: '2022-01-01T00:00:00.000Z'
},
meta: [['date', 'detached_at']]
}))
const response = await fetch(url)Request Body
curl -X POST https://example.com/rpc/planet/create \
-H 'Content-Type: application/json' \
-d '{
"json": {
"name": "Earth",
"detached_at": "2022-01-01T00:00:00.000Z"
},
"meta": [["date", "detached_at"]]
}'With Files
const form = new FormData()
form.set('data', JSON.stringify({
json: {
name: 'Earth',
thumbnail: {},
images: [{}],
},
maps: [['thumbnail'], ['images', 0]]
}))
form.set('0', new Blob([''], { type: 'image/png' }))
form.set('1', new Blob([''], { type: 'image/png' }))
const response = await fetch('https://example.com/rpc/planet/create', {
method: 'POST',
body: form
})Success Response
HTTP/1.1 200 OK
Content-Type: application/json
{
"json": {
"id": "1",
"name": "Earth",
"detached_at": "2022-01-01T00:00:00.000Z"
},
"meta": [["bigint", "id"], ["date", "detached_at"]]
}A successful response uses an HTTP status code in the 200-299 range and returns the procedure output.
INFO
Response bodies depend on the serializer and are not plain JSON. Learn more in RPC Serializer Format.
Error Response
HTTP/1.1 500 Internal Server Error
Content-Type: application/json
{
"json": {
"defined": false,
"inferable": false,
"code": "INTERNAL_SERVER_ERROR",
"message": "Internal server error",
"data": {
"id": "1234567890"
}
},
"meta": [["bigint", "data", "id"]]
}An error response uses an HTTP status code in the 400-599 range and returns an ORPCError object.
INFO
Response bodies depend on the serializer and are not plain JSON. Learn more in RPC Serializer Format.

