Skip to main content

Use the gRPC API from any language

This guide connects an app written in any language to a Priompt server through its gRPC API. The API is one service, priompt.v1.PromptService, defined in a single file, prompt.proto. It covers every operation, including history, branches, merges, and rollback, which the Python and Node SDKs don't all wrap.

Prerequisites​

Before you begin, make sure you have:

  • A running server: see the Quickstart. The examples use localhost:8443 without authentication.

  • The contract: clone the proto repository, which holds proto/priompt/v1/prompt.proto:

    git clone https://github.com/priompt/proto
  • grpcurl: to try calls from a shell.

  • buf: to generate a client. Not needed for Go.

Call the API with grpcurl​

The server doesn't enable gRPC reflection, so pass the .proto file to grpcurl.

To fetch a prompt, run from the directory that holds the proto clone:

grpcurl -plaintext -H "authorization: Bearer <token>" \
-import-path proto/proto -proto priompt/v1/prompt.proto \
-d '{"uri":"priompt://acme/onboarding/welcome"}' \
localhost:8443 priompt.v1.PromptService/GetPrompt
Output
{
"uri": "priompt://acme/onboarding/welcome",
"template": "Hi {name}, welcome to {org}!\n",
"slots": [
"name",
"org"
],
"versionHash": "22e5cc10ac0f3d70fd97c6b554a36abcb3173731412212dc222106e9cbcac402"
}

Replace <token> with a token the server accepts, or drop the -H line for a server without authentication. grpcurl prints field names in camel case, such as versionHash. Generated code uses each language's own convention.

Generate a client​

To generate a client with buf:

  1. Next to the proto clone, create a buf.gen.yaml that names your language's plugins. This one generates Go:

    buf.gen.yaml
    version: v2
    inputs:
    - directory: proto/proto
    plugins:
    - remote: buf.build/protocolbuffers/go
    out: gen
    opt: paths=source_relative
    - remote: buf.build/grpc/go
    out: gen
    opt: paths=source_relative

    For another language, swap in its plugins from the Buf Schema Registry, for example buf.build/grpc/java or buf.build/grpc/csharp. Remote plugins run on Buf's servers, so you don't install protoc or any plugin locally.

  2. Generate the code:

    buf generate
    find gen -type f
    Output
    gen/priompt/v1/prompt.pb.go
    gen/priompt/v1/prompt_grpc.pb.go

Use the published Go stubs​

Go apps can skip generation. The proto module publishes its generated stubs:

go get github.com/priompt/[email protected]
main.go
package main

import (
"context"
"fmt"
"log"

priomptv1 "github.com/priompt/proto/gen/priompt/v1"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/metadata"
)

func main() {
conn, err := grpc.NewClient("localhost:8443", grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
log.Fatal(err)
}
defer conn.Close()
client := priomptv1.NewPromptServiceClient(conn)

ctx := metadata.AppendToOutgoingContext(context.Background(), "authorization", "Bearer <token>")
p, err := client.GetPrompt(ctx, &priomptv1.GetPromptRequest{Uri: "priompt://acme/onboarding/welcome"})
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s%s\n", p.GetTemplate(), p.GetVersionHash()[:12])
}
Output
Hi {name}, welcome to {org}!
22e5cc10ac0f

Follow the connection rules​

Every client, generated or not, talks to the server the same way:

  • Address: host:8443. The connection is plaintext unless the server runs with -tls-cert and -tls-key. A server with -client-ca also requires a client certificate signed by that CA.
  • Authentication: send the metadata header authorization: Bearer <token> on every call. A server without tokens ignores it.
  • Pinning: set ref on GetPromptRequest to a branch name or a full 64-character commit hash. The response then carries commit_hash.
  • Errors: failures use standard gRPC status codes. A missing prompt returns NotFound with the message prompt "<uri>" not found. See Errors.

The gRPC API reference documents every RPC and message.

Subscribe without an SDK​

The server publishes a change event on its NATS broker each time the served version of a prompt changes. To receive events from any language, connect a NATS client to nats://127.0.0.1:4222, or nats://<api-token>@host:4222 with your API token when the broker requires one. Then subscribe to the prompt's subject. An org-scoped token can subscribe only inside its org.

The subject is priompt. followed by the address's segments joined by .. Inside a segment, every byte other than a letter, a digit, _, or - is percent-encoded as % and two uppercase hex digits. For example, priompt://acme/support/agent publishes on priompt.acme.support.agent, priompt://acme.corp/x/a.b on priompt.acme%2Ecorp.x.a%2Eb, and priompt.acme.> matches every prompt in the acme org. Servers before v0.7.3 didn't encode segments.

The message body is JSON:

{"version":"bd45a4721079b550b784f3fe346b34a86d640ebd6e9b0248ea5b957aea345274","classification":"minor edit"}

version is the new version hash, and classification is the semantic verdict. The server omits classification when it couldn't classify the change. Treat an event as a signal to fetch the prompt again over gRPC. To decide which verdicts your app reloads on its own, see Hot-reload prompts safely.

Next steps​