---
id: WF-PFM-INT-018
title: Deliver subscribed Rhythm changes to an integration
trigger: The initiating owning application starts this flow.
product_area: platform
module: integrations
revision: 1
status: draft
design_intent: proposed
implementation_evidence: observed
inference: []
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
implements:
  - CAP-PFM-INT-014
moves:
  - STATE-PFM-INT-011
  - STATE-PFM-INT-012
crosses: []
idempotency: >-
  Subscription-change keys prevent new duplicate delivery records; adapters recognize repeated delivery
  identifiers.
concurrency: Fan-out and worker attempts process deliveries independently; no adapter delivery ordering is guaranteed.
hops:
  - 'n': 1
    actor_or_service: Owning application
    action: Receive up to one hundred source-record change events from the owning application.
    anchor: 'services-platform:modules/integrations/services/subscriptions/change-event-handler.ts:handleChangeEvents'
    seam: event
    on_failure: The source stream repeats unsuccessful work.
    left_inconsistent: The source retains changes awaiting acknowledgement.
    observer: The owner’s stream metrics
    provenance: observed
    source: 'services-platform:modules/integrations/services/subscriptions/change-event-handler.ts:handleChangeEvents'
  - 'n': 2
    actor_or_service: Change-event handler
    action: >-
      Find eligible active subscriptions, evaluate change-time filters and commit projected or filtered
      delivery records keyed to each subscription and change.
    anchor: 'services-platform:modules/integrations/services/subscriptions/change-event-handler.ts:handleChangeEvents'
    seam: sync
    on_failure: Return event-specific failures for source retry.
    left_inconsistent: Previously successful event processing need not roll back with another failed event.
    observer: Events screen
    provenance: observed
    source: 'services-platform:modules/integrations/services/subscriptions/change-event-handler.ts:handleChangeEvents'
  - 'n': 3
    actor_or_service: Message work dispatcher
    action: Publish push-delivery dispatch work to the delivery queue.
    anchor: 'services-platform:modules/integrations/services/work/work-dispatcher.ts:dispatchWork'
    seam: queue
    on_failure: Retain unpublished work for a later pass.
    left_inconsistent: Duplicate queue messages can follow publication-before-deletion failures.
    observer: Dispatcher silence alarm
    provenance: observed
    source: 'services-platform:modules/integrations/services/work/work-dispatcher.ts:dispatchWork'
  - 'n': 4
    actor_or_service: Delivery worker
    action: >-
      Lease account credentials and invoke adapter delivery with its stable delivery identifier, saving
      acknowledgement.
    anchor: 'services-platform:modules/integrations/services/subscriptions/delivery-worker.ts:processDelivery'
    seam: queue
    on_failure: Retry classified failures with backoff until dead.
    left_inconsistent: The adapter can apply a change whose acknowledgement was lost.
    observer: Events screen
    provenance: observed
    source: 'services-platform:modules/integrations/services/subscriptions/delivery-worker.ts:processDelivery'
  - 'n': 5
    actor_or_service: Delivery worker
    action: Pause an active subscription at fifty successive dead deliveries and request one administrator notice.
    anchor: 'services-platform:modules/integrations/services/subscriptions/delivery-worker.ts:processDelivery'
    seam: sync
    on_failure: Log notice failure.
    left_inconsistent: New changes are skipped while paused and are not recovered automatically on resume.
    observer: Needs Attention
    provenance: observed
    source: 'services-platform:modules/integrations/services/subscriptions/delivery-worker.ts:processDelivery'
  - 'n': 6
    actor_or_service: Adapter
    action: 'For pull delivery, read pending changes and advance the cursor, marking covered deliveries delivered.'
    anchor: 'services-platform:modules/integrations/services/events/event-operations.ts:writePullCursor'
    seam: sync
    on_failure: Reject adapters outside the authorized account boundary.
    left_inconsistent: Unread pending changes remain until a valid cursor write.
    observer: Events screen
    provenance: observed
    source: 'services-platform:modules/integrations/aws/api/gateway.routes.ts:writePullCursor'
  - 'n': 7
    actor_or_service: Executions operator
    action: >-
      Restart supported failed deliveries or replay an existing subscription-delivery window of up to seven
      days.
    anchor: 'services-platform:modules/integrations/services/events/event-operations.ts:replaySubscription'
    seam: sync
    on_failure: Reject invalid windows or unsupported retry requests.
    left_inconsistent: Replay can repeat a change already applied; it does not invent deliveries skipped during a pause.
    observer: Integration history
    provenance: observed
    source: 'services-platform:modules/integrations/services/events/event-operations.ts:replaySubscription'
