From wallet to first call in two minutes.
Base URL https://ai.dagentx.com/v1. Authenticate with Authorization: Bearer crk_… (or x-api-key for Anthropic clients).
Get USDC on Monad
Any EVM wallet works: WRAITH, MetaMask, Rabby. Bridge USDC from Ethereum, Base, Arbitrum or Solana with Circle CCTP (native USDC, no wrapped tokens), or swap on Monad. Keep a little MON for gas.
USDC on Monad 0x754704Bc059F8C67012fEd69BC8A327a5aafb603 Chain id 143 RPC https://rpc.monad.xyz
Deposit
On the Account page, connect and deposit any amount. It becomes your credit balance in the CandorCredits contract, keyed to your wallet. Or from a script:
cast send 0x754704Bc059F8C67012fEd69BC8A327a5aafb603 \ "approve(address,uint256)" 0x4e4b2fDD7026df99B91aEA847D248326C9e33751 20000000 cast send 0x4e4b2fDD7026df99B91aEA847D248326C9e33751 \ "deposit(address,address,uint256)" $YOUR_WALLET \ 0x754704Bc059F8C67012fEd69BC8A327a5aafb603 20000000 # $20
Register an API key
Click Create key. The key is generated in your browser and looks like
crk_<your address>_<secret>; only its SHA-256 hash is stored on chain. Copy it once. You can hold up to 64 keys and revoke any of them from your wallet.Scripted, the same thing is:
KEY="crk_$(echo ${YOUR_WALLET#0x} | tr A-F a-f)_$(openssl rand -hex 24)" HASH=0x$(printf %s "$KEY" | sha256sum | cut -d' ' -f1) cast send 0x4e4b2fDD7026df99B91aEA847D248326C9e33751 "registerKey(bytes32)" $HASHMake a call
export WRAITH_NEXUS_KEY=crk_… curl https://ai.dagentx.com/v1/chat/completions \ -H "Authorization: Bearer $WRAITH_NEXUS_KEY" -H "content-type: application/json" \ -d '{"model":"venice/zai-org-glm-5","messages":[{"role":"user","content":"hi"}]}'Optional: cap your spend
Set a daily cap or freeze settlement from the Account page (
setDailyCapon chain). The relay can never settle more than you allow.
Reference
- Base URL
https://ai.dagentx.com/v1- Text
POST /v1/chat/completions(OpenAI),POST /v1/messages(Anthropic); streaming supported- Embeddings
POST /v1/embeddings- Images
POST /v1/images/generations- Voice
POST /v1/audio/speech- Speech to text
POST /v1/audio/transcriptions(multipart)- Your account
GET /relay/account,GET /relay/usage,GET /relay/proof/:seq- Credits contract
0x4e4b2fDD7026df99B91aEA847D248326C9e33751
Copy, paste, done.
from openai import OpenAI
client = OpenAI(base_url="https://ai.dagentx.com/v1", api_key=os.environ["WRAITH_NEXUS_KEY"])
stream = client.chat.completions.create(
model="near/anthropic/claude-sonnet-5",
messages=[{"role": "user", "content": "Write a haiku about Monad"}],
stream=True,
)
for chunk in stream:
print(chunk.choices[0].delta.content or "", end="")import anthropic
client = anthropic.Anthropic(base_url="https://ai.dagentx.com", api_key=os.environ["WRAITH_NEXUS_KEY"])
msg = client.messages.create(
model="near/anthropic/claude-sonnet-5",
max_tokens=512,
messages=[{"role": "user", "content": "Hello"}],
)
print(msg.content[0].text)import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
import { generateText } from "ai";
const monad = createOpenAICompatible({
name: "wraith-nexus",
baseURL: "https://ai.dagentx.com/v1",
apiKey: process.env.WRAITH_NEXUS_KEY,
});
const { text } = await generateText({ model: monad("venice/zai-org-glm-5"), prompt: "Hello" });from langchain_openai import ChatOpenAI, OpenAIEmbeddings
llm = ChatOpenAI(base_url="https://ai.dagentx.com/v1", api_key=KEY, model="venice/zai-org-glm-5")
emb = OpenAIEmbeddings(base_url="https://ai.dagentx.com/v1", api_key=KEY,
model="venice/text-embedding-bge-m3", check_embedding_ctx_length=False)import litellm
r = litellm.completion(
model="openai/venice/zai-org-glm-5", # "openai/" = OpenAI-compatible route
api_base="https://ai.dagentx.com/v1",
api_key=KEY,
messages=[{"role": "user", "content": "Hello"}],
)# Most OpenAI-compatible tools read these: export OPENAI_BASE_URL=https://ai.dagentx.com/v1 export OPENAI_API_KEY=crk_… # Cursor: Settings → Models → OpenAI API Key = crk_…, # "Override OpenAI Base URL" = https://ai.dagentx.com/v1, # then add model names exactly as listed on /models.
# Image
img = client.images.generate(model="venice/flux-2-pro", prompt="a purple ghost over a city", size="1024x1024")
# Text to speech
audio = client.audio.speech.create(model="venice/tts-kokoro", voice="af_sky", input="Built on Monad.")
audio.write_to_file("out.mp3")
# Speech to text
with open("clip.mp3", "rb") as f:
t = client.audio.transcriptions.create(model="venice/openai/whisper-large-v3", file=f)
# Embeddings
e = client.embeddings.create(model="venice/text-embedding-bge-m3", input=["hello", "world"])How you are charged
Reserve, then bill
Each request reserves its worst-case cost (your max_tokens and input size). After the call you are billed the actual tokens, images, characters or audio seconds at the listed price. Lower max_tokens if a request is refused for balance.
Settled on chain
Usage is settled to CandorCredits periodically, each settlement carrying a Merkle root of your signed records. GET /relay/usage lists them; /relay/proof/:seq proves any one.
Errors
401 unknown or revoked key · 402 payment required (agents) · 429 balance too low, daily cap reached or rate limit (the message says which) · 503 try again shortly.