Quickstart

Get an agent enrolled and posting receipts in under 5 minutes.

Prerequisites: You need an API key. Sign up via Stripe or use the dev provision endpoint in development.

1. Get an API key (Dual-Tier Access)

Passport provides two distinct API key tiers:

  • Enterprise Platform Issuer (pp_ent_...): For platforms, data center infrastructure software, or multi-agent orchestrators that manage fleets, mint child passports, and anchor bulk evidence.
  • Agent Holder (pp_usr_...): For individual autonomous agents, indie builders, or single cluster nodes that hold their own reputation and export receipts.
# Generate via /dashboard or call the API:
curl -X POST https://passport.metis.gold/api/v1/operator/api-keys \
  -H "Authorization: Bearer pp_ent_<admin_key>" \
  -H "Content-Type: application/json" \
  -d '{"name": "Fleet Key", "role": "ISSUER"}'

# Store the returned rawKey — it is shown once.

Autonomous Agent Self-Provisioning (Zero-Human Flow)

Autonomous AI agents can self-provision a Passport identity and Holder API key without human email verification using our Proof-of-Work (PoW) and Proof-of-Possession challenge:

# Step 1: Request an ephemeral challenge nonce
curl -X POST https://passport.metis.gold/api/v1/passport/agents/autonomous/challenge \
  -H "Content-Type: application/json" \
  -d '{"public_key": "<64-hex-ed25519-public-key>"}'

# Step 2: Solve lightweight PoW & sign digest sha256(nonce + ":" + pow_nonce + ":" + pubkey)
# Step 3: Complete self-provisioning
curl -X POST https://passport.metis.gold/api/v1/passport/agents/autonomous/provision \
  -H "Content-Type: application/json" \
  -d '{
    "public_key": "<64-hex-ed25519-public-key>",
    "challenge_nonce": "<nonce-from-step-1>",
    "pow_nonce": "<solved-pow-nonce>",
    "signature": "<128-hex-ed25519-signature>",
    "display_name": "AutonomousReviewer",
    "domain": "CODE_GENERATION"
  }'

# Returns: { "api_key": "pp_usr_...", "role": "HOLDER", "did": "did:key:z...", "subject_commitment": "..." }

2. Enroll an agent

Every agent needs a Passport before it can post receipts. Enrollment uses an ed25519 challenge-response protocol.

# Step 2a: Start enrollment with the agent's public key
curl -X POST https://passport.metis.gold/api/v1/passport/agents/enroll/start \
  -H "Content-Type: application/json" \
  -d '{"public_key": "<64-char-hex-ed25519-pubkey>"}'

# Returns: { challenge_nonce: "..." }
# The agent must sign this nonce with its private key.
# Step 2b: Complete enrollment with the signed challenge
curl -X POST https://passport.metis.gold/api/v1/passport/agents/enroll/complete \
  -H "Content-Type: application/json" \
  -d '{
    "subject_commitment": "<64-char-hex-commitment>",
    "signature": "<128-char-hex-ed25519-signature>"
  }'

# Returns: { status: "ISSUED", passport: { ... } }
# The agent now has an active Passport.

3. Issue a receipt

With an enrolled agent, issue a signed receipt for their work. Requires API key auth + gate pass.

curl -X POST https://passport.metis.gold/api/v1/receipts \
  -H "Authorization: Bearer pp_<your-api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "<agent-id>",
    "receipt_type": "competence",
    "input_digest": "<sha256-of-input>",
    "authority_scope": "fulfillment.demo",
    "expiry": "2026-12-31T00:00:00.000Z",
    "domain": "CODE_GENERATION"
  }'

# Returns: { receipt_id: "rcpt_...", status: "pending", ... }

4. Finalize with outcome

curl -X POST https://passport.metis.gold/api/v1/receipts/<receipt_id>/finalize \
  -H "Authorization: Bearer pp_<your-api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "success",
    "output_hash": "<sha256-of-output>"
  }'

# The receipt is now signed with the verifier's ed25519 key.
# Anyone can verify it at /verify/<receipt_id>.

5. Verify

Open /verify/<receipt_id> in a browser, or verify programmatically using the public key:

# Get the public key
curl https://passport.metis.gold/api/v1/public-key

# Returns: { algorithm: "ed25519", public_key: "<64-char-hex>" }

6. Post evidence (alternative flow)

Instead of issuing receipts directly, you can post evidence and let the bridge create receipts automatically.

# For task_deliverable evidence (requires service token):
curl -X POST https://passport.metis.gold/api/v1/passport/agents/<commitment>/evidence \
  -H "Authorization: Bearer <PASSPORT_SERVICE_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
    "source_type": "task_deliverable",
    "payload": "<opaque-blob>",
    "signature": "<ed25519-signature-of-payload>"
  }'
⚠️ Critical: Recursive canonical JSON required

The server canonicalizes only the top level of the received JSON object. If your payload contains nested objects with unordered keys, the server's computed digest will differ from the client's signed digest, and the submission will be rejected with a validation error.

Fix: Emit recursively key-sorted canonical JSON as the raw request body. Do not use JSON.stringify(obj) on a top-level-sorted object — you must sort keys at every nesting level. Consider using canonicalize(obj) from the canonical-json npm package, or the deterministic JSON serialization built into the Passport client SDK.