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_selectorCCIP chain selector for the source chain.
event_hashHash of the verifiable event payload: useful as a stable, cross-system identifier.
timestampUnix seconds.
verifiable_eventBase64-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_idUUID 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"`
}
FieldNotes
addressSmart Account that authored the operation.
chain_selectorTarget chain.
event_hashPresent for confirmed_latest, confirmed_safe, and confirmed statuses.
operation_idUUID assigned by the CRE Connect backend.
statusOne of pending_signature, accepted, sending, sent, broadcasting, confirmed_latest, confirmed_safe, confirmed, cancelled, expired, failed.
status_reasonHuman-readable explanation (especially for failed).
verifiable_eventPresent for confirmed_latest, confirmed_safe, and confirmed; verify with events.Client.VerifyOperationStatus.
wallet_operation_idThe 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"`
}
FieldNotes
query_idUUID assigned by the CRE Connect backend.
statusOne of accepted, sending, sent, completed, failed, expired.
targetThe contract address for evm_call queries.
chain_selectorTarget chain.
timestampUnix seconds.
event_hashPresent on terminal events (completed, failed); Keccak256(verifiable_result).
verifiable_resultPresent on terminal events; base64-encoded ChainQueryVerifiableEvent.
workflow_idCRE chain-query workflow that executed this query.
workflow_execution_idCRE 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
serviceService namespace (e.g. dta.v2) when the watcher was created with Watchers.CreateWithService. Absent for ABI-based watchers.
status_reasonUseful 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
FieldNotes
addressSmart-Account address. May be unset on pending.
wallet_idBackend UUID.
chain_selectorTarget 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"`
}
FieldNotes
event_idStable UUID for deduplication.
created_atUnix seconds: use as the cursor when paging.
typeDiscriminator (see top).
payloadOne 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

Get the latest Chainlink content straight to your inbox.