Reaktor Logs and Run Tracking
This guide explains how to access execution logs for Reaktors via API and how to correlate logs with specific executions using the runId.
Overview
When a Reaktor executes, Operaide automatically:
- Assigns a unique runId to each execution
- Logs all framework events (retries, AI calls, errors) to MongoDB
- Returns the runId in response headers for correlation
This enables:
- Debugging: Trace what happened during a specific execution
- Monitoring: Track error rates, retry patterns, AI token usage
- Auditing: Review execution history for compliance
Getting the Run ID
Every Reaktor execution returns the runId in the response header X-Run-Id:
# Execute a reaktor
curl -i -X POST \
-H "X-Operaide-Token: $TOKEN" \
-H "Content-Type: application/json" \
-d '{"world": "Claude"}' \
https://your-instance.operaide.com/api/v1/aktor/hello-world
# Response headers include:
# HTTP/1.1 200 OK
# X-Run-Id: abc123-def456-789xyz
# Content-Type: application/json
Important: The X-Run-Id header is returned even on errors, allowing you to debug failed executions.
Capturing the Run ID Programmatically
JavaScript/TypeScript:
const response = await fetch('/api/v1/aktor/my-reaktor', {
method: 'POST',
headers: {
'X-Operaide-Token': token,
'Content-Type': 'application/json'
},
body: JSON.stringify(input)
});
const runId = response.headers.get('X-Run-Id');
console.log(`Execution runId: ${runId}`);
// Store runId for later log retrieval
if (!response.ok) {
console.error(`Failed execution - check logs with runId: ${runId}`);
}
Python:
import requests
response = requests.post(
'https://your-instance.operaide.com/api/v1/aktor/my-reaktor',
headers={'X-Operaide-Token': token, 'Content-Type': 'application/json'},
json={'input': 'value'}
)
run_id = response.headers.get('X-Run-Id')
print(f"Execution runId: {run_id}")
curl (extract header):
# Store response and headers separately
RUN_ID=$(curl -s -D - -o response.json \
-X POST \
-H "X-Operaide-Token: $TOKEN" \
-H "Content-Type: application/json" \
-d '{"input": "value"}' \
https://instance/api/v1/aktor/my-reaktor | grep -i "x-run-id" | cut -d' ' -f2 | tr -d '\r')
echo "Run ID: $RUN_ID"
Fetching Logs via API
Endpoint
GET /api/v1/deployments/{deploymentId}/logs
Authentication: Required (X-Operaide-Token or X-API-KEY header)
Permission: roleExpert or higher
Query Parameters
| Parameter | Type | Description | Example |
|---|---|---|---|
runId | string | Filter by specific execution | abc123-def456 |
levels | string | Comma-separated log levels | warn,error |
aktorId | string | Filter by aktor name | aktorFetchData |
fromDate | ISO 8601 | Start of time range | 2025-12-01T00:00:00Z |
toDate | ISO 8601 | End of time range | 2025-12-09T23:59:59Z |
limit | number | Max logs to return (default: 500, max: 1000) | 100 |
Examples
Get logs for a specific execution:
curl -H "X-Operaide-Token: $TOKEN" \
"https://instance/api/v1/deployments/my-deployment/logs?runId=abc123-def456"
Get only errors and warnings:
curl -H "X-Operaide-Token: $TOKEN" \
"https://instance/api/v1/deployments/my-deployment/logs?levels=warn,error"
Get logs for a specific aktor:
curl -H "X-Operaide-Token: $TOKEN" \
"https://instance/api/v1/deployments/my-deployment/logs?aktorId=aktorProcessDocument"
Get logs from last 24 hours:
FROM_DATE=$(date -u -v-1d +"%Y-%m-%dT%H:%M:%SZ")
curl -H "X-Operaide-Token: $TOKEN" \
"https://instance/api/v1/deployments/my-deployment/logs?fromDate=$FROM_DATE"
Combine filters:
curl -H "X-Operaide-Token: $TOKEN" \
"https://instance/api/v1/deployments/my-deployment/logs?runId=abc123&levels=error&limit=50"
Response Format
{
"metadata": {
"exportedAt": "2025-12-09T10:30:00.000Z",
"reaktorId": "my-deployment",
"filters": {
"levels": ["warn", "error"],
"aktorId": null,
"runId": "abc123-def456",
"timeRange": {
"from": null,
"to": null
}
},
"totalCount": 3,
"limit": 500
},
"logs": [
{
"timestamp": "2025-12-09T10:25:15.123Z",
"level": "warn",
"message": "Retrying aktor after error",
"reaktorId": "my-deployment",
"aktorId": "aktorFetchData",
"runId": "abc123-def456",
"context": {
"retryNumber": 1,
"maxRetries": 3,
"waitMs": 1000,
"errorMessage": "Connection timeout"
},
"error": null
},
{
"timestamp": "2025-12-09T10:25:14.500Z",
"level": "error",
"message": "Aktor failed after max retries",
"reaktorId": "my-deployment",
"aktorId": "aktorFetchData",
"runId": "abc123-def456",
"context": {
"retries": 3,
"maxRetries": 3
},
"error": {
"name": "Error",
"message": "Connection timeout after 3 retries",
"stack": "Error: Connection timeout...\n at aktorFetchData..."
}
}
]
}
Log Levels
| Level | Description | Typical Use |
|---|---|---|
debug | Detailed tracing | Development, deep debugging |
info | Normal operations | Execution flow, AI call starts |
warn | Recoverable issues | Retries, fallbacks, rate limits |
error | Failures | Exceptions, max retries exceeded |
What Gets Logged
The framework automatically logs the following events:
Aktor Retry & Failure Events
| Event | Level | Message | Context Fields |
|---|---|---|---|
| Retry attempt | warn | "Retrying aktor after error" | aktorId, retryNumber, maxRetries, waitMs |
| Max retries exceeded | error | "Aktor failed after max retries" | aktorId, retries, maxRetries + error details |
| No retry configured | error | "Aktor failed, no retry configured" | aktorId + error details |
AI Streaming Events (streaming mode only)
| Event | Level | Message | Context Fields |
|---|---|---|---|
| Stream start | info | "AI streaming call started" | aktorId, provider, model, messageCount |
| Stream complete | info | "AI streaming call completed" | aktorId, provider, model, chunks, responseLength |
Note: Non-streaming AI calls (aktorAICall with .get()) do not generate log entries.
Error Details
Errors logged include:
name: Error class namemessage: Error messagestack: Full stack trace (for debugging)
Common Patterns
Debug a Failed Execution
# 1. Execute and capture runId
RESPONSE=$(curl -i -s -X POST \
-H "X-Operaide-Token: $TOKEN" \
-H "Content-Type: application/json" \
-d '{"input": "value"}' \
https://instance/api/v1/aktor/my-reaktor)
RUN_ID=$(echo "$RESPONSE" | grep -i "x-run-id" | cut -d' ' -f2 | tr -d '\r')
# 2. Fetch logs for that execution
curl -H "X-Operaide-Token: $TOKEN" \
"https://instance/api/v1/deployments/my-deployment/logs?runId=$RUN_ID" | jq .
Monitor Error Rates
# Get error count for last hour
FROM=$(date -u -v-1H +"%Y-%m-%dT%H:%M:%SZ")
curl -H "X-Operaide-Token: $TOKEN" \
"https://instance/api/v1/deployments/my-deployment/logs?levels=error&fromDate=$FROM" \
| jq '.metadata.totalCount'
Export Logs for Analysis
# Export last 1000 logs as JSON
curl -H "X-Operaide-Token: $TOKEN" \
"https://instance/api/v1/deployments/my-deployment/logs?limit=1000" \
> logs-export.json
# Convert to CSV for spreadsheet analysis
cat logs-export.json | jq -r '.logs[] | [.timestamp, .level, .aktorId, .message] | @csv' > logs.csv
Log Retention
Logs are stored with a TTL (Time-To-Live) of 30 days by default. After 30 days, logs are automatically deleted from MongoDB.
For longer retention:
- Export logs periodically via API
- Configure platform-level log forwarding (contact admin)
Permissions
| Action | Required Role |
|---|---|
| View logs | roleExpert |
| Access deployment logs | Must belong to same organization as deployment |
Attempting to access logs for a deployment in a different organization returns 403 Forbidden.
Troubleshooting
"Deployment not found" (404)
- Verify you're using
deploymentId, notreaktorDefinitionId - Check if the deployment exists:
GET /api/v1/deployments/{id}/settings
"Access denied" (403)
- Ensure you have
roleExpertor higher - Verify the deployment belongs to your current organization
No logs returned
- Check time range filters (logs may be outside range)
- Verify the
runIdis correct - Logs only exist if the Reaktor executed (check if deployment is configured)
Missing runId in response
- The Reaktor may have failed before execution started
- Check the error response body for details