Invoking Buf Schema Registry APIs#
The Buf Schema Registry serves a set of RPC services defined in Protobuf and exposed over Connect, gRPC, and gRPC-Web.
The same domain that hosts the web UI also serves the APIs: buf.build for the public BSR, or your private hostname (<org>.buf.dev for Pro, your custom domain for Enterprise).
Available APIs#
buf.build/bufbuild/registryis the main public BSR API surface. It contains stablev1services for modules, owners, commits, and labels.buf.build/bufbuild/reflectis a separate beta module for fetching compiledFileDescriptorSets. See Reflection.
Protocols and URLs#
The same RPC services are reachable through three protocols:
- Connect, the default. Works over HTTP/1.1 and HTTP/2 and supports JSON request bodies, which makes the APIs callable from
curlorwgetwithout a generated client. - gRPC, for clients that already speak gRPC.
- gRPC-Web, for browser clients.
Every method is mounted at the root URI of the host (a gRPC compatibility requirement). The path is the fully qualified service name plus the method name:
For Connect’s JSON encoding, see the Connect protocol spec. For how Protobuf messages map to JSON, see the Protobuf JSON mapping.
Authentication#
Most BSR APIs require a Bearer token in the Authorization header:
To create a token, see Authentication.
Note
To let an AI agent call these same APIs on your behalf, connect it to the BSR MCP server instead of wiring up a client by hand.
Public modules on the public BSR (buf.build) accept unauthenticated reads. Private BSR instances typically require authentication for every call regardless of repository visibility, depending on the instance’s access configuration.
Generating a client#
Two ways to get a typed client for a BSR API:
- Run
buf generateagainst the API’s module (for example,buf.build/bufbuild/registry) using a Connect or gRPC plugin. See the code-generation tutorial. - Use a generated SDK to depend on a prebuilt client for the language you’re working in (Go, npm, Maven, Cargo, and so on).
Example: curl#
The example below calls the Reflection API to fetch the compiled FileDescriptorSet for buf.build/connectrpc/eliza:
$ curl \
https://buf.build/buf.reflect.v1beta1.FileDescriptorSetService/GetFileDescriptorSet \
-H "Authorization: Bearer ${BUF_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"module": "buf.build/connectrpc/eliza"}'
The path shape (<host>/<fully.qualified.ServiceName>/<MethodName>) and the JSON request body are the same for any BSR API; substitute the service, method, and request type for the call you want to make.
Example: Go SDK#
For application code, the cleaner path is a generated SDK. From the buf.build/bufbuild/reflect SDKs page, you’ll need:
protocolbuffers-gofor the message types.connect-gofor the RPC client.
The call shape:
import (
reflectv1beta1 "buf.build/gen/go/bufbuild/reflect/protocolbuffers/go/buf/reflect/v1beta1"
"buf.build/gen/go/bufbuild/reflect/connectrpc/go/buf/reflect/v1beta1/reflectv1beta1connect"
"connectrpc.com/connect"
)
client := reflectv1beta1connect.NewFileDescriptorSetServiceClient(
http.DefaultClient,
"https://buf.build",
)
req := connect.NewRequest(&reflectv1beta1.GetFileDescriptorSetRequest{
Module: "buf.build/connectrpc/eliza",
})
req.Header().Set("Authorization", "Bearer "+os.Getenv("BUF_TOKEN"))
resp, err := client.GetFileDescriptorSet(ctx, req)
The full runnable example:
package example
import (
"context"
"net/http"
reflectv1beta1connect "buf.build/gen/go/bufbuild/reflect/connectrpc/gosimple/buf/reflect/v1beta1/reflectv1beta1connect"
reflectv1beta1 "buf.build/gen/go/bufbuild/reflect/protocolbuffers/go/buf/reflect/v1beta1"
)
func Example() (*reflectv1beta1.GetFileDescriptorSetResponse, error) {
client := reflectv1beta1connect.NewFileDescriptorSetServiceClient(
http.DefaultClient,
"https://buf.build",
)
request := &reflectv1beta1.GetFileDescriptorSetRequest{
Module: "buf.build/connectrpc/eliza",
}
// If you're using a private BSR, set your Authorization header to a
// BUF_TOKEN value.
//
// request.Header().Set("Authorization", "Bearer <BUF_TOKEN>")
response, err := client.GetFileDescriptorSet(context.Background(), request)
if err != nil {
return nil, err
}
return response, nil
}