VirtuousAI
Primitives

Events

Query the immutable audit trail of all system activities

Events

Events are the immutable audit trail of everything that happens in VirtuousAI. Every action, connection change, and automation run generates events that you can query, filter, and subscribe to.

Concept

Each event contains:

  • Type — What happened (e.g., action.completed)
  • Entity — What was affected (e.g., action_xyz)
  • Actor — Who/what caused it (e.g., user_abc, system)
  • Data — Event-specific payload (e.g., { records: 1250 })
  • Timestamp — When it happened (UTC)

Events are:

  • Immutable — Cannot be modified after creation
  • Append-only — New events always added, never removed
  • Correlated — Related events share a correlation ID

Event Structure

{
  "id": "evt_abc123",
  "type": "action.completed",
  "timestamp": "2026-01-22T14:32:15Z",
  "entity": {
    "type": "action_run",
    "id": "run_xyz789"
  },
  "actor": {
    "type": "automation",
    "id": "auto_abc123"
  },
  "data": {
    "duration": 135000,
    "recordsProcessed": 1250,
    "status": "COMPLETED"
  },
  "metadata": {
    "correlationId": "corr_abc123",
    "organizationId": "org_xyz"
  }
}

Event Types

TypeDescriptionTypical Actor
connection.createdNew connection createduser
connection.updatedSettings modifieduser
connection.deletedConnection removeduser
connection.testedConnectivity test runuser, system
connection.errorError occurredsystem
connection.token_refreshedOAuth token refreshedsystem
TypeDescriptionTypical Actor
action.createdNew action createduser
action.startedExecution starteduser, automation
action.progressExecution progress updatesystem
action.completedFinished successfullysystem
action.failedFinished with errorsystem
action.cancelledManually cancelleduser
TypeDescriptionTypical Actor
automation.createdNew automation createduser
automation.triggeredTrigger firedsystem, api
automation.completedRun finished successfullysystem
automation.failedRun finished with errorsystem
automation.enabledAutomation enableduser
automation.disabledAutomation disableduser
TypeDescriptionTypical Actor
auth.loginUser logged inuser
auth.logoutUser logged outuser
auth.token_createdAPI token createduser
auth.token_revokedAPI token revokeduser
auth.permission_grantedPermission addeduser
auth.permission_revokedPermission removeduser

Actor Types

Actor TypeDescriptionIncludes
userHuman via UI or CLIemail, IP, user agent
systemInternal processesprocess name, version
automationTriggered by automationautomation ID
apiExternal API callAPI key ID, IP

Querying Events

Filtering

GET /api/v1/events?type=action.completed&since=2026-01-20T00:00:00Z
ParameterDescription
typeFilter by event type (e.g., action.completed)
entityTypeFilter by entity type (e.g., action)
entityIdFilter by specific entity ID
sinceEvents after this timestamp
untilEvents before this timestamp
actorTypeFilter by actor type (user, system, etc.)
actorIdFilter by specific actor
correlationIdGet all events in a correlation chain

Pagination

Events use cursor-based pagination:

{
  "items": [...],
  "nextCursor": "eyJ0cyI6IjIwMjYtMDEtMjBUMTQ6MzI6MTVaIn0=",
  "hasMore": true
}

Cursor Expiration

Cursors are valid for 24 hours. For long-running exports, use the since/until parameters instead.

Webhooks

Subscribe to events in real-time via webhooks:

Creating a Webhook Subscription

POST /api/v1/webhooks
{
  "url": "https://your-server.com/webhook",
  "events": ["action.completed", "action.failed"],
  "secret": "whsec_your_secret"
}

Verifying Signatures

All webhook payloads include a signature header:

X-VAI-Signature: sha256=abc123def456...
X-VAI-Timestamp: 1705764735

Verify by computing HMAC-SHA256 of {timestamp}.{payload} with your secret:

const crypto = require('crypto');

function verifyWebhook(payload, signature, timestamp, secret) {
  const signedPayload = `${timestamp}.${payload}`;
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(signedPayload)
    .digest('hex');
  
  return `sha256=${expectedSignature}` === signature;
}

Use Cases

Audit & Compliance

Query all actions by a specific user:

GET /api/v1/events?actorType=user&actorId=user_abc123&since=2026-01-01

Debugging Failures

Find all events for a failed action:

GET /api/v1/events?entityId=run_xyz789&type=action.*

Correlation Tracing

Get all events in a workflow:

GET /api/v1/events?correlationId=corr_abc123

Building Dashboards

Stream events to build real-time monitoring:

{
  "url": "https://dashboard.internal/events",
  "events": [
    "action.completed",
    "action.failed", 
    "automation.triggered",
    "connection.error"
  ]
}

Best Practices

  1. Use correlation IDs — When debugging, find one event and query others with the same correlation ID
  2. Subscribe selectively — Only subscribe to events you need to reduce webhook load
  3. Verify signatures — Always verify webhook signatures in production
  4. Handle retries idempotently — Webhooks may be delivered more than once
  5. Set up alerting — Create webhooks for error events to trigger alerts
  6. Archive for compliance — Export events periodically for long-term retention

OpenAPI Reference

For detailed endpoint schemas, request/response formats, and authentication:

On this page