Skip to main content
Agreement activity webhooks are agreement.transitioned events. Use them when your backend needs to react to agreement lifecycle changes without polling agreement state on a timer. Treat each activity webhook as a compact signal: verify it, store and dedupe it, acknowledge it, and then read current agreement data from the Agreements API before updating your local mirror.

Before you start

Create a webhook subscription that includes agreement.transitioned:
For signing, retries, test events, URL requirements, and shared filter semantics, see Receive webhooks.

When activity events are sent

Shodai sends agreement.transitioned for API-managed agreements owned by the Shodai account when:
  • the chain projection worker reconciles an agreement deployment into its initial state
  • a mined input changes the agreement state
Deploy transition events are produced from finalized chain projection, not by the deployment response. The deployment request returns after the transaction receipt is mined, at roughly one confirmation, without waiting for webhook finality. Projection emits the canonical transition only after the deployment block reaches the shared finality pin at head - 20. Deploy transitions use fromState: "", inputId: "__deploy", and sequence: 0. Those are payload values, not filter values: to subscribe to deploy transitions only, filter with inputIds: ["__deploy"] — a blank filter value such as fromStates: [""] is rejected with 400. Input transition events are sent only when the mined input changes state. If an input is accepted but the agreement remains in the same state, no agreement.transitioned event is emitted for that input.

Payload shape

An activity event includes compact transition data:
The activity payload does not include the full agreement record, variables, participants, observers, or full input history.

Reconcile after receipt

After verification and dedupe, read the current agreement data before updating local state:
Use GET /v0/agreements/{id} for the hosted agreement record, GET /v0/agreements/{id}/state for current lifecycle state, and GET /v0/agreements/{id}/inputs for input history. This pattern keeps your integration resilient when events arrive more than once, arrive after your own write response, or do not contain enough data to update your local model directly.

Filter activity events

Activity webhooks support these filters: Filter values are exact string matches. Multiple values inside one filter field act like OR. Different filter fields combine like AND. Use inputIds: ["__deploy"] to receive only deploy activity events for matching agreements and templates.

Idempotency expectations

Webhook delivery is at-least-once. Your receiver should:
  • store each event by id
  • treat a repeated id as already received
  • return 2xx after durable receipt
  • process reconciliation asynchronously when possible
  • make local mirror updates idempotent
Activity events are compact and may arrive after your backend has already observed the same state through a write response or a manual refresh. Retries can also reorder arrival. For one agreement, apply events by sequence, ignore a sequence lower than the highest already applied, and use the current API state as the source of truth. Events emitted before sequence was introduced may omit it.