The short version
Your agent keeps running where it already runs. You change where its model calls go. Xay is an OpenAI-compatible and Anthropic-compatible gateway: it forwards each call with your own provider key, reads the usage the provider reports, and signs a receipt. That receipt is what raises the agent’s tower, and what you later claim as testnet XAY.
Nothing is installed. There is no package to add and no runtime to move. The agent keeps its models, its prompts, and its code. Two things change: the base URL, and the key.
Paste one prompt
This is the way to connect. The prompt is the same for every stack. On the connect page it already contains your agent’s name, the gateway address, and the agent key.
- Sign in and name the agent. Naming it creates it. You get an agent key, shown once. Copy it then. We keep only a hash, so the page cannot show it again. If you lose it, issue a new one there. The old one stops. The name, the history, and the tower stay.
- Add the key from whoever bills you for models: OpenAI, Anthropic, or Groq. The form is on the same page, above the prompt. Xay forwards each call with that key. You pay your provider. A call with no key on file comes back as a 402, and nothing is earned.
- Copy the prompt.
- Paste it into Claude Code, Cursor, Codex, or whatever you already have open on that project. It finds how the project talks to a model, tells you what it found, changes the base URL and the key, makes one small call, and reports whether a receipt came back.
Your provider key stays on your Xay account. The prompt tells the agent to stop and ask you rather than go looking for one. If it cannot edit a file or reach the network, it stops and tells you the line to type. That line is in the next sections.
The text below is that same prompt. Copied from here, replace the key line with the one from your connect page. Copied from the connect page, it is already filled in.
I pasted this into you myself. Please point this project's model calls at XAY's
gateway so the compute my agent "your agent" burns is metered and earns.
XAY is an OpenAI- and Anthropic-compatible gateway. Nothing is installed and no
package is added: the agent keeps its own models, prompts and code, and only the
base URL and the key change. XAY forwards each call with my own provider key,
which it already holds, and reads the usage off the provider's response.
1. Find how this project talks to a model. It might be the OpenAI or Anthropic
SDK, a framework like LangChain, CrewAI or the OpenAI Agents SDK, a coding
agent configured by environment variables, or plain HTTP. Tell me what you
found before you change anything.
2. Point it here:
base URL https://api.xay.ai/v1
key <your XAY agent key, from the connect page>
The key goes in the `Authorization: Bearer` header, which is the only header
the gateway authenticates on. An Anthropic-shaped client must send it as its
auth token rather than its API key: `ANTHROPIC_AUTH_TOKEN`, not
`ANTHROPIC_API_KEY`, which travels as `x-api-key` and 401s every time.
4. Check the key reaches the gateway. This spends nothing:
curl -sS https://api.xay.ai/v1/models -H "Authorization: Bearer <the key above>" | head -c 400
A 200 with a list of models means the key works. A 401 means the key is
wrong or was revoked — stop and tell me, do not try another one.
5. Make one small real call through whatever you just configured, and show
me the response headers. The header that matters is
`x-aiworld-receipt-id`: it is present when XAY signed a metering
receipt for the call, which is the only thing that earns. A streamed
call carries `x-aiworld-metering: on-stream-end` instead, because the
receipt is not signed until the last chunk lands.
6. Tell me which of these you got:
- a receipt id — the setup is done and the agent is earning;
- a 402 with code `provider_key_required` — the setup is right and my
provider key is missing. XAY forwards with my own key and never pays
for inference on anyone's behalf, so I have to add one at
https://www.xay.ai/connect. You cannot do this step for me and should not try;
- anything else — quote the status, the body, and the
`x-aiworld-request-id` header back to me.
Things not to do, because each has a wrong-looking fix that makes it worse:
- Do not invent, guess, or go looking for an API key. The only key you need
is in this message. If something asks for another one, stop and ask me.
- Do not put my OpenAI or Anthropic key anywhere in this project. XAY holds
it and forwards with it; the agent's environment never sees it.
- Do not change the model, the prompts, or anything about what the agent
does. You are changing where its model calls go, and nothing else.
- Do not echo the key back to me in full, and do not commit it.Do it by hand
The whole change is two values. Put them where your tool already keeps its model address and its key.
https://api.xay.ai/v1The agent key is the other value. You get it when you create the agent, on the connect page. It goes in the Authorization: Bearer header. It is a Xay agent key. It is separate from the OpenAI, Anthropic, or Groq key, which stays on your Xay account and is what Xay forwards with.
Claude Code and the Anthropic SDK send the key as an auth token. Set ANTHROPIC_AUTH_TOKEN. ANTHROPIC_API_KEY travels as x-api-key, and the gateway reads Authorization: Bearer alone, so that variable is a 401 on every call.
An OpenAI-shaped client already puts its key in the right header. OPENAI_BASE_URL and OPENAI_API_KEY are enough when the tool reads them from the environment. The value of OPENAI_API_KEY is still the Xay agent key.
The exact lines
The same two values, written the way each tool expects them. Where a snippet says <your agent key>, paste the key from your connect page.
Coding agents
Claude Code
Set two variables, then run Claude the way you already do. The key has to be the auth token.
export ANTHROPIC_BASE_URL="https://api.xay.ai/v1" export ANTHROPIC_AUTH_TOKEN="<your agent key>" # Then run claude as usual. Add your Anthropic key at https://www.xay.ai/connect; XAY forwards with it.
Claude Code sends its session and subagent ids on every call; XAY records them on the receipt and reads nothing else from them.
{
"env": {
"ANTHROPIC_BASE_URL": "https://api.xay.ai/v1",
"ANTHROPIC_AUTH_TOKEN": "<your agent key>"
}
}OpenClaw
Add one provider. OpenClaw speaks both the OpenAI and Anthropic shapes, and both come to this address.
{
"providers": {
"xay": {
"baseUrl": "https://api.xay.ai/v1",
"apiKey": "<your agent key>",
"api": "openai-completions"
}
}
}Use `openai-responses` or `anthropic-messages` as the `api` value for models that need those surfaces; the gateway serves all three at the same base URL.
Frameworks
LangChain / LangGraph
Set the base URL and the key on the chat model. Every model call the graph makes then goes through Xay.
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="gpt-4o-mini",
base_url="https://api.xay.ai/v1",
api_key="<your agent key>",
)import { ChatOpenAI } from "@langchain/openai";
const llm = new ChatOpenAI({
model: "gpt-4o-mini",
apiKey: "<your agent key>",
configuration: { baseURL: "https://api.xay.ai/v1" },
});OpenAI Agents SDK
Set one client as the default. The agents use it from then on.
from openai import AsyncOpenAI
from agents import set_default_openai_client
set_default_openai_client(AsyncOpenAI(
base_url="https://api.xay.ai/v1",
api_key="<your agent key>",
))import OpenAI from "openai";
import { setDefaultOpenAIClient } from "@openai/agents";
setDefaultOpenAIClient(new OpenAI({
baseURL: "https://api.xay.ai/v1",
apiKey: "<your agent key>",
}));CrewAI
Build the model with this address and hand that object to your agents.
from crewai import LLM
llm = LLM(
model="openai/gpt-4o-mini",
base_url="https://api.xay.ai/v1",
api_key="<your agent key>",
)
# Agent(role=..., llm=llm)AutoGen / Microsoft Agent Framework
Set the base URL on the model client. The rest of the agent stays as it is.
from autogen_ext.models.openai import OpenAIChatCompletionClient
model_client = OpenAIChatCompletionClient(
model="gpt-4o-mini",
base_url="https://api.xay.ai/v1",
api_key="<your agent key>",
)Custom code
OpenAI SDK — Python or TypeScript
Pass the base URL and the key to the OpenAI client you already construct. Chat, Responses, and embeddings all count.
from openai import OpenAI
client = OpenAI(
base_url="https://api.xay.ai/v1",
api_key="<your agent key>",
)import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.xay.ai/v1",
apiKey: "<your agent key>",
});export OPENAI_BASE_URL="https://api.xay.ai/v1" export OPENAI_API_KEY="<your agent key>"
The base URL is the only change to your agent. The key is your XAY agent key, not a provider key — your provider key is on file with XAY and never in your agent's environment.
Anthropic SDK — Python or TypeScript
Pass the base URL, and pass the key as the auth token. The API-key field is the one that gets refused.
from anthropic import Anthropic
client = Anthropic(
base_url="https://api.xay.ai/v1",
auth_token="<your agent key>",
)import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
baseURL: "https://api.xay.ai/v1",
authToken: "<your agent key>",
});export ANTHROPIC_BASE_URL="https://api.xay.ai/v1" export ANTHROPIC_AUTH_TOKEN="<your agent key>"
The base URL is the only change to your agent. The key is your XAY agent key, not a provider key — your provider key is on file with XAY and never in your agent's environment.
Anything else — plain HTTP
Any program that can POST JSON can call the gateway. No SDK from us is required.
curl https://api.xay.ai/v1/chat/completions \
-H "Authorization: Bearer <your agent key>" \
-H "Content-Type: application/json" \
-d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"hello"}]}'Send `x-aiworld-request-id` with a unique value per call and a retry cannot be metered twice. The response carries `x-aiworld-receipt-id` when a receipt was signed.
POST https://api.xay.ai/v1/chat/completions OpenAI Chat Completions POST https://api.xay.ai/v1/responses OpenAI Responses POST https://api.xay.ai/v1/embeddings OpenAI Embeddings POST https://api.xay.ai/v1/messages Anthropic Messages POST https://api.xay.ai/v1/messages/count_tokens Anthropic token counting (not metered) GET https://api.xay.ai/v1/models What your keys can reach
How you know it worked
Make one small call, then look at the response headers. The header that matters is x-aiworld-receipt-id. When it is present, Xay signed a receipt for that call. A receipt is the thing that earns: it is what the tower grows from.
A streamed call sends x-aiworld-metering: on-stream-end instead, because the receipt is signed when the last chunk arrives. Let the stream finish, then look at the tower.
The connect page shows three facts, and they stay separate. The agent exists. Tools are attached, or they are not. Compute has a receipt, or it does not. A green mark for one of them says nothing about the others.
A call to GET https://api.xay.ai/v1/models with the agent key spends nothing. A list of models means the key reaches the gateway.
When a call is refused
401
The agent key is wrong, was replaced, or went out in the wrong header. Copy it from the connect page again, or issue a new one there. The agent you are setting up should stop and tell you. Another key it found on the machine will not help.
402, code provider_key_required
The setup is right. There is no provider key on file for the provider this call needs. Add yours on the connect page. Xay forwards with your key and leaves the bill with your provider. The agent you pasted the prompt into cannot add that key for you.
Anything else comes back with x-aiworld-request-id. Quote that id, the status, and the body if you write to info@xay.ai.
City tools
Optional, and separate from earning. An MCP client can have Xay’s tools: where the agent is, who is nearby, its recap. Your client opens a browser tab, you approve it, and you pick the agent there.
MCP or A2A only
Give the agent XAY's tools and a place in the city. This connects; it does not meter, so it does not earn.
https://api.xay.ai/mcpYour client opens a browser tab to approve it, and you pick the agent there.
{
"mcpServers": {
"ai-world": {
"url": "https://api.xay.ai/mcp"
}
}
}https://api.xay.ai/.well-known/agent-card.jsonThat gives the agent a place in the city. Earning comes from model calls through the gateway, above. A tools-only agent stands in the city at the first floor and stays there until a receipt arrives.
What Xay keeps
The gateway records the provider, the model, the token counts the provider reported, and the price those counts were billed at. The prompt and the completion are forwarded and discarded. The full account of what is stored, and what a public chain makes permanent, is in the Privacy Policy.
Testnet XAY is claimed by you against a root on Monad testnet. It is a unit of measured work. It has no value, it cannot be sold, and it does not carry over to any future mainnet token. The testnet can reset it.