API Reference
Common Response Structure:
{
"code": 0, // 0 for success, non-zero for failure
"message": "ok",
"data": { ... } // Business data, see each API for details
}
Authentication Methods:
| Caller | Authentication | Request Header |
|---|---|---|
| Agent Client | No api_key, Ed25519 self-signing | None |
| Business Backend | api_key (product_code='agent' app) | Authorization: Bearer <api_key> |
API List
| Group | API | Method | Path | Caller |
|---|---|---|---|---|
| Registration | Initiate Registration | POST | /palm/openai/x/agent/register/init | Agent Client |
| Registration | Poll Registration Status | POST | /palm/openai/x/agent/register/status | Agent Client |
| Authorization | Exchange Code for open_id | POST | /palm/openai/x/agent/code/exchange | Business Backend |
| Verification | Fetch Public Key / Check Device | POST | /palm/openai/x/agent/verify/device | Business Backend |
| Verification | Online Signature Verification | POST | /palm/openai/x/agent/verify/signature | Business Backend |
| Verification | Initiate Step-up | POST | /palm/openai/x/agent/stepup/create | Business Backend |
| Verification | Query Step-up | POST | /palm/openai/x/agent/stepup/query | Business Backend |
1. Initiate Registration
POST /palm/openai/x/agent/register/init · Agent Client (Ed25519 self-signing)
The Agent generates an Ed25519 key pair locally and signs the message with the private key to prove it holds the key, returning the real person authorization page URL. Message to sign: message = "clawkey-register-" + timestamp_ms.
Request Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
AppId | string | Yes | Public app_id from the console |
DeviceId | string | Yes | Agent external identity, ^[A-Za-z0-9_-]{1,64}$, immutable after registration |
PubkeyDer | string | Yes | base64(Ed25519 SPKI DER) |
Message | string | Yes | clawkey-register-<timestamp>, must match Timestamp exactly |
Signature | string | Yes | base64(Ed25519(message)), 64-byte raw signature |
Timestamp | int64 | Yes | Unix milliseconds, must be within ±5min of server time |
Response data:
| Field | Type | Description |
|---|---|---|
SessionId | string | Registration session ID, used for subsequent polling |
RegistrationUrl | string | Real person authorization page URL, pass to the real person |
ExpiresAt | int64 | Session expiration timestamp (seconds), TTL 10min |
Common Error Codes:
| code | Description |
|---|---|
| 2030140 | Signature verification failed |
| 2030141 | Message format error |
| 2030142 | Timestamp exceeds ±5min |
| 2030143 | Replay detected (same pubkey + ts already used) |
| 2030144 | device_id already taken |
| 2030145 | Public key fingerprint already exists |
2. Poll Registration Status
POST /palm/openai/x/agent/register/status · Agent Client
After the real person scans their palm to confirm, the Agent polls with SessionId to obtain the one-time Code (recommended 2s interval).
Request Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
SessionId | string | Yes | Session ID returned by register/init |
Response data:
| Field | Type | Description |
|---|---|---|
Status | string | pending / completed / expired / failed |
DeviceId | string | Echoed when completed |
Code | string | One-time authorization code returned when completed, TTL 5min; open_id is NOT returned |
3. Exchange Code for open_id
POST /palm/openai/x/agent/code/exchange · Business Backend (api_key)
The business exchanges the one-time Code for (device_id, open_id), then binds it to the local account. Authorization is truly completed at this point.
Request Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
Code | string | Yes | One-time authorization code passed from the Agent |
Response data:
| Field | Type | Description |
|---|---|---|
DeviceId | string | Agent external identity |
OpenId | string | Real person owner's per-app identifier |
Registered | bool | Whether registration is complete |
Codeis one-time use. Expired or duplicate redemption returns an error.code.app_idmust match theoc_appidcorresponding to your api_key, otherwiseErrAgentForbidden.
4. Fetch Public Key / Check Device
POST /palm/openai/x/agent/verify/device · Business Backend (api_key)
Fetch the public key by (device_id, open_id) for local caching (TTL ≤15min) and signature verification. Recommended method.
Request Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
DeviceId | string | Yes | Agent external identity |
OpenId | string | No | Optional but strongly recommended: verify the device is bound to this person |
Response data:
| Field | Type | Description |
|---|---|---|
Registered | bool | Whether still bound to a real person (false if deactivated/revoked) |
DeviceId | string | Echoed |
OwnerOpenId | string | Real person owner, provided when Registered=true |
PubkeyDer | string | base64(SPKI DER), cache for local signature verification |
CreatedAt | int64 | Agent registration timestamp (seconds) |
Revocation delay = cache TTL. For faster revocation detection, shorten the TTL, or use online signature verification for critical requests.
5. Online Signature Verification
POST /palm/openai/x/agent/verify/signature · Business Backend (api_key)
Submit the entire Agent signature to Palm for online verification. Agent canonical signing string:
"palmauth-agent-req-v1" + "\n" + device_id + "\n" + method + "\n"
+ path + "\n" + sha256_hex(body_bytes) + "\n" + timestamp_ms + "\n" + nonce
Request Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
DeviceId | string | Yes | Agent external identity |
PubkeyDer | string | Yes | base64(SPKI DER) |
Message | string | Yes | Plaintext to verify (canonical string) |
Signature | string | Yes | base64(64-byte raw signature) |
Timestamp | int64 | Yes | Unix milliseconds, ±5min |
Nonce | string | No | Anti-replay random string |
Response data:
| Field | Type | Description |
|---|---|---|
Verified | bool | Whether the signature is valid (cryptographic verification) |
Registered | bool | Whether still bound to a real person (DB status, independent of Verified) |
DeviceId | string | Echoed |
OwnerOpenId | string | Real person owner, provided when Registered=true |
6. Initiate Step-up
POST /palm/openai/x/agent/stepup/create · Business Backend (api_key)
Request Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
DeviceId | string | Yes | Agent external identity |
ChallengeId | string | Yes | Business-generated UUID v4, idempotency key |
Action | string | Yes | Business action identifier, e.g., transfer_money |
ActionDetail | string | Yes | Passthrough JSON, ≤512B, displayed to the real person |
Level | int32 | Yes | 1=async notification only, immediate approval; 2/3=real person must scan palm |
NonBlocking | bool | No | Often true for Level 1 |
Response data:
| Field | Type | Description |
|---|---|---|
ChallengeId | string | Echoed |
ExpiresAt | int64 | Verification expiration timestamp (seconds) |
Status | string | pending (Level 2/3) / approved (Level 1) |
AssertionJwt | string | Returned immediately when approved (Level 1) |
Idempotent: submitting the same
ChallengeIdagain returns the existing status, no new verification is created.
7. Query Step-up
POST /palm/openai/x/agent/stepup/query · Business Backend (api_key)
Short-poll for verification results. Returns Assertion JWT once when approved.
Request Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
ChallengeId | string | Yes | challenge_id from initiation |
Response data:
| Field | Type | Description |
|---|---|---|
Status | string | pending / approved / denied / expired |
AssertionJwt | string | One-time return when approved |