Developer Portal
Build on Orva Eon — the privacy-first AI Agent Phone platform.
Overview
Orva Eon exposes a FastAPI REST backend. All endpoints return JSON. The three-lane compute model is the core abstraction: every request is routed through Lane A (on-device), Lane B (private cloud), or Lane C (external model).
A — On-Device (Ollama)
B — Private Cloud (Claude)
C — External (GPT-4o)
Base URL
http://localhost:8000
Authentication
Set DEMO_TOKEN in .env to gate all endpoints. Pass the token as a request header:
X-Demo-Token: your-token-here
Leave DEMO_TOKEN empty to run in open mode (development).
Compute Lanes
GET
/api/lanes
Lane status + capabilities
{
"lane_a": { "status": "available", "privacy_level": "MAXIMUM", "requires_internet": false },
"lane_b": { "status": "available", "privacy_level": "HIGH", "requires_internet": true },
"lane_c": { "status": "not_configured", "consent_required": true }
}
Tasks
Rate limited: 30 requests/minute per IP.
POST
/api/task
Submit a task to an agent
Request
{
"task": "Book a table for two Friday evening, Italian restaurant",
"lane": "B", // "A" | "B" | "C"
"user_id": "demo-user",
"thread_id": null // optional conversation thread
}
Response
{
"result": "I found three Italian restaurants...",
"lane_used": "B",
"agent_trace": ["[Router] Semantic classification → Travel...", "..."],
"memories_updated": [{ "type": "travel", "content": "Book a table..." }],
"permission_prompts": [],
"used_crew": true,
"privacy_budget": { "score": 80, "label": "GOOD", "total_tasks": 5 }
}
POST
/api/compare
Run same task on all 3 lanes in parallel
// Request
{ "task": "What is the weather today?", "user_id": "demo-user" }
// Response
{
"task": "What is the weather today?",
"results": [
{ "lane": "A", "result": "...", "elapsed_ms": 1200, "error": null },
{ "lane": "B", "result": "...", "elapsed_ms": 800 },
{ "lane": "C", "result": "...", "elapsed_ms": 650 }
]
}
Memory
GET/api/memory/{uid}List all memories
GET/api/memory/{uid}/search?q=query&n=5Semantic search
DELETE/api/memory/{uid}/{mid}Delete a single memory
All memories are Fernet-encrypted at rest. Semantic search uses a plaintext index for real embeddings; the payload store is opaque without the server secret.
Privacy
GET/api/privacy-budget/{uid}Current privacy score (0–100)
{ "score": 85, "label": "EXCELLENT", "total_tasks": 20, "on_device_tasks": 14, "cloud_tasks": 5, "external_tasks": 1 }
GET/api/privacy-report/{uid}Full privacy report with data destinations
GET/api/audit/{uid}?limit=50Append-only audit log
Voice
POST/api/transcribeLocal Whisper STT (Lane A — never leaves device)
// Multipart form: audio file (webm, wav, mp3) + user_id field
// Returns: { "text": "transcribed text here" }
POST/api/speakOpenAI TTS — returns audio/mpeg
{ "text": "Your agent response here.", "voice": "alloy" }Push Notifications
GET/api/push/public-keyVAPID public key for subscription setup
POST/api/push/subscribeRegister browser push subscription
{ "user_id": "demo-user", "endpoint": "https://...", "p256dh": "...", "auth": "..." }API Key Management
Users can store their own API keys (Anthropic, OpenAI, etc.) encrypted server-side. Never stored in plaintext.
POST/api/keysStore encrypted API key
{ "user_id": "demo-user", "key_name": "anthropic", "key_value": "sk-ant-..." }GET/api/keys/{uid}List key names (values never returned)
DELETE/api/keys/{uid}/{key_name}Delete a key
Enterprise Mode
Requires
ENTERPRISE_MODE=true in .envPOST/api/enterprise/team/memberAdd team member
{ "team_id": "acme-corp", "user_id": "alice", "role": "admin" }GET/api/enterprise/team/{team_id}/privacy-reportAggregate team privacy dashboard
GET/api/enterprise/team/{team_id}/exportFull compliance export (all members)
GDPR
GET/api/export/{uid}Full data export
DELETE/api/delete-account/{uid}Right to erasure — wipes all data
Agent SDK
Register custom agents into the Orva marketplace. Each agent must declare its privacy lane and data policy upfront.
POST/api/agents/registerRegister a custom agent
{
"id": "my-recipe-agent",
"name": "Recipe & Nutrition Agent",
"description": "Finds recipes and computes nutrition info.",
"icon": "🍳",
"category": "health",
"privacy_lane": "A", // A = never leaves device
"version": "1.0.0",
"capabilities": ["recipe_search", "nutrition_calc"],
"data_policy": "No personal data stored. All processing on-device.",
"system_prompt": "You are a recipe expert..."
}
See agents/template_agent.py for the full reference implementation with CrewAI integration.
JSON Schema — TaskRequest
| Field | Type | Required | Description |
|---|---|---|---|
| task | string | YES | The user's natural language request |
| lane | "A"|"B"|"C" | no (default B) | Compute lane |
| user_id | string | no (default demo-user) | User identifier for memory + audit scoping |
| thread_id | string|null | no | Conversation thread for context continuity |