evidence:
  - >-
    services-platform at ad3f6a65: modules/integrations/services/subscriptions/change-event-handler.ts,
    domain-event-projection.ts, subscription-filter.ts, delivery-worker.ts;
    services/events/event-operations.ts; docs/integrations/README.md (Subscriptions and deliveries)
  - >-
    services-platform:modules/integrations/tests/integration/services/subscriptions/subscriptions.integration.spec.js#turns
    a CRM change event into a queued delivery of the catalog projection, never the row
  - >-
    services-platform:modules/integrations/tests/integration/services/subscriptions/subscriptions.integration.spec.js#retries
    a classified failure with the async backoff and records the delivery dead after six attempts
  - >-
    services-platform:modules/integrations/tests/integration/services/subscriptions/subscriptions.integration.spec.js#pauses
    a subscription after fifty dead deliveries in a row and tells its administrators once
  - >-
    services-platform:modules/integrations/tests/integration/services/subscriptions/subscriptions.integration.spec.js#retries
    a dead delivery an operator asks for, from its first attempt
controls: [TC-AVL-001, TC-AVL-004, TC-AVL-005, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-DAT-004, TC-IAM-001, TC-IAM-002, TC-IAM-004, TC-IAM-005, TC-IAM-006, TC-LOG-001, TC-LOG-002, TC-LOG-003, TC-LOG-005, TC-MON-001, TC-MON-002, TC-PI-001, TC-PI-002, TC-PI-003, TC-PI-004, TC-PI-005, TC-PRV-001, TC-PRV-002, TC-PRV-004, TC-SEC-001, TC-SEC-002, TC-SEC-003, TC-SEC-004, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-VEN-001, TC-VEN-002, TC-VEN-003]
---

# Deliver subscribed Rhythm changes to an integration

## What It Does

Subscriptions project allowed Rhythm change fields into deliveries for an installed adapter. Push processing invokes the adapter; pull processing waits for a cursor. Repeated dead delivery pauses future fan-out until an administrator intervenes.

## The Flow

```mermaid
sequenceDiagram
  participant P0 as Owning application
  participant P1 as Change-event handler
  participant P2 as Message work dispatcher
  participant P3 as Delivery worker
  participant P4 as Adapter
  participant P5 as Executions operator
  P0->>P0: 1. Receive up to one hundred source-record change events from the owning application.
  P1->>P1: 2. Find eligible active subscriptions
  P2->>P2: 3. Publish push-delivery dispatch work to the delivery queue.
  P3->>P3: 4. Lease account credentials and invoke adapter delivery with its stable delivery identifier
  P3->>P3: 5. Pause an active subscription at fifty successive dead deliveries and request one administrator notice.
  P4->>P4: 6. For pull delivery
  P5->>P5: 7. Restart supported failed deliveries or replay an existing subscription-delivery window of up to seven days.
```

## When Something Fails

The source stream repeats unsuccessful work. The source retains changes awaiting acknowledgement. Return event-specific failures for source retry. Previously successful event processing need not roll back with another failed event. Retain unpublished work for a later pass. Duplicate queue messages can follow publication-before-deletion failures. Retry classified failures with backoff until dead. The adapter can apply a change whose acknowledgement was lost. Log notice failure. New changes are skipped while paused and are not recovered automatically on resume. Reject adapters outside the authorized account boundary. Unread pending changes remain until a valid cursor write. Reject invalid windows or unsupported retry requests. Replay can repeat a change already applied; it does not invent deliveries skipped during a pause.

## Open Design Questions

Replay covers existing delivery records and cannot recreate changes skipped while paused. Pull support must remain distinct from unbuilt synchronization profiles.
