The starting point
Connecting an AI workflow to another application introduces a new responsibility: the generated suggestion can now cause a real change. The integration needs an explicit contract for the record being changed, the actor authorizing it, the permitted fields, and the evidence that confirms completion.
Choose the trigger from the business timing requirement. A user-facing lookup may need a direct API response. A record-change notification may fit an event. A source that exposes only periodic data may need polling. These mechanisms have different delays and failure modes, so define freshness and recovery requirements before selecting one.
Treat an accepted event, a processing attempt, and a completed destination action as different states. When a request times out, the destination may already have committed it. The recovery design should explain how the operator can discover that outcome without blindly repeating the effect.
The decisions that shape the implementation
Define a contract and a source of truth
Record identifiers, schema version, required fields, timestamps, ownership, and how changes are ordered. Decide which system can change each field and how conflicting updates are resolved. An adapter can translate between applications, while a shared business meaning keeps those translations consistent across the workflow.
Acknowledge only what has been durably accepted
A webhook handler should authenticate the delivery and persist accepted work before returning an acknowledgement. Long-running processing belongs behind that handoff. Keep an inbox key for repeated events and preserve the dispatch intent in a durable record so a process restart does not erase work that the sender believes was accepted.
Make repeated delivery safe at the destination
Deduplicating an incoming event does not by itself prevent a destination action from repeating after a timeout. Use a destination-supported idempotency key where available and retain the action’s identifiers and result. If completion is uncertain, query the destination or route the item for reconciliation before creating another effect.
Bound retries and make exceptions operable
Retry transient failures with a delay and a limit; do not retry an invalid mapping or missing permission indefinitely. Respect provider limits, keep attempt history, and send exhausted or ambiguous work to a visible exception state. Reconciliation compares intended changes with destination records and catches gaps that a successful transport response alone cannot explain.
Architecture and data flow
- Verify and validate
Authenticate the sender and validate the event contract and account scope.
- Record and dispatch
Persist accepted work with its unique event key and delivery intent.
- Apply the change
Use a bounded worker, an approved mapping, and a destination idempotency key.
- Reconcile the result
Record completion or an exception and compare uncertain effects with the destination.
Provider-specific signature rules belong at ingress. Approval, account scope, and field permissions belong at the action boundary. Delivery history and reconciliation support recovery across both.
Accept repeated events without repeating accepted work
The handler verifies the provider’s signature using the expected raw request format, then persists the event and dispatch intent atomically. A destination worker handles the external action separately.
function receive(rawBody, headers):
provider = verifyProviderSignature(rawBody, headers)
event = parseAndValidate(rawBody, provider.schema)
scope = resolveConfiguredConnection(provider, event.accountId)
eventHash = hash(canonicalize(event))
transaction:
accepted = insertInboxIfAbsent(
scope, provider.id, event.id, eventHash
)
if not accepted:
requireSameAcceptedPayload(scope, provider.id, event.id, eventHash)
return acknowledgement()
appendOutbox("delivery.ready", scope, event.id)
return acknowledgement()
function deliver(job):
change = loadApprovedMappedChange(job)
authorizeConnector(job.connection, job.scope, change)
result = destination.apply(change, key = job.actionKey)
recordDeliveryResult(job, result)Enforce the inbox key with a database uniqueness constraint. Treat the destination call and local completion record as a separate failure boundary; use the same action key on a retry. Handle provider-specific event ordering, signature replay windows, and uncertain destination responses in the adapter and operating runbook.
An automated newsroom and a product enquiry handoff
RoboMarket’s newsroom fetches external coverage, normalizes records, filters content, deduplicates items, and ranks stored articles before public display. A separate enquiry path carries product and contact context into partner and support email workflows. Each integration serves a different business step and needs its own completion and exception behavior.
The integration lesson is to separate content preparation from public reads and contact delivery from the visitor’s research. Feed aggregation and signed webhooks use different ingress mechanisms, but both benefit from explicit identifiers, repeatable processing, and visible failures. The webhook sketch above illustrates a separate event-driven handoff that can be applied when a provider offers that contract.
Explore the catalogue, enquiry routing, and stored-newsroom pipeline in the RoboMarket case study. Read the RoboMarket.ae case study.
Failure cases to design for
A successful acknowledgement confused with completed work
Report the lifecycle explicitly. An accepted event can still be waiting, retrying, or in an exception state before its destination action completes.
Retrying every failure in the same way
Separate transient provider failures, permanent validation errors, missing permissions, and uncertain completion. Each category needs a different recovery decision.
Unobserved schema or ordering changes
Validate versioned payloads and define how older or out-of-order changes affect the destination. Preserve enough history to reconcile the record that should now exist.
Measurable outcomes
Agree on a baseline, a representative workload, and the evidence needed for the next decision. Keep the measurement conditions with the result.
- Completed delivery and freshness
Track completed destination actions divided by accepted events, plus acceptance-to-completion delay and unresolved backlog age.
Count failed and missing work in the report and distinguish timely completion from eventual recovery.
- Duplicate destination effects
Replay deliveries, interrupt a worker after the remote call, and count extra committed changes at the destination.
Investigate every duplicate effect in the replay set; use reconciliation when the destination cannot enforce a stable action key.
- Exception recovery effort
Record time to diagnose and resolve each exception type, including the work needed to inspect the destination.
Prioritize errors that consume operator time or leave the business record uncertain, rather than only reducing retry counts.
For delivery milestones and acceptance criteria, explore AI software engineering, automation & integrations and Data, cloud & modernization.
Sources and next reading
- Stripe: webhook delivery and handling. A concrete provider reference for signatures, repeated events, delivery behavior, and asynchronous handling.
- AWS: transactional outbox. Atomic recording of state and dispatch intent, with duplicate-aware downstream processing.
Return to the AI software engineering guide to connect these decisions to the wider product lifecycle.