API Reference
Base URL: https://api.clawkey.ai/v1
Local development: http://localhost:3000/v1
All endpoints are unauthenticated. Security is provided through Ed25519 signature verification within the request payloads.
Endpoints
| Method | Endpoint | Description |
POST | /agent/register/init | Start registration session |
GET | /agent/register/{sessionId}/status | Poll registration status |
POST | /agent/verify/signature | Verify a signature |
GET | /agent/verify/device/{deviceId} | Look up agent by device ID |
GET | /agent/verify/public-key/{publicKey} | Look up agent by public key |
GET | /human/leaderboard | Human ownership leaderboard |
POST /agent/register/init
Start a registration session. The agent sends a signed proof that it controls its Ed25519 key. ClawKey creates a short-lived session and returns a registrationUrl for the human owner to complete VeryAI palm verification.
Request Body
Content-Type: application/json
| Field | Type | Required | Description |
deviceId | string | Yes | Agent/device identifier (e.g. public key hash or app ID) |
publicKey | string | Yes | Ed25519 public key, base64 DER SPKI |
message | string | Yes | Exact message that was signed (e.g. clawkey-register-1738500000000) |
signature | string | Yes | Ed25519 signature over message, base64 |
timestamp | integer | Yes | Unix timestamp (ms) when the challenge was created |
Response (201)
{
"sessionId": "uuid",
"registrationUrl": "https://clawkey.ai/register/...",
"expiresAt": "2026-02-02T12:00:00Z"
}
| Field | Type | Description |
sessionId | string | Use to poll registration status |
registrationUrl | URI | Human owner opens this to complete VeryAI palm verification |
expiresAt | datetime | Session expiration (ISO 8601) |
Error Responses
| Code | Description |
| 400 | Bad request — invalid or missing fields |
| 409 | Conflict — agent already registered (deviceId exists) |
| 500 | Server error |
GET /agent/register/{sessionId}/status
Poll to check whether the human owner has completed VeryAI palm verification.
Path Parameters
| Parameter | Type | Description |
sessionId | string | Session ID from the /agent/register/init response |
Response (200)
{
"status": "completed",
"deviceId": "my-agent-device-id",
"registration": {
"publicKey": "...",
"registeredAt": "2026-02-02T12:00:00Z"
}
}
| Field | Type | Description |
status | enum | pending | completed | expired | failed |
deviceId | string | Agent/device ID (present when completed) |
registration | object | Contains publicKey and registeredAt (present when completed) |
Error Responses
| Code | Description |
| 404 | Session not found |
| 500 | Server error |
POST /agent/verify/signature
Verify that a message was signed by the given Ed25519 key and whether the agent is registered under a verified human.
Request Body
Content-Type: application/json
Same AgentChallenge schema as /agent/register/init:
| Field | Type | Required | Description |
deviceId | string | Yes | Agent/device identifier |
publicKey | string | Yes | Ed25519 public key, base64 DER SPKI |
message | string | Yes | Exact message that was signed |
signature | string | Yes | Ed25519 signature over message, base64 |
timestamp | integer | Yes | Unix timestamp (ms) |
Response (200)
{
"verified": true,
"registered": true
}
| Field | Type | Description |
verified | boolean | Signature is valid for this key and message |
registered | boolean | Agent is registered under a verified human |
Error Responses
| Code | Description |
| 400 | Bad request — invalid or missing fields |
| 500 | Server error |
GET /agent/verify/device/{deviceId}
Look up an agent's registration and verification status by its device ID.
Path Parameters
| Parameter | Type | Description |
deviceId | string | Agent/device identifier |
Response (200)
{
"registered": true,
"verified": true,
"humanId": "uuid",
"registeredAt": "2026-02-02T12:00:00Z"
}
| Field | Type | Description |
registered | boolean | Agent is registered in ClawKey |
verified | boolean | Agent is under a verified human owner |
humanId | string (uuid) | Human (verified person) identifier |
registeredAt | string | When the agent was registered (ISO date or "never") |
Error Responses
| Code | Description |
| 500 | Server error |
GET /agent/verify/public-key/{publicKey}
Look up an agent's status by its Ed25519 public key (base64 DER SPKI). Use base64url encoding for the path parameter if the key contains + or /.
Path Parameters
| Parameter | Type | Description |
publicKey | string | Ed25519 public key, base64 DER SPKI (base64url-safe in URL) |
Response (200)
Same schema as /agent/verify/device/{deviceId}.
GET /human/leaderboard
Returns a list of human IDs and their agent count, sorted by agent count descending. When counts are equal, humans who registered their first agent earlier appear first.
Response (200)
[
{
"humanId": "uuid",
"agentCount": 5,
"earliestRegisteredAt": "2026-01-15T10:00:00Z"
},
{
"humanId": "uuid",
"agentCount": 3,
"earliestRegisteredAt": "2026-01-20T14:30:00Z"
}
]
| Field | Type | Description |
humanId | string (uuid) | Human (verified person) identifier |
agentCount | integer | Number of agents registered under this human |
earliestRegisteredAt | datetime | When their first agent was registered |
Error Format
All error responses follow this format:
{
"error": "Human-readable message",
"code": "optional_code",
"details": {}
}
Common Error Codes
| HTTP Code | Meaning |
| 400 | Bad request — invalid or missing fields |
| 404 | Session or device not found |
| 409 | Agent already registered (deviceId already exists) |
| 500 | Server error |