Docs
API & SDK
Verify that an agent is who it claims in two calls. Rules live on the Standard page. Built on Robinhood Chain. Not affiliated with or endorsed by Robinhood.
01Quickstart
Quickstart
The SDK is the workspace package @embassy/sdk in packages/sdk (built on viem), or call the HTTP API from any language.
import { Embassy, signChallenge } from "@embassy/sdk";
const cl = new Embassy({ baseUrl: "https://www.embassyagents.com" });
const challenge = await cl.createChallenge("nova"); // you → challenge
const signed = await signChallenge(agentPrivateKey, challenge); // the agent signs it (EIP-191)
const { valid, tier } = await cl.verifyAgent("nova", signed); // one call to verify02For agents
For agents
Your agent controls an EVM account (its agent address). It proves it is the agent behind a passport by signing the exact message of a challenge with EIP-191 personal_sign. Keep the private key in the agent's environment; never send it anywhere.
import { signChallenge, handleChallenge } from "@embassy/sdk";
// A. Sign a challenge someone sent you (EIP-191, with the agent's EVM key):
const signed = await signChallenge(process.env.AGENT_PRIVATE_KEY!, challenge);
// B. Or expose an endpoint that answers challenges automatically
// (list its URL as your passport's "Agent endpoint"):
export async function POST(req: Request) {
return Response.json(await handleChallenge(await req.json(), process.env.AGENT_PRIVATE_KEY!));
}To earn the agent stamp, request a challenge with { "purpose": "agent_stamp" } and submit the signature to /api/v1/verify, or use “Challenge my endpoint” in your dashboard.
03For verifiers
For verifiers
Lookups are public and need no key. Always check status: suspended and revoked passports are invalid.
import { Embassy } from "@embassy/sdk";
const cl = new Embassy({ baseUrl: "https://www.embassyagents.com" });
// Look someone up (no signature, no auth):
const passport = await cl.getPassport("nova"); // id, #number, handle, agent or token address
if (passport.status !== "active") throw new Error("not trusted");
// Prove the agent you're talking to IS that passport:
const challenge = await cl.createChallenge("nova");
const signed = await askTheAgentToSign(challenge); // { nonce, signature }
const { valid, tier } = await cl.verifyAgent("nova", signed);04HTTP API
HTTP API
Base URL https://www.embassyagents.com/api/v1. JSON in and out. Read and verify endpoints send open CORS headers. Addresses are EIP-55 checksummed; every response carries chainId.
{
"passport": {
"id": "8c0e…", "chainId": 4663, "number": 42, "displayId": "000042", "handle": "nova",
"name": "Nova", "status": "active", "tier": "verified", "origin": "external",
"ownerWallet": "0x71C7…976F", "agentAddress": "0x4B20…02dB",
"registry": "0x…", "mintTx": "0x…", "issuedAt": "2026-10-06T10:00:00Z",
"stamps": [{ "kind": "owner", … }, { "kind": "endpoint", … }, { "kind": "x", "value": "nova" }],
"links": [{ "kind": "x", "url": "https://x.com/nova", "proven": true }]
},
"verification": { "tier": "verified", "rule": "…", "missing": [] }
}- > Challenges expire after 10 minutes and work once. Replays return
valid: false, reason: "nonce_invalid". - > Signatures are EIP-191 over the UTF-8 message, recovered against the agent address; smart-contract agents verify through ERC-1271.
- > A challenge's purpose and chain id are part of the signed message, so a signature can't be replayed across purposes or networks.
05On-chain
On-chain
Passports live in the PassportRegistry contract on Robinhood Chain (chain 4663) as soulbound ERC-721 tokens (ERC-5192). Read statusOf(id), passportOf(id), passportOfAgent(address), or the ERC-8004 views getAgentWallet(id) and getMetadata(id, key). The token URI serves ERC-721 metadata that is also an ERC-8004 registration file.
06Errors and limits
Errors and limits
Errors look like { "error": "message", "code": "machine_code" } with a matching HTTP status. Limits are per IP (and per API key, when you send Authorization: Bearer ap_…):
- > Lookups 240/min · Directory 120/min
- > Challenge 60/min (600/min with an API key) · Verify 120/min (600/min with an API key)
- > 429 responses include retryAfter in seconds
07Badge
Badge
Embed a live badge in a README or site. It shows the number and current tier, and turns red if the passport is suspended or revoked.
[](https://www.embassyagents.com/p/nova)