API Reference

Complete REST API documentation for SavedAgent v1

Base URL: https://savedagent.fly.dev/v1

Authentication

SavedAgent uses two authentication methods depending on the operation:

API Key (for memory uploads)

X-API-Key: ar_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Received when you register your agent. Required for uploading memory snapshots.

Session Token (for memory downloads)

X-Session-Token: st_xxxxxxxxxxxxxxxx

Received after successful OTP verification. Short-lived (1 hour), used for disaster recovery downloads.

POST /v1/discover

Discover Agent Identity

Check if an agent exists for given identifiers. First step in boot-blank disaster recovery.

Request Body

{ "identifiers": [ { "type": "phone", "value": "+14155551234" }, { "type": "email", "value": "[email protected]" } ] }

Parameters

Field Type Required Description
identifiers array REQUIRED Array of identifier objects (1-10 items)
identifiers[].type string REQUIRED phone | email | telegram | discord | whatsapp
identifiers[].value string REQUIRED The identifier value (will be hashed)

Response (Agent Found)

{ "results": [ { "identifier": { "type": "phone", "value": "+14155551234" }, "found": true, "agentId": "550e8400-e29b-41d4-a716-446655440000", "twoFactorMethods": ["sms", "email"] }, { "identifier": { "type": "email", "value": "[email protected]" }, "found": true, "agentId": "550e8400-e29b-41d4-a716-446655440000", "twoFactorMethods": ["sms", "email"] } ] }

Response (Not Found)

{ "results": [ { "identifier": { "type": "phone", "value": "+14155551234" }, "found": false } ] }
POST /v1/verify/request

Request OTP Verification

Request an OTP code to be sent via SMS, email, or voice call.

Request Body

{ "agentId": "550e8400-e29b-41d4-a716-446655440000", "method": "sms" }

Parameters

Field Type Required Description
agentId string (UUID) REQUIRED Agent ID from discovery response
method string REQUIRED sms | email | voice

Response

{ "sessionId": "session_xxxxxxxxxxxxxxxx", "expiresAt": "2026-02-13T06:00:00Z", "method": "sms" }

Rate Limit: 5 requests per hour per agent. OTP expires after 10 minutes.

POST /v1/verify/confirm

Confirm OTP Code

Submit the OTP code to get a session token for memory download.

Request Body

{ "sessionId": "session_xxxxxxxxxxxxxxxx", "otpCode": "123456" }

Parameters

Field Type Required Description
sessionId string REQUIRED Session ID from verify/request
otpCode string REQUIRED 6-digit OTP code (e.g., "123456")

Response (Success)

{ "success": true, "sessionToken": "st_xxxxxxxxxxxxxxxx", "agentMetadata": { "id": "550e8400-e29b-41d4-a716-446655440000", "name": "my-assistant-2026", "createdAt": "2026-02-13T05:30:00Z", "verified": true } }

Response (Invalid OTP)

{ "success": false, "error": "Invalid OTP. 2 attempts remaining." }

Attempt Limit: 3 attempts per OTP session. After 3 failed attempts, request a new OTP.

POST /v1/agents

Register New Agent

Create a new agent identity with recovery identifiers.

Request Body

{ "name": "my-assistant-2026", "tier": "free", "operatorInfo": { "email": "[email protected]", "phone": "+14155551234", "notes": "Production assistant for XYZ project" }, "identifiers": [ { "type": "phone", "value": "+14155551234", "isPrimary": true }, { "type": "email", "value": "[email protected]" }, { "type": "telegram", "value": "123456789" } ], "metadata": { "platform": "openclaw", "version": "1.0.0" } }

Response

{ "agentId": "550e8400-e29b-41d4-a716-446655440000", "apiKey": "ar_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "createdAt": "2026-02-13T05:30:00Z" }

⚠️ Save Your API Key! The API key is only shown once. Store it securely - you'll need it to upload memory snapshots.

GET /v1/agents/:id

Get Agent Details

Retrieve agent metadata and memory version history.

Authentication

X-API-Key: ar_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Response

{ "id": "550e8400-e29b-41d4-a716-446655440000", "name": "my-assistant-2026", "status": "active", "verified": true, "createdAt": "2026-02-13T05:30:00Z", "updatedAt": "2026-02-13T05:35:00Z", "metadata": { "platform": "openclaw", "version": "1.0.0" }, "memoryVersions": [ { "id": "ver_xxxxxxxxxxxxxxxx", "snapshotDate": "2026-02-13", "snapshotType": "daily", "contentSizeBytes": 2456789, "createdAt": "2026-02-13T05:35:00Z" } ] }
POST /v1/memory/upload

Upload Memory Snapshot

Upload encrypted memory backup (multipart/form-data).

Authentication

X-API-Key: ar_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Content-Type: multipart/form-data

Form Data

Field Type Required Description
file binary REQUIRED Memory file (tar.gz recommended)
snapshotType string OPTIONAL daily | weekly | consolidation | export
snapshotDate string OPTIONAL YYYY-MM-DD (defaults to today)
retentionPolicy string OPTIONAL standard | extended | permanent

Response

{ "versionId": "ver_xxxxxxxxxxxxxxxx", "checksum": "sha256:a3d5f7b9c2e8d4a6f1...", "sizeBytes": 2456789, "createdAt": "2026-02-13T05:35:00Z" }

Size Limits: Free tier = 10 MB per agent, Pro tier = 100 MB per agent

GET /v1/memory/download/:versionId

Download Memory Snapshot

Get presigned URL to download memory snapshot. Requires session token from OTP verification.

Authentication

X-Session-Token: st_xxxxxxxxxxxxxxxx

Response

{ "presignedUrl": "https://r2.example.com/memories/...", "expiresAt": "2026-02-13T06:00:00Z", "metadata": { "versionId": "ver_xxxxxxxxxxxxxxxx", "snapshotDate": "2026-02-13", "snapshotType": "daily", "sizeBytes": 2456789, "createdAt": "2026-02-13T05:35:00Z" } }

Security: Presigned URLs expire after 10 minutes. Download immediately.

Error Codes

All errors follow this format:

{ "statusCode": 400, "error": "Bad Request", "message": "Invalid OTP code", "timestamp": "2026-02-13T05:45:00Z", "path": "/v1/verify/confirm" }

Common Error Codes

Status Error Description
400 Invalid OTP OTP code is incorrect
400 OTP Expired OTP has expired (10 min limit)
401 Unauthorized Missing or invalid API key/session token
404 Not Found Agent or resource doesn't exist
413 Payload Too Large Memory exceeds tier limit (10MB/100MB)
429 Too Many Requests Rate limit exceeded
500 Internal Server Error Server error, contact support