---
id: CAP-PFM-INT-015
title: Route integration events to their application owners
feature: FEAT-PFM-INT-04
product_area: platform
module: integrations
revision: 1
status: draft
product_intent: proposed
implementation_evidence: partially-observed
supersedes:
  - CAP-INT-EVT-007
  - CAP-INT-EVT-008
  - CAP-INT-EVT-009
  - CAP-INT-LIB-017
  - CAP-INT-SEC-015
  - CAP-INT-ADP-005
  - CAP-INT-ADP-007
  - CAP-INT-ADP-016
  - CAP-INT-ADP-029
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  macroservice-libraries: 54536a441935c6e09fdb7f96f0bec71c52ba4e03
intent_sources:
  - 'services-platform:docs/milestones/INTG-M3-webhooks-events-deliveries.md#Objective'
  - 'services-platform:docs/milestones/INTG-M2-calls-through-the-gateway.md#M2-D6'
purpose: Rhythm forwards provider events and completion results to the applications registered to receive them.
outcomes:
  - Registered applications receive relevant events; unclaimed events remain visible.
  - Completion results go to the application responsible for the call.
concepts:
  - CON-PFM-INT-004
actors:
  - ACT-PFM-020
  - ACT-PFM-021
  - ACT-PFM-006
  - ACT-PFM-019
surfaces:
  - api
  - job
preconditions: []
postconditions: []
permissions:
  - key: hq.integrations.publish
    where_checked: service
    scope: global
  - key: platform.integrations.read
    where_checked: api
    scope: tenant
  - key: hq.integrations.operate
    where_checked: api
    scope: global
rules:
  - id: BR-CAP-PFM-INT-015-01
    proved_by: [ATS-PFM-INT-015-01, TST-PFM-INT-537]
    statement: >-
      An application registers its consumer event types or prefixes under its own principal during deployment,
      replacing its previous registration in full.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/integrations/tests/integration/services/events/event-router.integration.spec.js#replaces
      what a principal registered before, whole
    origin: none
  - id: BR-CAP-PFM-INT-015-02
    proved_by: [ATS-PFM-INT-013-11, ATS-PFM-INT-015-02, ATS-PFM-INT-015-07, ATS-PFM-INT-015-10, TST-PFM-INT-537]
    statement: >-
      Each routing attempt invokes relevant consumers as Platform with batches no larger than ten; retries may
      repeat delivery to earlier successful consumers, requiring event-identity deduplication, and end dead
      after six attempts while events without recipients remain unclaimed.
    kind: lifecycle
    enforced_at:
      - service
    must_prove: true
    provenance: observed
    source: 'services-platform:modules/integrations/services/events/event-router.ts:routeIntegrationEvents'
    origin: none
  - id: BR-CAP-PFM-INT-015-03
    proved_by: [ATS-PFM-INT-010-10, ATS-PFM-INT-015-03, ATS-PFM-INT-015-08, TST-PFM-INT-480]
    statement: >-
      Execution-completion events reach only a consumer for the invoking application and include the response
      or error.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/integrations/tests/e2e-adapters/events-dummy.adapters.spec.js#reaches the
      consumer of the application that invoked it, carrying the response
    origin: 'services-platform:docs/milestones/INTG-M2-calls-through-the-gateway.md#M2-D6'
  - id: BR-CAP-PFM-INT-015-04
    proved_by: [ATS-PFM-INT-015-04, TST-PFM-INT-509]
    statement: >-
      An adapter emits no more than one hundred events per batch for its own connection, limited to declared
      produced types and valid event data.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/integrations/tests/integration/services/adapter-callbacks/adapter-callbacks.integration.spec.js#refuses
      a type the manifest does not produce, InvalidRequest
    origin: none
  - id: BR-CAP-PFM-INT-015-05
    proved_by: [ATS-PFM-INT-014-10, ATS-PFM-INT-015-05, ATS-PFM-INT-015-07, ATS-PFM-INT-015-09, TST-PFM-INT-537]
    statement: >-
      Event identifiers support consumer deduplication, and redelivered work for an already attempted dispatch
      has no further effect.
    kind: invariant
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/integrations/tests/integration/services/events/event-router.integration.spec.js#does
      nothing for a message of an attempt already made
    origin: none
  - id: BR-CAP-PFM-INT-015-06
    proved_by: [ATS-PFM-INT-015-06, TST-PFM-INT-537]
    statement: >-
      Workspace routes expose their own events, while Rhythm staff can list unclaimed and dead events across
      customers.
    kind: permission
    enforced_at:
      - api
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/integrations/tests/integration/services/events/event-router.integration.spec.js#lists
      the events nobody took for Rhythm HQ, across tenants
    origin: none
  - id: BR-CAP-PFM-INT-015-07
    proved_by: []
    statement: >-
      Webhook-derived events use the originating Rhythm record and execution where a provider reference
      matches, retaining the provider reference when no match exists.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/integrations/tests/unit/services/webhook-rules.spec.ts#names the Rhythm record
      of the execution that created the provider object
    origin: none
  - id: BR-CAP-PFM-INT-015-08
    proved_by: []
    statement: >-
      Data-grant query and projection callbacks validate adapter connection authority and then return the
      marked not-implemented response.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: observed
    source: 'services-platform:modules/integrations/aws/api/gateway.routes.ts:queryIntegrationDataGrant'
    origin: none
