HTTP endpoints for sponsored agent registration. External agents (with no SDK access) use this flow to obtain a passportId and agent private key — routed through a human principal who signs the on-chain transaction.
INFOAll API endpoints are served by the Next.js app at http://localhost:3000 in development. Deploy the demo/ui package to Vercel or any Node.js host for a public URL.
Base URL
bash
BASE_URL=http://localhost:3000 # development
BASE_URL==https://sigiltwoelves.vercel.app # production
Registration Flow
1Agent POSTs to /register/request — gets requestId + approvalUrl
2Agent shows approvalUrl to the principal (human)
3Principal visits the approve page, connects wallet, signs register() tx
4Agent polls /register/status/:requestId every 5s until approved
Generate a fresh agent keypair, pre-compute the passportId, and create a pending registration with a 24-hour TTL. Returns a requestId and an approvalUrl to present to the principal.
Request Body
Parameter
Type
Description
principalAddressrequired
string
0x + 40 hex chars. The wallet that will own the AgentPassport iNFT.
agentDescriptionrequired
string
Free-text description of the agent (≤ 280 characters).
permissionsrequired
object
Permission manifest defining what the agent is authorized to do.
permissions.whitelistedContracts
string[]
Contract addresses the agent may interact with.
permissions.maxTxValuePerWindow
Record<string, number>
Max token value per rolling window. e.g. { 'OG': 0 }
Rate limit exceeded: max 5 requests per IP per hour, or max 10 pending per principal.
Poll Registration Status
GET/api/v1/passport/register/status/:requestId
Poll until the principal approves the registration. The first response with status: "approved" includes agentPrivateKey — it is never returned again after that.
async function waitForApproval(requestId: string, baseUrl: string) {
while (true) {
const res = await fetch(`${baseUrl}/api/v1/passport/register/status/${requestId}`);
const data = await res.json();
if (data.status === "approved") {
if (data.agentPrivateKey) {
// Store immediately — won't be returned again
process.env.SIGIL_AGENT_PRIVATE_KEY = data.agentPrivateKey;
console.log("passportId:", data.passportId);
}
return data;
}
if (data.error) throw new Error(data.error);
await new Promise(r => setTimeout(r, 5000)); // poll every 5s
}
}
Approve Registration
POST/api/v1/passport/approve/:requestId
Called by the /approve/:requestId browser page after the principal submits the SigilRegistry.register() transaction. Not normally called directly by agents.
INFOThe approve endpoint verifies a principalSignature over the message sigil-approve:<requestId>. It must recover to the principalAddress stored in the pending registration. This prevents a third party from marking a request as approved.
Request Body
Parameter
Type
Description
txHashrequired
string
The register() transaction hash (0x + 64 hex chars).
passportIdrequired
string
The passportId confirmed by the transaction.
principalSignaturerequired
string
Principal's personal_sign over 'sigil-approve:<requestId>'.
Response
json
{ "ok": true, "passportId": "0x..." }
Rate Limits
Parameter
Type
Description
IP rate limit
5 / hour
Max 5 new registration requests per IP address per hour.
Principal limit
10 active
Max 10 pending (unapproved) registrations per principal address at any time.
TTL
24 hours
Pending registrations expire after 24 hours if not approved. Local development uses a 60-second sweeper; hosted deployments should back the API with durable KV.
NOTEHosted/serverless deployments should set KV_REST_API_URL and KV_REST_API_TOKEN (or the raw Upstash equivalents) so the request, approve, and status routes share durable state across instances. If those vars are unset, the app falls back to an in-memory store for local development only.
Additional Endpoints
GET/SKILL.md
The agent onboarding document. Machine-readable. Any AI agent can fetch and parse this to self-onboard without human guidance.
GET/api/storage/:rootHash
Server-side proxy to 0G Storage. Returns raw bytes for a given content-addressed root hash. Used by the resolver UI to download proof envelopes and encrypted manifests without browser-side 0G SDK dependencies.