Rensei docs
Factory

Factory Events API

Factory events API.

The Factory Events API provides real-time, append-only access to work-item lifecycle events flowing through your SDLC pipeline. It is the foundation for real-time dashboards, audit trails, and custom integrations.

Event Types

The API supports nine event types, grouped by category:

Work-Item Lifecycle

Event TypeWhen FiredPayloadAudience
work-item.startedIssue enters first SDLC station{ issueId, sessionId, stage }OPS, DEV
work-item.completedIssue exits final station (deployed){ issueId, sessionId, result, cost }OPS, WFE
work-item.handoffIssue moves between stations{ fromStage, toStage, duration }OPS
work-item.reworkIssue returns to earlier station (failed QA, etc.){ fromStage, toStage, reason }OPS

Human Review

Event TypeWhen FiredPayloadAudience
human.review-startedHuman begins code review{ reviewerId, sessionId, stage }OPS
human.review-completedHuman approves or rejects{ approved, comment, duration }OPS, WFE
human.overrideHuman overrides automated decision{ overriddenSessionId, reason, newOutcome }OPS, WFE

Agent Diagnostics

Event TypeWhen FiredPayloadAudience
agent.tool-summaryAgent completes a session{ toolCalls, errors, duration, model }DEV, OPS
agent.crash-recoveryAgent crashes and recovers{ crashType, recoveryCount, errorMsg }OPS, DEV

API Endpoint

GET /api/factory/events

Query factory events with filtering and pagination.

Required parameters:

  • Authorization: Bearer $RENSEI_API_KEY (header)

Query parameters:

ParamTypeDefaultNotes
eventTypeenum(none)Filter by event type (optional; can specify multiple)
issueIdstring(none)Filter by issue ID (optional)
fromISO 860130 days agoStart date (inclusive)
toISO 8601nowEnd date (inclusive)
limitint100Max results (capped at 500)
projectIdsCSV(all)Filter by project(s) (optional, space-separated)

Response:

{
  "events": [
    {
      "id": "evt_abc123",
      "eventType": "work-item.started",
      "issueId": "LINEAR-456",
      "sessionId": "ses_def789",
      "actorId": "user-123",
      "actorType": "human",
      "occurredAt": "2026-06-02T14:32:15Z",
      "payload": {
        "stage": "research",
        "issueUrl": "https://linear.app/org/issue/LINEAR-456",
        "linkedSession": "ses_def789"
      }
    },
    ...
  ]
}

POST /api/factory/events

Emit a custom factory event (for custom integrations).

Required permission: workflow:create (via Cedar policy).

Request body:

{
  "eventType": "work-item.completed",
  "issueId": "LINEAR-123",
  "sessionId": "ses_abc123",
  "actorId": "agent-claude-sonnet",
  "actorType": "agent",
  "payload": {
    "result": "passed",
    "cost": 1.23,
    "duration": 3600000
  }
}

Response:

{
  "event": {
    "id": "evt_xyz789",
    "eventType": "work-item.completed",
    "issueId": "LINEAR-123",
    "occurredAt": "2026-06-02T15:00:00Z",
    ...
  }
}

Event Payloads

work-item.started

{
  "issueId": "LINEAR-123",
  "sessionId": "ses_abc",
  "stage": "research",
  "issueUrl": "https://linear.app/org/issue/LINEAR-123",
  "linkedSession": "ses_abc"
}

work-item.completed

{
  "issueId": "LINEAR-123",
  "sessionId": "ses_abc",
  "result": "passed",
  "cost": 1.23,
  "duration": 3600000,
  "durationMs": 3600000
}

work-item.handoff

{
  "fromStage": "development",
  "toStage": "qa",
  "duration": 7200000,
  "reason": "review_complete"
}

work-item.rework

{
  "fromStage": "qa",
  "toStage": "development",
  "reason": "test_failure",
  "defectCount": 2
}

human.review-started

{
  "reviewerId": "user-123",
  "sessionId": "ses_abc",
  "stage": "acceptance",
  "reviewerName": "Alice",
  "changesSummary": "Fix login flow"
}

human.review-completed

{
  "approved": true,
  "comment": "Looks good!",
  "duration": 900000,
  "durationMs": 900000
}

human.override

{
  "overriddenSessionId": "ses_abc",
  "reason": "agent_hallucinated",
  "newOutcome": "rejected",
  "overrideComment": "Agent generated fake code"
}

agent.tool-summary

{
  "toolCalls": 12,
  "successfulCalls": 11,
  "failedCalls": 1,
  "errors": ["timeout on tool_code_review"],
  "duration": 1800000,
  "model": "claude-sonnet-1",
  "tokens": {
    "input": 25000,
    "output": 8000
  }
}

agent.crash-recovery

{
  "crashType": "timeout",
  "recoveryCount": 2,
  "errorMsg": "Execution exceeded 5m timeout",
  "recoveryMs": 60000
}

Example: Real-Time Dashboard

Stream work-item progress in real-time:

#!/bin/bash

ORG_ID="org-123"
API_KEY="rsk_live_..."

while true; do
  curl -s -H "Authorization: Bearer $API_KEY" \
    "https://app.rensei.ai/api/factory/events?limit=50" \
    | jq '.events[] | select(.eventType | startswith("work-item")) | {type:.eventType, issue:.issueId, at:.occurredAt}'
  
  sleep 5
done

Output:

{
  "type": "work-item.started",
  "issue": "LINEAR-123",
  "at": "2026-06-02T15:00:00Z"
}
{
  "type": "work-item.completed",
  "issue": "LINEAR-122",
  "at": "2026-06-02T15:05:30Z"
}

Example: Audit Trail Export

Export all events for compliance:

curl -H "Authorization: Bearer $RENSEI_API_KEY" \
  "https://app.rensei.ai/api/factory/events?limit=500&from=2026-01-01&to=2026-06-02" \
  | jq '.events[] | @json' > events-archive.jsonl

Example: Custom Metric Emission

Emit custom events from your own integration:

curl -X POST \
  -H "Authorization: Bearer $RENSEI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "eventType": "work-item.completed",
    "issueId": "PROJ-789",
    "sessionId": "ses_custom",
    "actorId": "integration-slack",
    "actorType": "system",
    "payload": {
      "result": "passed",
      "source": "slack_approval"
    }
  }' \
  "https://app.rensei.ai/api/factory/events"

Data Retention

Factory events are retained for:

  • 7 days - real-time queries (default time window)
  • 30 days - typical dashboard window
  • 90 days - quarterly analysis
  • 1 year - compliance/audit trail (archived)

Older events are archived to cold storage for compliance purposes and are available via a separate archive API.

Performance Considerations

Rate Limiting

  • 1,000 events/minute per org
  • Burst limit: 10,000 events/minute (then throttled)

Query Optimization

For large time ranges or high-volume orgs:

  • Use from and to to narrow the window
  • Use eventType to filter to specific events
  • Use issueId to track single issues (rare)
  • Paginate with limit=500 for large result sets

Permissions

The Events API enforces Cedar policies:

  • GET requires factory:read (included in standard org access)
  • POST requires workflow:create (writer-only)

For API keys, use scopes: ["factory:read"] or ["factory:write"].

Next Steps

  • For aggregated metrics instead of raw events, see Metrics API
  • For audit trail and compliance, see Audit Trail
  • For custom workflows using events, see Workflows

On this page