Skip to content
Skip the search — install the Self skill Let your AI agent integrate Self for you.

Start typing to search the documentation.

Building an Agent

This guide walks through registering an AI agent with Self Agent ID and making authenticated requests. By the end, your agent will have an on-chain identity backed by a real passport verification.

1. Choose Your SDK

LanguagePackageInstall
TypeScript@selfxyz/agent-sdknpm install @selfxyz/agent-sdk
Pythonselfxyz-agent-sdkpip install selfxyz-agent-sdk
Rustself-agent-sdkcargo add self-agent-sdk

All three SDKs have identical functionality with language-idiomatic naming.

2. Register Your Agent

Six registration modes — choose based on your use case:

ModeBest forWallet needed?
wallet-freeEmbedded agents, IoT, CLI-onlyNo
ed25519OpenClaw, Eliza, IronClaw agentsNo
linkedAutonomous AI agentsYes (human’s)
ed25519-linkedEd25519 agents with human walletYes (human’s)
privySocial login (Google, Twitter)No
smartwalletConsumer-facing, passkey UXNo

Via the SDK (simplest)

Render the passport-scan QR in your own frontend and read the result from the chain. No hosted service is involved. This is the recommended path. See Register an Agent with the SDK for the full runnable example (generate the agent key, sign the challenge, build the QR with @selfxyz/qrcode, mint on-chain).

Via CLI

# Install the CLI (comes with the SDK)
npm install -g @selfxyz/agent-sdk

# Initialize registration
self-agent register init \
  --mode linked \
  --human-address 0xYourWallet \
  --network mainnet \
  --minimum-age 18 \
  --ofac

# Print the QR (fetched from the API) to scan with the Self app
self-agent register open --session .self/session-*.json

# Wait for verification to complete
self-agent register wait --session .self/session-*.json

# Export the agent private key
self-agent register export --session .self/session-*.json --unsafe --print-private-key

The CLI talks to https://agent-api.self.xyz by default (override with SELF_AGENT_API_BASE).

Via A2A Protocol (for agents)

Agents can self-register by sending a JSON-RPC request to the A2A endpoint:

curl -X POST https://agent-api.self.xyz/api/a2a \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "message/send",
    "params": {
      "message": {
        "role": "user",
        "parts": [{ "type": "data", "data": { "intent": "register" } }]
      }
    }
  }'

The endpoint returns a QR code and deep link. A human scans the QR with the Self app to complete verification. Send { "intent": "help" } to see all available modes and a decision guide.

Via REST API

curl -X POST https://agent-api.self.xyz/api/agent/register \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "linked",
    "network": "mainnet",
    "humanAddress": "0xYourWallet",
    "disclosures": { "minimumAge": 18, "ofac": true }
  }'

Poll /api/agent/register/status?token=<token> until stage: "completed".

Via Smart Wallet (passkeys)

Smart-wallet mode uses a passkey to create a ZeroDev Kernel smart account as the guardian, with gasless operations via the Pimlico paymaster on mainnet. Build the passkey step into your own frontend with @zerodev/sdk and @zerodev/passkey-validator; the agent keypair and challenge are generated the same way as linked. The gasless bundler and paymaster are proxied through https://agent-api.self.xyz/api/aa/*. See Registration Modes.

3. Sign Outbound Requests

Every SDK provides agent.fetch() which automatically signs requests with three headers:

import { SelfAgent } from "@selfxyz/agent-sdk";

const agent = new SelfAgent({
  privateKey: process.env.AGENT_PRIVATE_KEY!,
  network: "mainnet",
});

const res = await agent.fetch("https://api.example.com/data", {
  method: "POST",
  body: JSON.stringify({ query: "test" }),
});

The signed headers:

HeaderValue
x-self-agent-addressAgent’s Ethereum address
x-self-agent-signatureECDSA signature of keccak256(timestamp + METHOD + path + bodyHash)
x-self-agent-timestampUnix timestamp (ms)

4. Check Registration Status

const registered = await agent.isRegistered();
const info = await agent.getInfo();
// { agentId, isVerified, proofProvider, verificationStrength, ... }

5. Read Credentials

const creds = await agent.getCredentials();
// { nationality, olderThan, ofac, dateOfBirth, gender, issuingState, ... }

Credentials are ZK-attested — extracted from passport data without revealing the full document.

6. Set an Agent Card (A2A)

Agent cards enable discovery in agent-to-agent protocols:

await agent.setAgentCard({
  name: "My Agent",
  description: "Analyzes market data",
  url: "https://myagent.example.com",
  skills: [{ name: "market-analysis", description: "Analyzes crypto markets" }],
});

const card = await agent.getAgentCard();

Cards are stored on-chain and readable by any agent or service.

Gotchas

Next Steps

Was this page helpful?