Manage Watcher Lifecycle

Once a watcher is created (see Create with Service or Create with ABI), you can list, filter, rename, and archive it.

Status reference

A watcher moves through these states:

The entity statuses surfaced by the REST API are pending, active, archiving, archived, and failed (the API maps internal archive_failed to failed on the entity response). The richer archive_failed state is visible on the watcher.status event payload (apiClient.WatcherEventStatus).

List and filter

The Watchers tab on the channel page lists every watcher with its status. Use the Service, Network, and Status filters to narrow the view.

Go SDK

import (
    apiClient "github.com/smartcontractkit/crec-api-go/client"
    "github.com/smartcontractkit/crec-sdk/watchers"
)

active := []apiClient.WatcherStatus{apiClient.WatcherStatusActive}
limit := 50

list, err := client.Watchers.List(ctx, channelID, watchers.ListFilters{
    Status:        &active,
    ChainSelector: ptr("16015286601757825753"),
    EventName:     ptr("Transfer"),
    Limit:         &limit,
})

curl

curl -sS "$CREC_BASE_URL/channels/$CHANNEL_ID/watchers?status=active&chain_selector=16015286601757825753&limit=50" \
  -H "Authorization: Apikey $CREC_API_KEY"

Available filter fields on ListFilters:

FieldNotes
Limit / OffsetPagination; check HasMore.
NameSubstring match on watcher name.
StatusSlice of apiClient.WatcherStatus.
ChainSelectorFilter by chain.
AddressFilter by contract address.
ServiceSlice of service names (e.g. ["dta.v2"]).
EventNameFilter watchers subscribed to a specific event.

Get a single watcher

w, err := client.Watchers.Get(ctx, channelID, watcherID)
if errors.Is(err, watchers.ErrWatcherNotFound) {
    // 404: surface to caller
}

The watcher's Status, ChainSelector, Address, and (for service watchers) Service are all returned in the response. The StatusReason is not part of the entity response; subscribe to watcher.status events on the channel to receive the human-readable reason whenever the status changes.

Update metadata (name only)

The SDK only supports updating the watcher name. Address, ABI, service, and chain selector are immutable; create a new watcher to change them.

Open the watcher detail panel and click the pencil icon next to the name to rename it inline.

updated, err := client.Watchers.Update(ctx, channelID, watcherID, watchers.UpdateInput{
    Name: "renamed-watcher",
})
curl -sS -X PATCH "$CREC_BASE_URL/channels/$CHANNEL_ID/watchers/$WATCHER_ID" \
  -H "Authorization: Apikey $CREC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"renamed-watcher"}'

Archive

Archiving is asynchronous. The PATCH returns HTTP 202 with the watcher in archiving; you must poll until it reaches archived or archive_failed.

Click the menu on the watcher row and select Archive, then confirm. The status will transition to archiving immediately and to archived shortly after.

Go SDK

queued, err := client.Watchers.Archive(ctx, channelID, watcherID)
if err != nil {
    return err
}
fmt.Println(queued.Status) // -> archiving

if err := client.Watchers.WaitForArchived(ctx, channelID, watcherID, 60*time.Second); err != nil {
    return err
}

curl

curl -sS -X PATCH "$CREC_BASE_URL/channels/$CHANNEL_ID/watchers/$WATCHER_ID" \
  -H "Authorization: Apikey $CREC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status":"archived"}'
# -> 202 Accepted, body contains watcher with status "archiving"

WaitForArchived returns watchers.ErrWaitForArchivedTimeout if the deadline elapses. If the watcher transitions back to active/pending/failed instead of archived, it returns watchers.ErrWatcherArchiveFailed: investigate the workflow's logs and retry.

Handling failure states

Sentinel error
Returned by
Recovery
watchers.ErrWatcherDeploymentFailedWaitForActiveArchive, then re-create; check service config and address.
watchers.ErrWatcherIsArchivingWaitForActiveSomeone archived concurrently; wait for WaitForArchived.
watchers.ErrWatcherAlreadyArchivedWaitForActiveArchived watchers cannot return to active; create a new one.
watchers.ErrWatcherArchiveFailedWaitForArchivedSubscribe to the watcher.status event on the channel to read the StatusReason, then retry the archive once.

Transient vs. permanent errors

WaitForActive and WaitForArchived both invoke the SDK's isTransientError helper. Transient errors (HTTP 429, 5xx, network timeouts, broken pipes) are silently retried at the configured poll interval. Permanent errors (validation, ctx.Done(), 4xx other than 429) abort the wait immediately.

For details on tuning the poll interval and consistency window, see SDK Configuration.

Next steps

Get the latest Chainlink content straight to your inbox.