Skip to main content

Event Commands

Commands for applying events and batch operations.

APPLY_EVENT

Applies an event to an instance, triggering a state transition.

Request

{
"op": "APPLY_EVENT",
"params": {
"instance_id": "order-001",
"event": "PAY",
"payload": {
"payment_id": "pay-123",
"amount": 99.99,
"method": "card"
},
"expected_state": "pending",
"expected_wal_offset": 1,
"event_id": "evt-unique-id",
"idempotency_key": "pay-order-001"
}
}
ParameterTypeRequiredDescription
instance_idstringYesTarget instance
eventstringYesEvent name
payloadobjectNoData to merge into context (default: {})
expected_statestringNoOptimistic concurrency: require this state
expected_wal_offsetintegerNoOptimistic concurrency: require this WAL offset
event_idstringNoUser-supplied event identifier
idempotency_keystringNoDeduplication key

Response

{
"status": "ok",
"result": {
"from_state": "pending",
"to_state": "paid",
"ctx": {
"customer": "alice",
"total": 99.99,
"payment_id": "pay-123",
"amount": 99.99,
"method": "card"
},
"wal_offset": 5,
"applied": true,
"event_id": "evt-unique-id"
}
}
FieldDescription
from_stateState before transition
to_stateState after transition
ctxUpdated context after payload merge
wal_offsetWAL offset of this event
appliedtrue if newly applied, false if idempotency key replay
event_idEcho of user-supplied event ID (if provided)

Errors

CodeDescription
INSTANCE_NOT_FOUNDInstance doesn't exist
INVALID_TRANSITIONNo valid transition for this event from current state
GUARD_FAILEDGuard condition not satisfied
CONFLICTexpected_state or expected_wal_offset doesn't match

Payload Merging

The payload is shallow-merged into the instance context:

// Before: ctx = {a: 1, b: 2}
// Payload: {b: 3, c: 4}
// After: ctx = {a: 1, b: 3, c: 4}

Optimistic Concurrency

Use expected_state or expected_wal_offset to detect concurrent modifications:

{
"op": "APPLY_EVENT",
"params": {
"instance_id": "order-001",
"event": "SHIP",
"expected_state": "paid"
}
}

If the instance is not in the expected state, returns CONFLICT.


BATCH

Executes multiple operations in a single request.

Request

{
"op": "BATCH",
"params": {
"mode": "best_effort",
"ops": [
{
"op": "APPLY_EVENT",
"params": {
"instance_id": "order-001",
"event": "PAY",
"payload": {}
}
},
{
"op": "APPLY_EVENT",
"params": {
"instance_id": "order-002",
"event": "PAY",
"payload": {}
}
},
{
"op": "CREATE_INSTANCE",
"params": {
"machine": "notification",
"version": 1,
"instance_id": "notif-001",
"initial_ctx": {"type": "payment"}
}
}
]
}
}
ParameterTypeRequiredDescription
modestringYes"atomic" or "best_effort"
opsOperation[]YesList of operations (max 100)

Batch Modes

Atomic Mode

All operations succeed or the batch fails:

{"mode": "atomic", ...}
  • Operations are applied in order
  • If any operation fails, the batch stops and returns an error
  • Note: This is NOT transactional — already-applied writes within the batch are not rolled back

Best Effort Mode

Apply as many as possible:

{"mode": "best_effort", ...}
  • Operations are applied in order
  • Failures don't stop subsequent operations
  • Response includes per-operation results

Supported Operations

Operations that can be batched:

  • CREATE_INSTANCE
  • APPLY_EVENT
  • DELETE_INSTANCE

Read operations (GET_INSTANCE, LIST_INSTANCES) cannot be batched.

Response (Best Effort)

{
"status": "ok",
"result": {
"results": [
{"status": "ok", "result": {"from_state": "pending", "to_state": "paid", "ctx": {}, "wal_offset": 10, "applied": true}, "error": null},
{"status": "error", "result": null, "error": {"code": "INSTANCE_NOT_FOUND", "message": "...", "retryable": false}},
{"status": "ok", "result": {"instance_id": "notif-001", "state": "pending", "wal_offset": 11}, "error": null}
]
}
}

Response (Atomic — All Succeed)

{
"status": "ok",
"result": {
"results": [
{"status": "ok", "result": {...}, "error": null},
{"status": "ok", "result": {...}, "error": null}
]
}
}

Examples

Multiple State Transitions

{
"op": "BATCH",
"params": {
"mode": "atomic",
"ops": [
{"op": "APPLY_EVENT", "params": {"instance_id": "order-001", "event": "PAY"}},
{"op": "APPLY_EVENT", "params": {"instance_id": "order-001", "event": "SHIP"}},
{"op": "APPLY_EVENT", "params": {"instance_id": "order-001", "event": "DELIVER"}}
]
}
}

Process Multiple Orders

{
"op": "BATCH",
"params": {
"mode": "best_effort",
"ops": [
{"op": "APPLY_EVENT", "params": {"instance_id": "order-001", "event": "SHIP"}},
{"op": "APPLY_EVENT", "params": {"instance_id": "order-002", "event": "SHIP"}},
{"op": "APPLY_EVENT", "params": {"instance_id": "order-003", "event": "SHIP"}}
]
}
}

Create with Initial Event

{
"op": "BATCH",
"params": {
"mode": "atomic",
"ops": [
{
"op": "CREATE_INSTANCE",
"params": {
"machine": "order",
"version": 1,
"instance_id": "order-new",
"initial_ctx": {"customer": "alice"}
}
},
{
"op": "APPLY_EVENT",
"params": {
"instance_id": "order-new",
"event": "PAY",
"payload": {"amount": 99.99}
}
}
]
}
}