OJS defines a standard event vocabulary that enables monitoring, auditing, and reactive automation. Events are emitted by the backend as jobs progress through their lifecycle.
The event format is inspired by CloudEvents, providing a consistent envelope that works across delivery mechanisms (Pub/Sub, LISTEN/NOTIFY, webhooks, WebSocket, gRPC streaming).
Every OJS event follows this structure:
"id" : " evt_01961234-5678-7abc-def0-123456789abc " ,
"source" : " /ojs/backend/redis " ,
"time" : " 2026-02-15T10:30:00Z " ,
"subject" : " 01961234-5678-7abc-def0-123456789abc " ,
"job_id" : " 01961234-5678-7abc-def0-123456789abc " ,
"job_type" : " email.send " ,
Field Type Description specversionstring Event format version ("1.0") idstring Unique event identifier typestring Event type (dot-namespaced) sourcestring Backend identifier URI timestring RFC 3339 timestamp in UTC subjectstring Job ID this event relates to dataobject Event-specific payload
Event Type Trigger Data Fields job.enqueuedJob submitted to queue job_id, job_type, queue, priorityjob.startedWorker begins processing job_id, job_type, queue, attempt, worker_idjob.completedHandler returns success job_id, job_type, queue, attempt, duration_msjob.failedHandler returns error job_id, job_type, queue, attempt, error, duration_msjob.retryingJob scheduled for retry job_id, job_type, queue, attempt, next_attempt_at, delay_msjob.discardedRetries exhausted, discarded job_id, job_type, queue, attempt, errorjob.cancelledJob cancelled by client job_id, job_type, queue, cancelled_byjob.scheduledDelayed job enqueued job_id, job_type, queue, scheduled_at
Event Type Trigger Data Fields worker.registeredWorker connects to backend worker_id, hostname, queues, concurrencyworker.heartbeatPeriodic heartbeat worker_id, active_jobs, stateworker.quietWorker entering quiet mode worker_idworker.terminatedWorker shutting down worker_id, reason
Event Type Trigger Data Fields queue.pausedQueue paused queue, paused_byqueue.resumedQueue resumed queue, resumed_by
Event Type Trigger Data Fields workflow.startedWorkflow begins workflow_id, workflow_type, total_stepsworkflow.step_completedWorkflow step finishes workflow_id, step, total_stepsworkflow.completedAll steps complete workflow_id, duration_msworkflow.failedWorkflow step fails terminally workflow_id, step, error
Event Type Trigger Data Fields cron.triggeredCron schedule fires cron_name, job_id, next_atcron.skippedOverlap policy prevents execution cron_name, reason, next_at
OJS events can be consumed through multiple channels:
Mechanism Description Use Case Redis Pub/Sub Subscribe to ojs.events.* channels Real-time monitoring PostgreSQL LISTEN/NOTIFY Listen on ojs_events channel Existing Postgres infrastructure NATS subjects Subscribe to ojs.events.> NATS-native consumers Kafka topics Consume from ojs.events topic Event streaming pipelines WebSocket Connect to /ojs/v1/events/ws Browser-based dashboards Webhooks Register HTTP callback endpoints External system integration
Level 0 : Implementations MAY emit events.
Level 1 : Implementations SHOULD emit job lifecycle events (job.enqueued, job.started, job.completed, job.failed).
Level 2+ : Implementations SHOULD emit scheduling and workflow events.