Observability

See every step of an agent run, and stop the bad ones.

Tag a run with x-session-id and read its timeline step by step. Stream every request to Langfuse, Datadog, any OTLP backend or your webhook. Cap what one session may spend and refuse a loop before it burns the budget.

A 40-turn run on Claude Sonnet 5.5, live
40 × 9,000 in, 700 out
$0.5160
Steps per timeline
up to 1,000
Export retries
3
Loop guard
>5 repeats in 10 min
Usage CSV
up to 92 days

What it does for an agent

Sessions
One header groups an agent run: requests, models, keys, tokens, cost and failures, per session.
A timeline per run
Every request in order with its model, tokens, cost, latency, outcome and tool calls.
Log export
Webhook, Langfuse or OTLP/HTTP to Datadog, Honeycomb or Grafana, within about a minute of each request.
Session caps
Requests per sliding hour and dollars per UTC day, per session, set on the key.
Loop guard
More than 5 identical tool calls or bodies in 10 minutes and the session is refused.
Usage as CSV
Every request with key, session, model, tokens, charge, latency and refund reason, up to 200,000 rows a file.

Copy, paste, run

OpenAI SDK: tag a run
python
1from openai import OpenAI
2import os
3
4client = OpenAI(
5 base_url="https://api.relayswitch.io/v1",
6 api_key=os.environ["RELAYSWITCH_API_KEY"],
7)
8
9run_id = "deploy-bot-2026-10-30-0412"
10for step in plan:
11 reply = client.chat.completions.create(
12 model="gpt-6.1-sol",
13 messages=history + [step],
14 extra_headers={"x-session-id": run_id},
15 )
Anthropic SDK: tag a client
python
1import anthropic
2import os
3
4client = anthropic.Anthropic(
5 base_url="https://api.relayswitch.io/v1",
6 api_key=os.environ["RELAYSWITCH_API_KEY"],
7)
8
9client = client.with_options(default_headers={"x-session-id": "triage-7731"})
10reply = client.messages.create(
11 model="claude-sonnet-5-5",
12 max_tokens=1024,
13 messages=[{"role": "user", "content": "Triage the new tickets."}],
14)
Key API: session caps and loop guard
bash
1# An agent key that stops a runaway session (admin key):
2# 300 requests per session per sliding hour, $5 per session per UTC day,
3# and more than 5 identical calls in 10 minutes refused.
4curl https://api.relayswitch.io/v1/keys \
5 -H "Authorization: Bearer $ADMIN_KEY" -H "Content-Type: application/json" \
6 -d '{"name": "deploy-bot", "budget_usd": 50,
7 "session_max_requests": 300, "session_max_spend_usd": 5,
8 "loop_guard": true}'
curl: export to Langfuse and OTLP
bash
1# Langfuse: each request a generation, grouped by session.
2curl https://api.relayswitch.io/v1/exports \
3 -H "Authorization: Bearer $ADMIN_KEY" -H "Content-Type: application/json" \
4 -d '{"kind": "langfuse", "name": "prod traces",
5 "public_key": "pk-lf-...", "secret_key": "sk-lf-..."}'
6
7# Any OTLP/HTTP backend: a session is one trace, each request a span.
8curl https://api.relayswitch.io/v1/exports \
9 -H "Authorization: Bearer $ADMIN_KEY" -H "Content-Type: application/json" \
10 -d '{"kind": "otlp", "name": "honeycomb",
11 "endpoint": "https://api.honeycomb.io",
12 "headers": {"x-honeycomb-team": "YOUR_INGEST_KEY"}}'
curl: sessions and the usage CSV
bash
1# Recent sessions, then one run's timeline (admin key).
2curl https://api.relayswitch.io/v1/sessions -H "Authorization: Bearer $ADMIN_KEY"
3curl https://api.relayswitch.io/v1/sessions/deploy-bot-2026-10-30-0412 -H "Authorization: Bearer $ADMIN_KEY"
4
5# The usage log as CSV, up to 92 days per file.
6curl "https://api.relayswitch.io/v1/usage/export?from=2026-10-01&to=2026-10-30" \
7 -H "Authorization: Bearer $ADMIN_KEY" -o usage.csv
Webhook signature check
python
1# Webhook deliveries are signed: verify before trusting.
2import hashlib, hmac
3
4def valid(body: bytes, timestamp: str, signature: str, secret: str) -> bool:
5 mac = hmac.new(secret.encode(), f"{timestamp}.".encode() + body, hashlib.sha256)
6 return hmac.compare_digest("sha256=" + mac.hexdigest(), signature)
7
8# headers: x-uplink-timestamp, x-uplink-signature
9# body: {"event": "usage.batch", "destination_id": ..., "data": [...]}

Export destinations

KindWhat arrivesYou provide
webhookPOST { event: "usage.batch", data: [...] }, signedA public https URL; the secret is returned once
langfuseEach request as a generation, grouped by sessionPublic and secret key; host optional
otlpA trace per session, a span per request, gen_ai.* attributesThe OTLP/HTTP base URL and up to 10 headers
FAQs

Questions

For agent builders.

Open the console

A key in under a minute

Get a key

Or email hello@relayswitch.io

Watch your agents in the tools you already use

Sessions, traces and caps on every key, exported where your team looks.