Skip to main content
Version: 2.6

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:

  1. Assigns a unique runId to each execution
  2. Logs all framework events (retries, AI calls, errors) to MongoDB
  3. 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

ParameterTypeDescriptionExample
runIdstringFilter by specific executionabc123-def456
levelsstringComma-separated log levelswarn,error
aktorIdstringFilter by aktor nameaktorFetchData
fromDateISO 8601Start of time range2025-12-01T00:00:00Z
toDateISO 8601End of time range2025-12-09T23:59:59Z
limitnumberMax 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

LevelDescriptionTypical Use
debugDetailed tracingDevelopment, deep debugging
infoNormal operationsExecution flow, AI call starts
warnRecoverable issuesRetries, fallbacks, rate limits
errorFailuresExceptions, max retries exceeded

What Gets Logged

The framework automatically logs the following events:

Aktor Retry & Failure Events

EventLevelMessageContext Fields
Retry attemptwarn"Retrying aktor after error"aktorId, retryNumber, maxRetries, waitMs
Max retries exceedederror"Aktor failed after max retries"aktorId, retries, maxRetries + error details
No retry configurederror"Aktor failed, no retry configured"aktorId + error details

AI Streaming Events (streaming mode only)

EventLevelMessageContext Fields
Stream startinfo"AI streaming call started"aktorId, provider, model, messageCount
Stream completeinfo"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 name
  • message: Error message
  • stack: 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

ActionRequired Role
View logsroleExpert
Access deployment logsMust 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, not reaktorDefinitionId
  • Check if the deployment exists: GET /api/v1/deployments/{id}/settings

"Access denied" (403)

  • Ensure you have roleExpert or higher
  • Verify the deployment belongs to your current organization

No logs returned

  • Check time range filters (logs may be outside range)
  • Verify the runId is 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