Skip to main content
The boxd CLI, SSH server, and SDKs are all clients of one thing: the public gRPC API at boxd.sh:9443. If your language doesn’t have a boxd SDK yet, generate one from the proto file and talk to it directly.

Endpoint

  • Transport: HTTP/2 cleartext (h2c). No TLS on this port — auth is short-lived JWTs.
  • Reflection: gRPC server reflection is enabled, so tools like grpcurl work without the proto file.
  • Service: boxd.api.v1.BoxdApi

The proto

Copy the full service definition into a local api.proto, then generate stubs with protoc, buf, grpc_tools, or @grpc/proto-loader. The proto is proto3 with no external imports — generation is one command. You don’t strictly need the file: since server reflection is on, grpcurl and buf curl work directly against the endpoint, and grpcurl -plaintext boxd.sh:9443 describe boxd.api.v1.BoxdApi dumps the schema on demand.

Authentication

Two-step: long-lived API key → short-lived JWT → bearer token on every gRPC call.

1. Create an API key

API keys are issued from the boxd console. Sign in at boxd.sh, open the API keys page, and create one. The raw key is shown once — copy it immediately. Format: bxd_ followed by ~40 base62 characters. You can also create them via the CLI once you’re logged in:

2. Exchange for a JWT

Send the API key to the exchange endpoint over HTTPS:
The JWT is short-lived (default ~1 hour). Re-exchange before expiry. Rate-limited per source IP.

3. Send it on every gRPC call

Standard gRPC metadata. Most generated clients expose this as a per-call interceptor or call option.

Hello world

Easiest way to verify auth and reachability — no proto file needed (server reflection is on).
Install: brew install grpcurl or github.com/fullstorydev/grpcurl.

Errors

Standard gRPC status codes. The most common ones you’ll hit: The error message in Status.message() is human-readable and safe to surface to users.

Streaming RPCs

Three RPCs use streams:
  • StreamLogs — server-streaming, emits LogChunk messages as the VM produces output. Set follow=true to keep the stream open after current logs flush.
  • UploadFileStream — client-streaming, lifts the 4 MiB single-message gRPC cap of UploadFile. The first UploadFileChunk carries vm_id, path, and total_size; subsequent chunks carry bytes only. The server reads exactly total_size bytes and returns the confirmed byte count.
  • Exec — bidirectional. First message must contain vm_id and command; subsequent client messages with stdin=true pipe stdin, or window_change=true with cols/rows resize a PTY. Server messages carry data with is_stderr set to true for stderr chunks and false (default) for stdout. PTY-mode execs merge stderr into stdout at the kernel, so is_stderr is only set for non-PTY execs. Final server message has exit_code set. Clients close their send half of the bidi stream to signal stdin EOF to the subprocess (the proxy translates this to CHANNEL_EOF on the underlying SSH channel).

What’s next

CLI

Same API, no codegen — useful for shell scripting and one-offs.

Primitives: Machines

Concepts behind CreateVm / ForkVm / SuspendVm.