Event Payloads
The Events API returns a discriminated union: every record carries a type from the EventType enum, a created_at timestamp, and one of five Event_Payload shapes. This page lists each payload with its exact JSON schema and Go struct (from the generated OpenAPI types).
Discriminator: EventType
operation.status // OperationStatusPayload
query.status // QueryStatusPayload
watcher.status // WatcherStatusPayload
watcher.event // WatcherEventPayload ← cryptographically verifiable
wallet.status // WalletStatusPayload
The Go SDK exposes typed accessors on Event_Payload:
// returns (OperationStatusPayload, error)
ev.Payload.AsOperationStatusPayload()
ev.Payload.AsQueryStatusPayload()
ev.Payload.AsWatcherStatusPayload()
ev.Payload.AsWatcherEventPayload()
ev.Payload.AsWalletStatusPayload()
WatcherEventPayload (watcher.event)
The cryptographically verifiable on-chain event payload. Every other payload type is an operational notification produced by the CRE Connect backend.
type WatcherEventPayload struct {
ChainSelector string `json:"chain_selector"`
EventHash string `json:"event_hash"`
Timestamp int64 `json:"timestamp"`
VerifiableEvent string `json:"verifiable_event"` // base64
WatcherId string `json:"watcher_id"`
}
Field | Notes |
|---|---|
chain_selector | CCIP chain selector for the source chain. |
event_hash | Hash of the verifiable event payload: useful as a stable, cross-system identifier. |
timestamp | Unix seconds. |
verifiable_event | Base64-encoded VerifiableEvent: verify the parent event with events.Client.Verify, then decode with events.Client.DecodeVerifiableEvent (canonical model) or events.Client.Decode (into your own struct). |
watcher_id | UUID of the watcher that produced this event. |
VerifiableEvent itself is a models.VerifiableEvent carrying the raw EVM log, the Off-Chain Reporting (OCR) signatures, and the workflow context required for verification; see Event Verification.
OperationStatusPayload (operation.status)
Emitted on every operation transition.
type OperationStatusPayload struct {
Address string `json:"address"`
ChainSelector string `json:"chain_selector"`
EventHash *string `json:"event_hash,omitempty"`
OperationId openapi_types.UUID `json:"operation_id"`
Status OperationStatus `json:"status"`
StatusReason string `json:"status_reason"`
Timestamp int64 `json:"timestamp"`
VerifiableEvent *string `json:"verifiable_event,omitempty"`
WalletOperationId string `json:"wallet_operation_id"`
}
| Field | Notes |
|---|---|
address | Smart Account that authored the operation. |
chain_selector | Target chain. |
event_hash | Present for confirmed_latest, confirmed_safe, and confirmed statuses. |
operation_id | UUID assigned by the CRE Connect backend. |
status | One of pending_signature, accepted, sending, sent, broadcasting, confirmed_latest, confirmed_safe, confirmed, cancelled, expired, failed. |
status_reason | Human-readable explanation (especially for failed). |
verifiable_event | Present for confirmed_latest, confirmed_safe, and confirmed; verify with events.Client.VerifyOperationStatus. |
wallet_operation_id | The Smart-Account-side operation ID (your nonce + ABI-encoded operation). |
operation.status events at confirmed_latest, confirmed_safe, and confirmed are DON-verified and carry OCR proofs. Each confirmation status has a different chain-finality guarantee; see Multi-Event Finality. pending_signature, cancelled, expired, and non-terminal transitions (accepted, sending, sent, broadcasting) are operational notifications without OCR proofs. See Draft Operations.
QueryStatusPayload (query.status)
Emitted on every chain query transition.
type QueryStatusPayload struct {
QueryId openapi_types.UUID `json:"query_id"`
Status QueryStatus `json:"status"`
Target string `json:"target"`
ChainSelector string `json:"chain_selector"`
Timestamp int64 `json:"timestamp"`
EventHash *string `json:"event_hash,omitempty"`
VerifiableResult *string `json:"verifiable_result,omitempty"`
WorkflowId *string `json:"workflow_id,omitempty"`
WorkflowExecutionId *string `json:"workflow_execution_id,omitempty"`
}
| Field | Notes |
|---|---|
query_id | UUID assigned by the CRE Connect backend. |
status | One of accepted, sending, sent, completed, failed, expired. |
target | The contract address for evm_call queries. |
chain_selector | Target chain. |
timestamp | Unix seconds. |
event_hash | Present on terminal events (completed, failed); Keccak256(verifiable_result). |
verifiable_result | Present on terminal events; base64-encoded ChainQueryVerifiableEvent. |
workflow_id | CRE chain-query workflow that executed this query. |
workflow_execution_id | CRE execution ID from the workflow run. Present when the query completed with an OCR proof. |
Terminal query.status events (completed, failed) carry OCR proofs and can be verified with events.Client.VerifyQueryStatus. Non-terminal events (accepted, sending, sent) and expired events are operational notifications without OCR proofs. See Chain Queries.
WatcherStatusPayload (watcher.status)
Emitted on every watcher provisioning / archival transition.
type WatcherStatusPayload struct {
ChainSelector string `json:"chain_selector"`
Service *string `json:"service,omitempty"`
Status WatcherEventStatus `json:"status"`
StatusReason string `json:"status_reason"`
Timestamp int64 `json:"timestamp"`
WatcherId string `json:"watcher_id"`
}
WatcherEventStatus extends WatcherStatus with archival states for filtering:
pending | active | failed | archiving | archive_failed | archived
Field | Notes |
|---|---|
service | Service namespace (e.g. dta.v2) when the watcher was created with Watchers.CreateWithService. Absent for ABI-based watchers. |
status_reason | Useful when status == failed or archive_failed. |
WalletStatusPayload (wallet.status)
Emitted on every wallet (Smart Account) deploy / archival transition.
type WalletStatusPayload struct {
Address string `json:"address"`
ChainSelector string `json:"chain_selector"`
Status WalletEventStatus `json:"status"`
StatusReason string `json:"status_reason"`
Timestamp int64 `json:"timestamp"`
WalletId openapi_types.UUID `json:"wallet_id"`
}
WalletEventStatus:
pending | deploying | deployed | failed | archived
| Field | Notes |
|---|---|
address | Smart-Account address. May be unset on pending. |
wallet_id | Backend UUID. |
chain_selector | Target chain for the wallet. |
Common envelope
Every Event returned by /channels/{id}/events and /channels/{id}/events/search carries:
type Event struct {
ChannelId openapi_types.UUID `json:"channel_id"`
CreatedAt int64 `json:"created_at"`
EventId openapi_types.UUID `json:"event_id"`
Payload Event_Payload `json:"payload"`
Type EventType `json:"type"`
}
| Field | Notes |
|---|---|
event_id | Stable UUID for deduplication. |
created_at | Unix seconds: use as the cursor when paging. |
type | Discriminator (see top). |
payload | One of the four *Payload shapes above. |
Decoding watcher.event further
Once you have a WatcherEventPayload, the next step depends on what you want:
// Step 1: cryptographic verification (returns (bool, error))
ok, err := client.Events.Verify(&ev)
if err != nil || !ok { return err }
// Extract the typed payload
wp, err := ev.Payload.AsWatcherEventPayload()
if err != nil { return err }
// Step 2a: canonical decoded form
decoded, err := client.Events.DecodeVerifiableEvent(&wp)
if err != nil { return err }
// Step 2b: pull out the EVM-specific event and read its decoded params
evm, err := decoded.ChainEvent.AsEVMEvent()
if err != nil { return err }
params := *evm.Params
fmt.Println(params["from"], params["to"], params["value"])
// Step 2c: extension decoder (e.g. DTA v2): handles steps 2a and 2b
// for you and returns a typed struct.
typed, err := dtav2.DecodeFromEvent(ctx, ev)
See Decode Event Data.
See also
- Lifecycles: what
Statustransitions trigger each*.statuspayload. - Event Verification: how
verifiable_eventis signed and verified. - Verifiable Events: the
VerifiableEventmodel itself.