Event State Machine
Every event in PromptJang follows a strict state machine. This ensures predictable behavior and a clear audit trail.
States
| State | Description |
|---|---|
RECEIVED | Event received by the API worker (transient) |
QUEUED | Event enqueued for delivery |
PROCESSING | Delivery worker is attempting to forward the event |
DELIVERED | Target endpoint returned 2xx — terminal state |
FAILED | Target returned non-2xx or was unreachable |
RETRYING | Event is scheduled for retry |
EXPIRED | Max retries exceeded — terminal state |
REPLAYED | Event was manually replayed — terminal state |
State Transitions
RECEIVED → QUEUED → PROCESSING → DELIVERED ✓
├─────▶ FAILED → RETRYING → QUEUED (loop)
│ └──▶ EXPIRED ✗
└─────▶ (any non-2xx)Retry Behavior
When delivery fails (non-2xx response or network error):
- Status moves to
FAILED - A delivery attempt is recorded with status code, response body, and latency
- If retries remain:
RETRYING→QUEUED(back to the queue) - If max retries exceeded:
EXPIRED(terminal)
Exponential Backoff
Retries use exponential backoff:
| Attempt | Delay |
|---|---|
| 1st retry | 30 seconds |
| 2nd retry | 60 seconds |
| 3rd retry | 120 seconds |
| 4th retry | 240 seconds |
| 5th retry | 480 seconds (8 minutes) |
Formula: delay = 30 * 2^(attempt - 1) seconds, capped at 480s.
Default max retries: 5.
Event Replay
Any event (regardless of state) can be replayed via POST /api/v1/events/:id/replay. This:
- Creates a new event with status
QUEUED - Copies the original payload from R2
- The original event is marked
REPLAYED
Replay does not modify the original event's delivery attempts — they remain in the audit trail.