Execute
All execution endpoints accept X-API-Key: eak_... (or wak_...) and
X-Workspace-Id: workspace:YOUR_ID.
Base URL: https://athena-dev-api.leanscale.com
Request Body
{ "message": "Summarise my last 7 days of activity", "attachments": [ { "filename": "notes.pdf", "content_type": "application/pdf", "storage_key": "attachments/user_abc/a1b2c3.pdf" } ], "variables": { "tone": "professional" }, "conversation_scope": "conversation:abc123", "external_user_id": "firebase_uid_xyz", "client_tools": [ { "name": "query_transactions", "description": "Query the user's local transaction ledger", "parameters": { "type": "object", "properties": { "start_date": { "type": "string", "format": "date" }, "end_date": { "type": "string", "format": "date" } }, "required": ["start_date", "end_date"] } } ]}| Field | Required | Description |
|---|---|---|
message | Conditional | User input (1–65,536 chars). Required when the agent has requires_user_message: true. |
attachments | No | File references via storage_key (max 10). |
variables | No | Input variables for wizard agents. Capped at 16 KiB. |
conversation_scope | No | Conversation ID — enables message history injection and auto-persistence. |
external_user_id | No | Your user’s ID — enables per-user memory personalization. |
client_tools | No | Client-fulfilled tool definitions. Max 32 per request. |
Sync Execution
POST /agents/{agent_id}/executeX-API-Key: eak_...X-Workspace-Id: workspace:YOUR_IDBlocks until the workflow completes. Response is a single JSON object.
{ "data": { "execution_id": "execution:xyz", "status": "completed", "output": { "text": "Here is your summary...", "usage": { "input_tokens": 150, "output_tokens": 280, "total_tokens": 430 }, "cost_microdollars": 4200 }, "latency_ms": 2341 }}Status values: completed, awaiting_approval, waiting_for_external_event,
awaiting_client_tool, failed.
Streaming Execution (SSE)
POST /agents/{agent_id}/execute/streamX-API-Key: eak_...X-Workspace-Id: workspace:YOUR_IDContent-Type: application/jsonReturns text/event-stream. Each event is data: <json>\n\n.
| Event | When | Action |
|---|---|---|
start | First event | Capture execution_id for tracking |
text | Each LLM token chunk | Append to displayed text |
reasoning | Thinking chunks | Show thinking indicator |
tool_call | LLM invokes a server tool | Show tool execution UI |
tool_result | Server tool returns result | Show tool output |
tool_call_awaiting_client | LLM invokes a client tool | Run tool locally and POST result |
node_start / node_complete | Workflow node lifecycle | Progress indicators |
media_gen_submitted | Image/video gen started | Show generating indicator |
media_gen_complete | Image/video gen done | Render the generated media |
heartbeat | Every 15 s during gen wait | Keep-alive — ignore in UI |
final | Workflow complete | Extract final usage and cost. Stream ends. |
error | Execution failed | Show error. Credits are auto-refunded. |
Batch Execution
POST /agents/{agent_id}/execute/batchX-API-Key: eak_...X-Workspace-Id: workspace:YOUR_IDContent-Type: application/json
{ "items": [ { "key": "item-1", "message": "Summarize this article: ..." }, { "key": "item-2", "message": "Translate to French: ..." } ]}Returns SSE: batch_started → batch_progress (per item) → batch_completed.
Idempotency
Prevent duplicate executions (and double credit charges) with an
Idempotency-Key header:
POST /agents/{agent_id}/executeIdempotency-Key: 550e8400-e29b-41d4-a716-446655440000| Scenario | Result |
|---|---|
| First request with key | Processed normally |
| Same key within 24 hours | 409 Conflict — no execution, no charge |
| Same key after 24 hours | Processed normally — key expired |
Credit Preview
Estimate the credit cost before executing:
POST /agents/{agent_id}/preview-creditsX-API-Key: eak_...
{ "inputs": { "tone": "professional", "length": "long" } }Returns the credit calculation with base cost and rule breakdown. No execution is created.
Client-Fulfilled Tools
Client tools let the LLM invoke functions that run on the client device.
The AI node must have accepts_client_tools: true.
Flow:
- Your app sends
client_toolsin the execute request. - If the LLM calls a client tool, execution suspends — status becomes
awaiting_client_tool. - SSE emits
tool_call_awaiting_client. - Your app runs the tool locally and POSTs the result:
POST /executions/{execution_id}/tool-resultX-API-Key: eak_...
{ "tool_call_id": "tc_abc123", "outcome": "success", "result": { "transactions": [], "total": 5.50 }}- The last fulfilled call resumes execution automatically.
Add Accept: text/event-stream to the tool-result POST to receive
the resumed execution as an SSE stream.
Tool name rules: must match ^[a-z][a-z0-9_]{0,63}$ and must not
collide with server-side tools on the agent.
File Attachments
Step 1: Upload the file
POST /attachments/uploadX-API-Key: eak_...Content-Type: multipart/form-data
file: <binary data>Response includes a storage_key string.
Step 2: Reference in execute request
Pass storage_key in the attachments array.
| Constraint | Value |
|---|---|
| Max attachments per request | 10 |
| Max file size | 50 MiB |
| Supported image types | image/jpeg, image/png, image/gif, image/webp |
| Supported document types | application/pdf, text/plain, text/csv, text/markdown |
Conversations
Use conversations to maintain message history across turns.
Create or resume a conversation:
POST /my/conversationsX-API-Key: eak_...
{ "agent_id": "agent:0bve9rxqh0hm7t5bq24j" }Returns 201 (new) or 200 (existing active conversation).
Execute with conversation history: pass conversation_scope in your
execution request body. This injects prior messages as context and
auto-persists the new exchange.
Start a fresh chat: archive the current conversation before the next
POST /my/conversations:
POST /my/conversations/{conversation_id}/archiveMessage roles:
role | Author | Replayed to LLM? |
|---|---|---|
user | End user | Yes |
assistant | Agent (LLM output) | Yes |
tool | Tool result | Yes |
system | Athena platform (failures, handoffs) | No |
Message feedback:
POST /my/conversations/{cid}/messages/{mid}/feedback{ "value": 1 }1 = thumbs up, -1 = thumbs down.
Structured Output
When an agent’s AI node has output_schema configured, responses include
parsed_output alongside text:
{ "data": { "output": { "text": "{\"type\":\"card\",\"amount\":\"$2,450\"}", "parsed_output": { "type": "card", "amount": "$2,450" } } }}Use parsed_output when present. Fall back to parsing text manually
if parsed_output is null.
Response Headers
Every authenticated response includes:
| Header | Value |
|---|---|
X-Credits-Remaining | Current credit balance (eak_ + customer only) |
X-App-Version | The workspace’s current published AppVersion ID |
X-Workspace-Id | Echo of the workspace ID |
Cache X-App-Version locally. When it changes, refetch CMS data.
Related Docs
- Authentication — key types, scopes, token exchange
- Webhooks — receive events from Fal.ai and RevenueCat
- Errors — error shapes and retry guidance
- Workflows — HumanGate resume and MediaGeneration events