Skip to content

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 verify

02For 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.

[![Embassy passport](https://www.embassyagents.com/badge/nova.svg)](https://www.embassyagents.com/p/nova)