relay

Documentation

Languages & SDKs

Two official SDKs (TypeScript, Python) and a documented HTTP + SSE protocol — wire Relay into any stack.

What's supported

The SDK contract is the same in every language: createAgent({...}) returns something you iterate, yielding events.

RuntimeInstallStatus
Node.js (npm / pnpm / yarn)npm install @relayhq/sdkOfficial ✓
Python (pip / uv / poetry)pip install relayhqOfficial ✓
Next.js (server / route handlers)npm install @relayhq/sdkvia Node SDK ✓
Bunbun add @relayhq/sdkvia Node SDK ✓
Denoimport "npm:@relayhq/sdk"via Node SDK ✓
Cloudflare Workersnpm install @relayhq/sdkvia Node SDK ✓
Browsernpm install @relayhq/sdkvia Node SDK ✓ (fetch + ReadableStream)
Go / Rust / Ruby / PHP / Elixir / …Direct HTTP + SSE (~30 LOC, see below)

TypeScript / Node

Published as @relayhq/sdk. Zero runtime dependencies. ESM only. Node 18+.

npm install @relayhq/sdk
# or
pnpm add @relayhq/sdk
# or
yarn add @relayhq/sdk
agent.ts
import { createAgent } from "@relayhq/sdk";

const agent = createAgent({
  apiKey: process.env.RELAY_API_KEY!,
  baseUrl: "https://api.relaygh.dev",
  model: "gpt-4o-mini",
});

for await (const event of agent.run("Say hi in three languages.")) {
  if (event.type === "token") process.stdout.write(event.text);
}

See the SDK reference for the full surface.

Python

Published as relayhq on PyPI. Pure async viahttpx. Python 3.9+.

pip install relayhq
# or
uv add relayhq
# or
poetry add relayhq
agent.py
import asyncio, os
from relayhq import create_agent

agent = create_agent(
    api_key=os.environ["RELAY_API_KEY"],
    base_url="https://api.relaygh.dev",
    model="gpt-4o-mini",
)

async def main():
    async for event in agent.run("Say hi in three languages."):
        if event["type"] == "token":
            print(event["text"], end="", flush=True)

asyncio.run(main())

Custom function tools (Python)

from relayhq import create_agent, builtin, tool

async def get_user_handler(input):
    return await db.users.find(input["id"])

get_user = tool(
    name="get_user",
    description="Look up a user by id",
    input_schema={
        "type": "object",
        "properties": {"id": {"type": "string"}},
        "required": ["id"],
    },
    handler=get_user_handler,   # sync or async; both work
)

agent = create_agent(
    model="claude-sonnet-4-6",
    tools=[builtin.calculator, get_user],
)

Next.js

The Node SDK works in every Next environment — server components, server actions, route handlers, middleware. Below is a route handler that proxies an agent run as an NDJSON stream.

app/api/agent/route.ts
import { createAgent } from "@relayhq/sdk";

export async function POST(req: Request) {
  const { prompt } = await req.json();

  const agent = createAgent({
    apiKey: process.env.RELAY_API_KEY!,
    baseUrl: "https://api.relaygh.dev",
    model: "gpt-4o-mini",
  });

  const encoder = new TextEncoder();
  const stream = new ReadableStream({
    async start(controller) {
      for await (const event of agent.run(prompt)) {
        controller.enqueue(encoder.encode(JSON.stringify(event) + "\n"));
      }
      controller.close();
    },
  });

  return new Response(stream, {
    headers: { "content-type": "application/x-ndjson" },
  });
}

The client component can read it with fetch(...).body.getReader() and parse each line.

cURL / HTTP

The protocol is plain HTTP + SSE. You can use Relay from anything that can do an HTTP POST.

curl -N -X POST https://api.relaygh.dev/v1/runs \
  -H "authorization: Bearer $RELAY_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "model": "gpt-4o-mini",
    "input": "Say hi in three languages."
  }'

Each event arrives as one SSE frame:

data: {"type":"token","text":"Hello"}

data: {"type":"token","text":" Bonjour"}

data: {"type":"done","output":"...","usage":{"input_tokens":34,"output_tokens":12}}

Full API surface lives at /docs/api.

Go (no official SDK, ~30 LOC)

No third-party deps required — just net/http + bufio.

agent.go
package main

import (
	"bufio"
	"fmt"
	"net/http"
	"os"
	"strings"
)

func main() {
	body := strings.NewReader(`{"model":"gpt-4o-mini","input":"Say hi."}`)
	req, _ := http.NewRequest("POST",
		"https://api.relaygh.dev/v1/runs", body)
	req.Header.Set("authorization", "Bearer "+os.Getenv("RELAY_API_KEY"))
	req.Header.Set("content-type", "application/json")

	resp, err := http.DefaultClient.Do(req)
	if err != nil { panic(err) }
	defer resp.Body.Close()

	scanner := bufio.NewScanner(resp.Body)
	for scanner.Scan() {
		line := scanner.Text()
		if strings.HasPrefix(line, "data: ") {
			fmt.Println(strings.TrimPrefix(line, "data: "))
		}
	}
}

Picking an SDK

  • You're shipping a Node / Next / Bun app: @relayhq/sdk. Type-safe, batteries-included.
  • You're shipping a Python service / FastAPI / Django: relayhq. Async-native, fits cleanly into existing async stacks.
  • Anything else: the HTTP API is small enough to wrap in an afternoon. See /docs/api.