scenarios:
  - id: SC-CAP-PFM-INT-015-01
    given: The provider updates a payment initiated by Accounting.
    when: The router delivers the corresponding event.
    then: Accounting receives the associated Rhythm payment reference and acknowledges it.
    provenance: test
    source: >-
      services-platform:modules/integrations/tests/e2e-adapters/events-dummy.adapters.spec.js#reaches
      Accounting’s consumer, which acknowledges it
edge_cases: []
constraints: []
depends_on:
  - CAP-PFM-INT-013
related:
  - CAP-PFM-INT-010
  - CAP-PFM-INT-014
journeys: []
open_questions:
  - OQ-PFM-INT-002
evidence:
  - >-
    services-platform source inventory: modules/integrations/services/events/* (event-router.ts,
    complete-event.ts, event-operations.ts, execution-completed.ts), aws/api/registration.routes.ts
    (consumers), gateway.routes.ts (events, data grants), events.routes.ts; rule-level automated test
    references; docs/integrations/README.md (Integration events).
  - 'macroservice-libraries source inventory: packages/integration-contracts/src/events.ts.'
  - >-
    Operation coverage: registerIntegrationEventConsumer, emitIntegrationEvents, listIntegrationEvents,
    listIntegrationEventsEverywhere, queryIntegrationDataGrant, projectIntegrationDataGrant.
  - 'Persistent record coverage: integration_events, integration_event_consumers, integration_work_dispatches.'
  - 'End-to-end definition inventory: events-dummy.adapters.spec.js.'
controls: [TC-AVL-004, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-AZ-005, TC-CHG-001, TC-CHG-002, TC-CHG-003, TC-CHG-004, TC-CHG-005, TC-CHG-006, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-IAM-001, TC-IAM-002, TC-IAM-003, TC-IAM-004, TC-IAM-005, TC-IAM-006, TC-LOG-001, TC-LOG-005, TC-MON-001, TC-PI-001, TC-PI-002, TC-PI-003, TC-PI-004, TC-PI-005, TC-PRV-001, TC-PRV-002, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-TEN-004, TC-VEN-001, TC-VEN-002, TC-VEN-003]
exercised_by: [FAS-PFM-INT-04-01, FAS-PFM-INT-04-02, FAS-PFM-INT-04-03, FAS-PFM-INT-04-04, FAS-PFM-INT-04-05]
suites: [TST-PFM-INT-480, TST-PFM-INT-509, TST-PFM-INT-537]
---
# Route integration events to their application owners

## Purpose

Rhythm forwards provider events and completion results to the applications registered to receive them.

## How It Works

An application registers a consumer for the event types it understands. The router matches integration events to those registrations. Consumers answer whether they handled, ignored or need another attempt at a message. Events without a matching consumer remain visible rather than disappear. Provider references can link an event back to the Rhythm operation responsible for it. Completion results return to the application that initiated the call. Staff can investigate failed or unclaimed events across customers. Data access callbacks remain marked as unavailable. The product should establish event-consumer acceptance independently of the still-deferred data-grant feature.

## Relationships

- Requires retain and verify incoming provider notifications to supply the prerequisite configuration or operation.
- Connects with determine the result of uncertain or overdue calls through shared integration records.
- Connects with deliver subscribed rhythm changes to integrations through shared integration records.
