Reelin ID API
API Reference
The Reelin ID API lets platforms verify that any inbound AI agent request was authorized by a real, verified human. All endpoints live under:
https://api.reelin.idAll requests and responses are JSON. All responses return HTTP 200 unless there is a request error (4xx) or server error (5xx).
Authentication
B2B verification endpoints require an API key passed in the X-Reelin-Api-Key request header. Consumer passport endpoints require a wallet signature.
Issue an API key from your Reelin dashboard or via the POST /v1/passport/dev-key endpoint.
X-Reelin-Api-Key: rk_live_your_key_here| Tier | Verifications / month | Rate limit | Price |
|---|---|---|---|
| Free | 1,000 | 100 req / min | $0 |
| Growth | 100,000 | 1,000 req / min | $49 / mo |
| Enterprise | Unlimited | Custom + SLA | Contact us |
/v1/verifyVerifies that a Reelin Passport token is valid. Checks the Ed25519 cryptographic signature, validates the DID matches the registered human root, and confirms the passport has not been revoked or suspended.
Request body
| Parameter | Type | Description |
|---|---|---|
reelin_passport_tokenrequired | object | The passport token object attached to the agent's outbound request. |
Example request
{
"reelin_passport_token": {
"version": "1.0.0",
"root_did": "did:reelin:0x71C7656EC7ab88b098defB751B7401B5f6d8976F",
"agent_pubkey": "302a300506032b6570032100a3f9...",
"nonce": "b7e2c1f4a9d3e8b1",
"payload_hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"signature": "7d4e1a9f3b2c8e5f1a..."
}
}Example responses
200 · Verified
{
"verified": true,
"humanRootDID": "did:reelin:0x71C7656EC7ab88b098defB751B7401B5f6d8976F",
"passportId": "rp_9f3b2c1a"
}200 · Not verified
{
"verified": false,
"reason": "Passport has been revoked."
}Response fields
| Field | Type | Description |
|---|---|---|
verified | boolean | true if the passport is valid, active, and signature is correct. |
humanRootDID | string | The DID of the verified human who issued this passport. Only present when verified is true. |
passportId | string | Internal passport identifier. Only present when verified is true. |
reason | string | Human-readable reason for failure. Only present when verified is false. |
Passport endpoints
/v1/auth/challengeNoneReturns a challenge string for a given wallet address. The user signs this string to authenticate.
/v1/auth/registerWallet sigRegisters or authenticates a HumanRoot. Creates the DID if it does not exist.
/v1/passport/issueWallet sigIssues a new agent passport. Returns the Ed25519 public key and a one-time private key. Private key is never stored.
/v1/passport/listNoneReturns all passports associated with a given wallet address, including status and creation date.
/v1/passport/revokeWallet sigPermanently revokes a passport. Revoked passports return verified: false on all future /verify calls.
/v1/passport/dev-keyWallet sigIssues a new B2B developer API key for calling the /verify endpoint. Key hash stored; raw key returned once.
/v1/verify/statsAPI keyReturns aggregate verification statistics: total passports, active passports, verification count and success rate.
Passport token schema
Agents attach this JSON structure to every outbound request. The signing string is the concatenation of all fields, colon-separated.
{
"reelin_passport_token": {
"version": "1.0.0", // Protocol version
"root_did": "did:reelin:0x...", // Human identity DID
"agent_pubkey": "hex-encoded-der", // Ed25519 SPKI public key
"nonce": "16-byte-hex", // Replay-attack prevention
"payload_hash": "sha256-hex", // SHA-256 of the action body
"signature": "ed25519-sig-hex" // Signs: version:did:pubkey:nonce:hash
}
}| Field | Type | Description |
|---|---|---|
version | string | Protocol version. Currently 1.0.0. |
root_didrequired | string | The DID of the human who issued this passport. Format: did:reelin:0x... |
agent_pubkeyrequired | string | Hex-encoded DER SPKI representation of the agent's Ed25519 public key. |
noncerequired | string | 16-byte cryptographically random hex string. Prevents replay attacks. |
payload_hashrequired | string | SHA-256 hex hash of the full request body. Links the signature to a specific action. |
signaturerequired | string | Ed25519 hex signature over: version:root_did:agent_pubkey:nonce:payload_hash |
Errors
The API returns standard HTTP status codes and a JSON body with an error field.
| Status | Code | Description |
|---|---|---|
400 | bad_request | Request body is missing required fields or fails schema validation. |
401 | unauthorized | Missing or invalid X-Reelin-Api-Key, or wallet signature verification failed. |
403 | forbidden | Authenticated but not permitted to perform this action (e.g. revoking another user's passport). |
404 | not_found | HumanRoot or passport does not exist. |
429 | rate_limited | Too many requests. Back off and retry after the Retry-After header. |
500 | internal_error | Server error. Retries with exponential backoff are safe. |
SDKs & examples
Official SDKs are in development. In the meantime, use the REST API directly.
Node.js / TypeScript
import { ReelinID } from "@reelin-id/sdk";
const reelin = new ReelinID({ apiKey: process.env.REELIN_API_KEY });
app.post("/apply", async (req, res) => {
const token = req.headers["x-reelin-passport"];
const result = await reelin.verify(token);
if (!result.verified) {
return res.status(403).json({ error: "Unverified agent." });
}
console.log("Human:", result.humanRootDID);
processApplication(req.body);
});Python
from reelin_id import ReelinID
client = ReelinID(api_key=os.environ["REELIN_API_KEY"])
@app.route("/apply", methods=["POST"])
def apply():
token = request.headers.get("X-Reelin-Passport")
result = client.verify(token)
if not result.verified:
return jsonify({"error": "Unverified agent"}), 403
process_application(request.json)
return jsonify({"status": "ok"})Changelog
v1.0.0June 2026
- + Initial release of Reelin ID API
- + POST /v1/verify, Ed25519 passport token verification
- + Full passport lifecycle: issue, list, revoke
- + Developer API key management
- + On-chain anchor via ReelinRegistry.sol (EVM)
- + Swiftdroom integration, first live consumer deployment