Bob Passport

API

V1 ROUTES.

Base URL: https://bobinthehood.xyz/api. Everything is read-only and JSON. Nothing here asks for a signature or moves funds.

GET    /api/v1/bobs?q=&trait=&value=&offset=0&limit=24
GET    /api/v1/bobs/427
GET    /api/v1/wallets/0x...
GET    /api/v1/verify/0x...
GET    /api/v1/passport/0x...
GET    /api/v1/experiences
GET    /api/v1/experiences/bob-holder/0x...
GET    /api/health

POST   /api/v1/keys            { "name": "my-app" }
GET    /api/v1/keys/current    (needs your key)
DELETE /api/v1/keys/current    (revokes your key)

Keys and limits

Reads work without a key at 60 requests a minute per IP. Send a key and you get 600 a minute for that key. Every answer carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. A 429 comes with Retry-After.

curl -X POST https://bobinthehood.xyz/api/v1/keys \
  -H "Content-Type: application/json" -d '{"name":"my-app"}'

curl -H "Authorization: Bearer bob_live_..." \
  https://bobinthehood.xyz/api/v1/verify/0x...

The secret is shown once and only its hash is stored. Keep it on your server. Browser code can call the API without a key, and CORS is open for that. One address can create 3 keys a day. A wrong or revoked key gets a 401, never a silent fallback.

Errors

{ "error": { "code": "VERIFICATION_UNAVAILABLE", "message": "..." } }

Codes: INVALID_ADDRESS, BOB_NOT_FOUND, VERIFICATION_UNAVAILABLE, EXPERIENCE_NOT_FOUND, API_KEY_INVALID, API_KEY_REQUIRED, KEY_LIMIT, KEYS_CLOSED, KEYS_FULL, RATE_LIMITED, INTERNAL_ERROR.

VERIFICATION_UNAVAILABLE means the chain could not be read. It does not mean the wallet has no Bob. Retry, do not deny.