RelayKey for AI agents
A one-screen recipe for any AI agent (Cursor, Claude Code, Replit, ChatGPT, Codex, etc.) to start using a RelayKey-protected API key without receiving the real production key.
TL;DR
Swap the base URL and API key the agent already uses. That's it.
# Before - in your .env UPSTREAM_BASE_URL = https://api.elevenlabs.io UPSTREAM_API_KEY = sk-real-production-key # After - in your .env (verify .env is in .gitignore) UPSTREAM_BASE_URL = https://proxy.relaykey.ai/conn_xxx RELAYKEY_API_KEY = rk_proxy_xxx
Save the token in .env as RELAYKEY_API_KEY, the same variable name across every project so prompts and examples stay uniform. The agent keeps calling the upstream API the same way: same paths, same methods, same request shape. RelayKey enforces the RelayKey's scope, swaps in the real upstream key, forwards the request, and audits the result.
Discovery - /_discover
Every RelayKey proxy exposes a discovery endpoint. GET /_discover with your RELAYKEY_API_KEY and the proxy returns the full list of tools, base URLs, and allowed methods/paths the key can reach. This exists so agent setup is uniform across projects and survives grant changes. If the operator adds or revokes a tool later, you re-run discovery instead of asking for a new prompt.
curl -H "Authorization: Bearer $RELAYKEY_API_KEY" \ https://proxy.relaykey.ai/_discover
The response shape:
{
"name": "Kate Mason",
"email": "[email protected]",
"type": "recipient",
"expires_at": "2026-06-01T00:00:00Z",
"grants": [
{
"vendor": "HiBob",
"connection_id": "conn_hibob",
"base_url": "https://proxy.relaykey.ai/conn_hibob",
"upstream_base_url": "https://api.hibob.com",
"allowed_methods": ["GET"],
"allowed_paths": ["/v1/people", "/v1/employments/*"]
}
]
}For each grant, point the SDK at base_url, never upstream_base_url. The upstream URL is shown only so you can recognize what tool the grant maps to. type is "recipient" for legacy/internal compatibility when one key-holder token covers many tools, or "credential" when it's scoped to a single integration.
What you'll be handed
- Integration name (e.g.
ElevenLabs). - Proxy base URL of the form
https://proxy.relaykey.ai/conn_xxx. - Proxy token of the form
rk_proxy_.... - Upstream base URL (the API the RelayKey targets) - used only so you know what to swap.
What to do
- Find where the upstream base URL and API key are configured. Typical locations:
.env, SDK constructor (new OpenAI({ baseURL, apiKey })), HTTP client config (axios.create({ baseURL })). - Replace the upstream base URL with the proxy base URL.
- Replace the upstream API key with the
rk_proxy_...token. - Confirm with a single request:
curl -i https://proxy.relaykey.ai/conn_xxx/v1/voices \ -H "Authorization: Bearer rk_proxy_..."
Expect a 200 from the upstream. The response also carries x-relaykey-decision: allowed.
Header style
Use whichever auth header the upstream SDK already uses. RelayKey accepts both:
Authorization: Bearer rk_proxy_... x-api-key: rk_proxy_...
If you get blocked
RelayKey returns a structured JSON body when it blocks a request:
{
"error": "path_not_allowed",
"message": "Path /admin/users not allowed on this RelayKey",
"allowed_patterns": ["/v1/*"],
"allowed_methods": ["GET", "POST"]
}Read allowed_patterns and allowed_methods and either retry within those constraints or report the mismatch to the human so they can widen the RelayKey's scope.
Multi-tool agent prompts
The user may hand you a single disposable RelayKey that grants access to several upstream APIs - one key for HiBob + Absorb + Greenhouse, etc. The prompt looks like this:
Hi Kate - I'm giving you scoped access to my tools through RelayKey for safety.
Disposable key (treat as a secret, works against every tool below):
RELAYKEY_API_KEY=rk_proxy_xxx
Save it to .env (and verify .env is in .gitignore - add it if missing).
Run discovery to see exactly what you have access to:
curl -H "Authorization: Bearer $RELAYKEY_API_KEY" https://proxy.relaykey.ai/_discover
For each tool in the response, point that SDK at the grant's base_url and use
process.env.RELAYKEY_API_KEY as the API key. Example:
new OpenAI({ baseURL: "https://proxy.relaykey.ai/conn_abc", apiKey: process.env.RELAYKEY_API_KEY })
Tools you have access to today (re-run discovery anytime - that is canonical):
- HiBob: https://proxy.relaykey.ai/conn_abc (instead of https://api.hibob.com)
- Absorb: https://proxy.relaykey.ai/conn_def (instead of https://acme.myabsorb.com/api/rest/v1)
- Greenhouse: https://proxy.relaykey.ai/conn_ghi (instead of https://harvest.greenhouse.io/v1)
Docs: https://relaykey.ai/docs/agent-setupThe same RELAYKEY_API_KEY works against every proxy URL listed; the proxy enforces a different scope per tool internally. Different SDKs / client objects in your code, but they all share the one token. The inlined tool list is human-readable context. Discovery is canonical, so re-run it if the operator adds or revokes a grant later.
Things to avoid
- Don't store
rk_proxy_...tokens in client-side code (browser bundles, mobile applications). They are server-side credentials. - Don't log the token. It's still a secret.
- Don't invent OAuth refresh flows through the proxy. Use only cataloged
token_refreshIntegrations whose refresh shape RelayKey supports; RelayKey still does not handle the user-facing OAuth login/callback flow. - Don't rewrite request bodies or paths beyond what the user told you. The proxy enforces a path allowlist; an agent that "improves" the upstream URL silently will produce confusing block responses.
Where to learn more
- Marketing: relaykey.ai
- Dashboard: app.relaykey.ai
- Per-SDK migration recipes: /docs (Agents and Quickstart sections).
