# Webhook Processing Reconciliation (`h_murdock/webhook-processing-reconciliation`) Actor

Find acknowledged webhook events without processing, overdue pending records, possible repeated successful processing and orphans in supplied scoped metadata exports. JSON, CSV and HTML evidence.

- **URL**: https://apify.com/h\_murdock/webhook-processing-reconciliation.md
- **Developed by:** [Gilad Ronen](https://apify.com/h_murdock) (community)
- **Categories:** Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.25 / completed report

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Webhook Processing Reconciliation

A webhook dashboard can say “delivered” while the application worker never records successful processing. Compare your **delivery-attempt metadata** with a separate **application processing ledger** to find that gap after a deploy or in a daily integration audit.

This Actor produces a review queue with exact event scopes, delivery IDs, processing IDs, timestamps, coverage explanations and JSON Pointers to your supplied rows. It accepts metadata exports; it does not require provider credentials, customer payloads or an external API subscription.

### What it checks

- Acknowledged events without successful application processing beyond your chosen delay, when complete comparable exports support the finding.
- Pending processing older than your policy, using the supplied application receipt time.
- Distinct successful processing records for one logical event and consumer, as possible repeated processing evidence.
- Processing records without delivery evidence, with a confirmed orphan finding only when complete coverage and an in-window `receivedAt` establish the comparison.
- Conflicting record IDs, repeated export rows, missing coverage, stale windows, out-of-window rows and future or impossible times.

An HTTP 2xx acknowledges delivery. It is not proof that your worker processed the event. Two transport attempts are legitimate retry evidence. Two successful processing IDs suggest possible repeated application processing; they do not prove that an invoice, order or other real side effect happened twice. Failed application and transport records remain visible alongside later supplied success, without claiming an event ordering from provider creation timestamps.

### Input and identity

Supply one JSON object containing all five required fields:

```json
{
  "asOf": "2026-10-01T11:00:00Z",
  "maxProcessingDelayMinutes": 5,
  "coverage": [{
    "scope": {"provider":"example","account":"account-001","subscription":"orders","consumer":"order-worker"},
    "delivery": {"from":"2026-10-01T09:00:00Z","to":"2026-10-01T11:00:00Z","complete":true},
    "processing": {"from":"2026-10-01T09:00:00Z","to":"2026-10-01T11:00:00Z","complete":true}
  }],
  "deliveries": [{
    "attemptId":"delivery-001",
    "scope":{"provider":"example","account":"account-001","subscription":"orders","consumer":"order-worker"},
    "eventKey":"event-001",
    "timestamp":"2026-10-01T10:00:00Z",
    "outcome":"acknowledged",
    "httpStatus":200
  }],
  "processing": []
}
```

This example yields an acknowledgment gap aged 60 minutes. The full synthetic fixture in `examples/input.json` also demonstrates a recovered retry, repeated successes, recent pending work, an orphan, partial coverage and a future record.

The four exact, case-sensitive scope values plus `eventKey` identify a logical event. Use aliases when identifiers are confidential. Preserve IDs as strings, including leading zeros. `attemptId` identifies one delivery attempt; `recordId` identifies one application ledger entry. These IDs must be unique within their entire respective input table. Prefix locally reused IDs with a stable source namespace before exporting. Delivery and processing IDs are separate and may coincide without joining different events.

Deliveries accept `acknowledged`, `failed` or `pending`. Optional `httpStatus` must be 2xx for acknowledged, non-2xx for failed, and omitted for pending. Processing accepts `succeeded`, `failed` or `pending`. `timestamp` means the actual recorded state time; optional `receivedAt` means receipt by your application. A pending state update time cannot replace receipt time. Use real UTC timestamps with seconds and optionally exactly three fractional digits. Unknown fields are rejected, including payload/header/token fields.

### Preparing inexpensive exports

Export only these metadata columns from your existing receiver log and worker ledger. Generate a distinct attempt ID for each receipt/response attempt, even when the provider retries the same event. Keep the provider event correlation ID in `eventKey`. Keep the subscription and consumer explicit: two legitimate subscriptions or workers must remain separate scopes. For Shopify, distinguish delivery identity from event correlation identity. For Stripe, do not substitute a second-resolution event-created timestamp for receipt or processing time. Map provider response status to acknowledgment, never to application success.

For a daily audit, choose one exact `asOf` and a start time retained by both systems. Read both exports over those same **closed intervals**, including endpoint timestamps. Retrieve every page and include all matching scopes, attempts and ledger records. Mark `complete:true` only after confirming retention, filters, pagination and source access. If your exporter uses half-open database queries, adapt its boundary explicitly rather than silently omitting the last instant. A useful receiver/worker SQL export recipe is provided in `docs/EXPORT-RECIPE.md`.

For current missing-event comparisons, both declared windows must be complete, identical and end at `asOf`; otherwise the finding stays uncertain. Rows outside a declared window or beyond `asOf` remain unresolved evidence and are excluded from current state. Processing before `receivedAt` is unresolved. Nothing absent from every supplied source can be discovered.

Repeated identical IDs with exactly equal normalized field values are counted once. Object-key order is ignored after typed normalization; timestamp spellings and string values are compared exactly. Conflicting versions are all quarantined. Conflict pointers include each affected event's rows plus a differing comparison pair, keeping a large ambiguous export bounded.

### Downloads and repeat usage

The dataset contains **one complete report item** with `summary`, `events`, `coverage`, `rows` and limitations. Each evidence row has a stable issue ID for unchanged input, scope, event key, related attempt/processing IDs, age when valid, source pointers and a reason. Event states partition into processed, pending, review or uncertain; a supplied success can still be present on an uncertain event. Review and uncertainty counts are reported separately.

Download full JSON from `OUTPUT`, flat evidence CSV from `reconciliation.csv`, or a standalone HTML report from `report.html`. CSV protects spreadsheet formula cells; HTML escapes identifiers and includes no external scripts. Reuse your normalization and delay policy for the next daily export or deployment. Review uncertain evidence before declaring an integration healthy.

### Price, limits and recovery

Price: **$0.25 per completed report**, including platform usage. One new run with the same input is a new billable report. There is no startup fee or per-row event. Maximum input is 2 MB UTF-8 JSON, 10,000 combined metadata rows and 500 coverage declarations. The allowed delay is an integer from 1 to 10,080 minutes. Full JSON must stay below 8 MB and each export below 9 MB; every export is checked before charging. Split dense exports if these output limits are reached.

The primary paid deliverable is the complete dataset item. If convenience export writing is interrupted after delivery, resurrecting the same run verifies the input and saved report, then repairs downloads without another report charge or dataset item. Missing or modified saved data is rejected. An interruption between dataset writing and event charging can charge the intact saved report once on recovery. This does not promise atomic delivery of every download during platform outages.

The Actor compares caller-supplied evidence. It does not validate signatures, receive live webhooks, replay events, retry workers, modify queues or independently verify declared completeness or business side effects.

# Actor input Schema

## `asOf` (type: `string`):

Strict real UTC timestamp YYYY-MM-DDTHH:mm:ss\[.sss]Z.

## `maxProcessingDelayMinutes` (type: `integer`):

Whole minutes from earliest usable acknowledgment or supplied pending receivedAt. Range 1–10,080 (7 days). No vendor SLA is assumed.

## `coverage` (type: `array`):

Supply this array; \[] allowed; validated by Actor. One declaration per exact four-part scope; closed UTC windows. Complete current comparisons require equal delivery/processing windows ending at asOf. A complete export must include all matching attempts and processing records in its declared interval.

## `deliveries` (type: `array`):

Supply this array; \[] allowed; validated by Actor. Distinct retry attempt IDs. HTTP acknowledgment does not imply application processing. Exact export replay rows are counted once; conflicting IDs are quarantined.

## `processing` (type: `array`):

Supply this array; \[] allowed; validated by Actor. Distinct processing record IDs and explicit state, independent of delivery attempts. Optional receivedAt establishes receipt age and complete-window orphan evidence. Do not infer state from HTTP status.

## Actor input object example

```json
{
  "asOf": "2026-10-01T11:00:00Z",
  "maxProcessingDelayMinutes": 5,
  "coverage": [
    {
      "scope": {
        "provider": "stripe",
        "account": "acct_example_001",
        "subscription": "orders-subscription",
        "consumer": "order-worker"
      },
      "delivery": {
        "from": "2026-10-01T09:00:00Z",
        "to": "2026-10-01T11:00:00Z",
        "complete": true
      },
      "processing": {
        "from": "2026-10-01T09:00:00Z",
        "to": "2026-10-01T11:00:00Z",
        "complete": true
      }
    },
    {
      "scope": {
        "provider": "github",
        "account": "example-repo",
        "subscription": "deployment-subscription",
        "consumer": "deploy-worker"
      },
      "delivery": {
        "from": "2026-10-01T09:00:00Z",
        "to": "2026-10-01T11:00:00Z",
        "complete": true
      },
      "processing": {
        "from": "2026-10-01T09:00:00Z",
        "to": "2026-10-01T11:00:00Z",
        "complete": false
      }
    }
  ],
  "deliveries": [
    {
      "attemptId": "del_retry_01",
      "scope": {
        "provider": "stripe",
        "account": "acct_example_001",
        "subscription": "orders-subscription",
        "consumer": "order-worker"
      },
      "eventKey": "evt_recovered",
      "timestamp": "2026-10-01T09:10:00Z",
      "outcome": "failed",
      "httpStatus": 503
    },
    {
      "attemptId": "del_retry_02",
      "scope": {
        "provider": "stripe",
        "account": "acct_example_001",
        "subscription": "orders-subscription",
        "consumer": "order-worker"
      },
      "eventKey": "evt_recovered",
      "timestamp": "2026-10-01T09:11:00Z",
      "outcome": "acknowledged",
      "httpStatus": 200
    },
    {
      "attemptId": "del_gap",
      "scope": {
        "provider": "stripe",
        "account": "acct_example_001",
        "subscription": "orders-subscription",
        "consumer": "order-worker"
      },
      "eventKey": "evt_ack_gap",
      "timestamp": "2026-10-01T09:30:00Z",
      "outcome": "acknowledged",
      "httpStatus": 200
    },
    {
      "attemptId": "del_repeat",
      "scope": {
        "provider": "stripe",
        "account": "acct_example_001",
        "subscription": "orders-subscription",
        "consumer": "order-worker"
      },
      "eventKey": "evt_two_successes",
      "timestamp": "2026-10-01T09:40:00Z",
      "outcome": "acknowledged",
      "httpStatus": 200
    },
    {
      "attemptId": "del_pending",
      "scope": {
        "provider": "stripe",
        "account": "acct_example_001",
        "subscription": "orders-subscription",
        "consumer": "order-worker"
      },
      "eventKey": "evt_pending",
      "timestamp": "2026-10-01T10:59:00Z",
      "outcome": "acknowledged",
      "httpStatus": 200
    },
    {
      "attemptId": "del_partial",
      "scope": {
        "provider": "github",
        "account": "example-repo",
        "subscription": "deployment-subscription",
        "consumer": "deploy-worker"
      },
      "eventKey": "evt_partial",
      "timestamp": "2026-10-01T09:50:00Z",
      "outcome": "acknowledged",
      "httpStatus": 200
    },
    {
      "attemptId": "del_future",
      "scope": {
        "provider": "stripe",
        "account": "acct_example_001",
        "subscription": "orders-subscription",
        "consumer": "order-worker"
      },
      "eventKey": "evt_future",
      "timestamp": "2026-10-01T10:00:00Z",
      "outcome": "acknowledged",
      "httpStatus": 200
    },
    {
      "attemptId": "del_retry_02",
      "scope": {
        "provider": "stripe",
        "account": "acct_example_001",
        "subscription": "orders-subscription",
        "consumer": "order-worker"
      },
      "eventKey": "evt_recovered",
      "timestamp": "2026-10-01T09:11:00Z",
      "outcome": "acknowledged",
      "httpStatus": 200
    }
  ],
  "processing": [
    {
      "recordId": "proc_failed",
      "scope": {
        "provider": "stripe",
        "account": "acct_example_001",
        "subscription": "orders-subscription",
        "consumer": "order-worker"
      },
      "eventKey": "evt_recovered",
      "timestamp": "2026-10-01T09:11:30Z",
      "state": "failed",
      "receivedAt": "2026-10-01T09:11:00Z"
    },
    {
      "recordId": "proc_recovered",
      "scope": {
        "provider": "stripe",
        "account": "acct_example_001",
        "subscription": "orders-subscription",
        "consumer": "order-worker"
      },
      "eventKey": "evt_recovered",
      "timestamp": "2026-10-01T09:12:00Z",
      "state": "succeeded",
      "receivedAt": "2026-10-01T09:11:00Z"
    },
    {
      "recordId": "proc_repeat_01",
      "scope": {
        "provider": "stripe",
        "account": "acct_example_001",
        "subscription": "orders-subscription",
        "consumer": "order-worker"
      },
      "eventKey": "evt_two_successes",
      "timestamp": "2026-10-01T09:41:00Z",
      "state": "succeeded",
      "receivedAt": "2026-10-01T09:40:00Z"
    },
    {
      "recordId": "proc_repeat_02",
      "scope": {
        "provider": "stripe",
        "account": "acct_example_001",
        "subscription": "orders-subscription",
        "consumer": "order-worker"
      },
      "eventKey": "evt_two_successes",
      "timestamp": "2026-10-01T09:42:00Z",
      "state": "succeeded",
      "receivedAt": "2026-10-01T09:40:00Z"
    },
    {
      "recordId": "proc_pending",
      "scope": {
        "provider": "stripe",
        "account": "acct_example_001",
        "subscription": "orders-subscription",
        "consumer": "order-worker"
      },
      "eventKey": "evt_pending",
      "timestamp": "2026-10-01T11:00:00Z",
      "state": "pending",
      "receivedAt": "2026-10-01T10:59:00Z"
    },
    {
      "recordId": "proc_orphan",
      "scope": {
        "provider": "stripe",
        "account": "acct_example_001",
        "subscription": "orders-subscription",
        "consumer": "order-worker"
      },
      "eventKey": "evt_orphan",
      "timestamp": "2026-10-01T10:11:00Z",
      "state": "succeeded",
      "receivedAt": "2026-10-01T10:10:00Z"
    },
    {
      "recordId": "proc_future",
      "scope": {
        "provider": "stripe",
        "account": "acct_example_001",
        "subscription": "orders-subscription",
        "consumer": "order-worker"
      },
      "eventKey": "evt_future",
      "timestamp": "2026-10-01T11:05:00Z",
      "state": "succeeded",
      "receivedAt": "2026-10-01T10:00:00Z"
    }
  ]
}
```

# Actor output Schema

## `dataset` (type: `string`):

One complete report item; the primary paid deliverable.

## `json` (type: `string`):

No description

## `csv` (type: `string`):

No description

## `html` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "asOf": "2026-10-01T11:00:00Z",
    "maxProcessingDelayMinutes": 5,
    "coverage": [
        {
            "scope": {
                "provider": "stripe",
                "account": "acct_example_001",
                "subscription": "orders-subscription",
                "consumer": "order-worker"
            },
            "delivery": {
                "from": "2026-10-01T09:00:00Z",
                "to": "2026-10-01T11:00:00Z",
                "complete": true
            },
            "processing": {
                "from": "2026-10-01T09:00:00Z",
                "to": "2026-10-01T11:00:00Z",
                "complete": true
            }
        },
        {
            "scope": {
                "provider": "github",
                "account": "example-repo",
                "subscription": "deployment-subscription",
                "consumer": "deploy-worker"
            },
            "delivery": {
                "from": "2026-10-01T09:00:00Z",
                "to": "2026-10-01T11:00:00Z",
                "complete": true
            },
            "processing": {
                "from": "2026-10-01T09:00:00Z",
                "to": "2026-10-01T11:00:00Z",
                "complete": false
            }
        }
    ],
    "deliveries": [
        {
            "attemptId": "del_retry_01",
            "scope": {
                "provider": "stripe",
                "account": "acct_example_001",
                "subscription": "orders-subscription",
                "consumer": "order-worker"
            },
            "eventKey": "evt_recovered",
            "timestamp": "2026-10-01T09:10:00Z",
            "outcome": "failed",
            "httpStatus": 503
        },
        {
            "attemptId": "del_retry_02",
            "scope": {
                "provider": "stripe",
                "account": "acct_example_001",
                "subscription": "orders-subscription",
                "consumer": "order-worker"
            },
            "eventKey": "evt_recovered",
            "timestamp": "2026-10-01T09:11:00Z",
            "outcome": "acknowledged",
            "httpStatus": 200
        },
        {
            "attemptId": "del_gap",
            "scope": {
                "provider": "stripe",
                "account": "acct_example_001",
                "subscription": "orders-subscription",
                "consumer": "order-worker"
            },
            "eventKey": "evt_ack_gap",
            "timestamp": "2026-10-01T09:30:00Z",
            "outcome": "acknowledged",
            "httpStatus": 200
        },
        {
            "attemptId": "del_repeat",
            "scope": {
                "provider": "stripe",
                "account": "acct_example_001",
                "subscription": "orders-subscription",
                "consumer": "order-worker"
            },
            "eventKey": "evt_two_successes",
            "timestamp": "2026-10-01T09:40:00Z",
            "outcome": "acknowledged",
            "httpStatus": 200
        },
        {
            "attemptId": "del_pending",
            "scope": {
                "provider": "stripe",
                "account": "acct_example_001",
                "subscription": "orders-subscription",
                "consumer": "order-worker"
            },
            "eventKey": "evt_pending",
            "timestamp": "2026-10-01T10:59:00Z",
            "outcome": "acknowledged",
            "httpStatus": 200
        },
        {
            "attemptId": "del_partial",
            "scope": {
                "provider": "github",
                "account": "example-repo",
                "subscription": "deployment-subscription",
                "consumer": "deploy-worker"
            },
            "eventKey": "evt_partial",
            "timestamp": "2026-10-01T09:50:00Z",
            "outcome": "acknowledged",
            "httpStatus": 200
        },
        {
            "attemptId": "del_future",
            "scope": {
                "provider": "stripe",
                "account": "acct_example_001",
                "subscription": "orders-subscription",
                "consumer": "order-worker"
            },
            "eventKey": "evt_future",
            "timestamp": "2026-10-01T10:00:00Z",
            "outcome": "acknowledged",
            "httpStatus": 200
        },
        {
            "attemptId": "del_retry_02",
            "scope": {
                "provider": "stripe",
                "account": "acct_example_001",
                "subscription": "orders-subscription",
                "consumer": "order-worker"
            },
            "eventKey": "evt_recovered",
            "timestamp": "2026-10-01T09:11:00Z",
            "outcome": "acknowledged",
            "httpStatus": 200
        }
    ],
    "processing": [
        {
            "recordId": "proc_failed",
            "scope": {
                "provider": "stripe",
                "account": "acct_example_001",
                "subscription": "orders-subscription",
                "consumer": "order-worker"
            },
            "eventKey": "evt_recovered",
            "timestamp": "2026-10-01T09:11:30Z",
            "state": "failed",
            "receivedAt": "2026-10-01T09:11:00Z"
        },
        {
            "recordId": "proc_recovered",
            "scope": {
                "provider": "stripe",
                "account": "acct_example_001",
                "subscription": "orders-subscription",
                "consumer": "order-worker"
            },
            "eventKey": "evt_recovered",
            "timestamp": "2026-10-01T09:12:00Z",
            "state": "succeeded",
            "receivedAt": "2026-10-01T09:11:00Z"
        },
        {
            "recordId": "proc_repeat_01",
            "scope": {
                "provider": "stripe",
                "account": "acct_example_001",
                "subscription": "orders-subscription",
                "consumer": "order-worker"
            },
            "eventKey": "evt_two_successes",
            "timestamp": "2026-10-01T09:41:00Z",
            "state": "succeeded",
            "receivedAt": "2026-10-01T09:40:00Z"
        },
        {
            "recordId": "proc_repeat_02",
            "scope": {
                "provider": "stripe",
                "account": "acct_example_001",
                "subscription": "orders-subscription",
                "consumer": "order-worker"
            },
            "eventKey": "evt_two_successes",
            "timestamp": "2026-10-01T09:42:00Z",
            "state": "succeeded",
            "receivedAt": "2026-10-01T09:40:00Z"
        },
        {
            "recordId": "proc_pending",
            "scope": {
                "provider": "stripe",
                "account": "acct_example_001",
                "subscription": "orders-subscription",
                "consumer": "order-worker"
            },
            "eventKey": "evt_pending",
            "timestamp": "2026-10-01T11:00:00Z",
            "state": "pending",
            "receivedAt": "2026-10-01T10:59:00Z"
        },
        {
            "recordId": "proc_orphan",
            "scope": {
                "provider": "stripe",
                "account": "acct_example_001",
                "subscription": "orders-subscription",
                "consumer": "order-worker"
            },
            "eventKey": "evt_orphan",
            "timestamp": "2026-10-01T10:11:00Z",
            "state": "succeeded",
            "receivedAt": "2026-10-01T10:10:00Z"
        },
        {
            "recordId": "proc_future",
            "scope": {
                "provider": "stripe",
                "account": "acct_example_001",
                "subscription": "orders-subscription",
                "consumer": "order-worker"
            },
            "eventKey": "evt_future",
            "timestamp": "2026-10-01T11:05:00Z",
            "state": "succeeded",
            "receivedAt": "2026-10-01T10:00:00Z"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("h_murdock/webhook-processing-reconciliation").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "asOf": "2026-10-01T11:00:00Z",
    "maxProcessingDelayMinutes": 5,
    "coverage": [
        {
            "scope": {
                "provider": "stripe",
                "account": "acct_example_001",
                "subscription": "orders-subscription",
                "consumer": "order-worker",
            },
            "delivery": {
                "from": "2026-10-01T09:00:00Z",
                "to": "2026-10-01T11:00:00Z",
                "complete": True,
            },
            "processing": {
                "from": "2026-10-01T09:00:00Z",
                "to": "2026-10-01T11:00:00Z",
                "complete": True,
            },
        },
        {
            "scope": {
                "provider": "github",
                "account": "example-repo",
                "subscription": "deployment-subscription",
                "consumer": "deploy-worker",
            },
            "delivery": {
                "from": "2026-10-01T09:00:00Z",
                "to": "2026-10-01T11:00:00Z",
                "complete": True,
            },
            "processing": {
                "from": "2026-10-01T09:00:00Z",
                "to": "2026-10-01T11:00:00Z",
                "complete": False,
            },
        },
    ],
    "deliveries": [
        {
            "attemptId": "del_retry_01",
            "scope": {
                "provider": "stripe",
                "account": "acct_example_001",
                "subscription": "orders-subscription",
                "consumer": "order-worker",
            },
            "eventKey": "evt_recovered",
            "timestamp": "2026-10-01T09:10:00Z",
            "outcome": "failed",
            "httpStatus": 503,
        },
        {
            "attemptId": "del_retry_02",
            "scope": {
                "provider": "stripe",
                "account": "acct_example_001",
                "subscription": "orders-subscription",
                "consumer": "order-worker",
            },
            "eventKey": "evt_recovered",
            "timestamp": "2026-10-01T09:11:00Z",
            "outcome": "acknowledged",
            "httpStatus": 200,
        },
        {
            "attemptId": "del_gap",
            "scope": {
                "provider": "stripe",
                "account": "acct_example_001",
                "subscription": "orders-subscription",
                "consumer": "order-worker",
            },
            "eventKey": "evt_ack_gap",
            "timestamp": "2026-10-01T09:30:00Z",
            "outcome": "acknowledged",
            "httpStatus": 200,
        },
        {
            "attemptId": "del_repeat",
            "scope": {
                "provider": "stripe",
                "account": "acct_example_001",
                "subscription": "orders-subscription",
                "consumer": "order-worker",
            },
            "eventKey": "evt_two_successes",
            "timestamp": "2026-10-01T09:40:00Z",
            "outcome": "acknowledged",
            "httpStatus": 200,
        },
        {
            "attemptId": "del_pending",
            "scope": {
                "provider": "stripe",
                "account": "acct_example_001",
                "subscription": "orders-subscription",
                "consumer": "order-worker",
            },
            "eventKey": "evt_pending",
            "timestamp": "2026-10-01T10:59:00Z",
            "outcome": "acknowledged",
            "httpStatus": 200,
        },
        {
            "attemptId": "del_partial",
            "scope": {
                "provider": "github",
                "account": "example-repo",
                "subscription": "deployment-subscription",
                "consumer": "deploy-worker",
            },
            "eventKey": "evt_partial",
            "timestamp": "2026-10-01T09:50:00Z",
            "outcome": "acknowledged",
            "httpStatus": 200,
        },
        {
            "attemptId": "del_future",
            "scope": {
                "provider": "stripe",
                "account": "acct_example_001",
                "subscription": "orders-subscription",
                "consumer": "order-worker",
            },
            "eventKey": "evt_future",
            "timestamp": "2026-10-01T10:00:00Z",
            "outcome": "acknowledged",
            "httpStatus": 200,
        },
        {
            "attemptId": "del_retry_02",
            "scope": {
                "provider": "stripe",
                "account": "acct_example_001",
                "subscription": "orders-subscription",
                "consumer": "order-worker",
            },
            "eventKey": "evt_recovered",
            "timestamp": "2026-10-01T09:11:00Z",
            "outcome": "acknowledged",
            "httpStatus": 200,
        },
    ],
    "processing": [
        {
            "recordId": "proc_failed",
            "scope": {
                "provider": "stripe",
                "account": "acct_example_001",
                "subscription": "orders-subscription",
                "consumer": "order-worker",
            },
            "eventKey": "evt_recovered",
            "timestamp": "2026-10-01T09:11:30Z",
            "state": "failed",
            "receivedAt": "2026-10-01T09:11:00Z",
        },
        {
            "recordId": "proc_recovered",
            "scope": {
                "provider": "stripe",
                "account": "acct_example_001",
                "subscription": "orders-subscription",
                "consumer": "order-worker",
            },
            "eventKey": "evt_recovered",
            "timestamp": "2026-10-01T09:12:00Z",
            "state": "succeeded",
            "receivedAt": "2026-10-01T09:11:00Z",
        },
        {
            "recordId": "proc_repeat_01",
            "scope": {
                "provider": "stripe",
                "account": "acct_example_001",
                "subscription": "orders-subscription",
                "consumer": "order-worker",
            },
            "eventKey": "evt_two_successes",
            "timestamp": "2026-10-01T09:41:00Z",
            "state": "succeeded",
            "receivedAt": "2026-10-01T09:40:00Z",
        },
        {
            "recordId": "proc_repeat_02",
            "scope": {
                "provider": "stripe",
                "account": "acct_example_001",
                "subscription": "orders-subscription",
                "consumer": "order-worker",
            },
            "eventKey": "evt_two_successes",
            "timestamp": "2026-10-01T09:42:00Z",
            "state": "succeeded",
            "receivedAt": "2026-10-01T09:40:00Z",
        },
        {
            "recordId": "proc_pending",
            "scope": {
                "provider": "stripe",
                "account": "acct_example_001",
                "subscription": "orders-subscription",
                "consumer": "order-worker",
            },
            "eventKey": "evt_pending",
            "timestamp": "2026-10-01T11:00:00Z",
            "state": "pending",
            "receivedAt": "2026-10-01T10:59:00Z",
        },
        {
            "recordId": "proc_orphan",
            "scope": {
                "provider": "stripe",
                "account": "acct_example_001",
                "subscription": "orders-subscription",
                "consumer": "order-worker",
            },
            "eventKey": "evt_orphan",
            "timestamp": "2026-10-01T10:11:00Z",
            "state": "succeeded",
            "receivedAt": "2026-10-01T10:10:00Z",
        },
        {
            "recordId": "proc_future",
            "scope": {
                "provider": "stripe",
                "account": "acct_example_001",
                "subscription": "orders-subscription",
                "consumer": "order-worker",
            },
            "eventKey": "evt_future",
            "timestamp": "2026-10-01T11:05:00Z",
            "state": "succeeded",
            "receivedAt": "2026-10-01T10:00:00Z",
        },
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("h_murdock/webhook-processing-reconciliation").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "asOf": "2026-10-01T11:00:00Z",
  "maxProcessingDelayMinutes": 5,
  "coverage": [
    {
      "scope": {
        "provider": "stripe",
        "account": "acct_example_001",
        "subscription": "orders-subscription",
        "consumer": "order-worker"
      },
      "delivery": {
        "from": "2026-10-01T09:00:00Z",
        "to": "2026-10-01T11:00:00Z",
        "complete": true
      },
      "processing": {
        "from": "2026-10-01T09:00:00Z",
        "to": "2026-10-01T11:00:00Z",
        "complete": true
      }
    },
    {
      "scope": {
        "provider": "github",
        "account": "example-repo",
        "subscription": "deployment-subscription",
        "consumer": "deploy-worker"
      },
      "delivery": {
        "from": "2026-10-01T09:00:00Z",
        "to": "2026-10-01T11:00:00Z",
        "complete": true
      },
      "processing": {
        "from": "2026-10-01T09:00:00Z",
        "to": "2026-10-01T11:00:00Z",
        "complete": false
      }
    }
  ],
  "deliveries": [
    {
      "attemptId": "del_retry_01",
      "scope": {
        "provider": "stripe",
        "account": "acct_example_001",
        "subscription": "orders-subscription",
        "consumer": "order-worker"
      },
      "eventKey": "evt_recovered",
      "timestamp": "2026-10-01T09:10:00Z",
      "outcome": "failed",
      "httpStatus": 503
    },
    {
      "attemptId": "del_retry_02",
      "scope": {
        "provider": "stripe",
        "account": "acct_example_001",
        "subscription": "orders-subscription",
        "consumer": "order-worker"
      },
      "eventKey": "evt_recovered",
      "timestamp": "2026-10-01T09:11:00Z",
      "outcome": "acknowledged",
      "httpStatus": 200
    },
    {
      "attemptId": "del_gap",
      "scope": {
        "provider": "stripe",
        "account": "acct_example_001",
        "subscription": "orders-subscription",
        "consumer": "order-worker"
      },
      "eventKey": "evt_ack_gap",
      "timestamp": "2026-10-01T09:30:00Z",
      "outcome": "acknowledged",
      "httpStatus": 200
    },
    {
      "attemptId": "del_repeat",
      "scope": {
        "provider": "stripe",
        "account": "acct_example_001",
        "subscription": "orders-subscription",
        "consumer": "order-worker"
      },
      "eventKey": "evt_two_successes",
      "timestamp": "2026-10-01T09:40:00Z",
      "outcome": "acknowledged",
      "httpStatus": 200
    },
    {
      "attemptId": "del_pending",
      "scope": {
        "provider": "stripe",
        "account": "acct_example_001",
        "subscription": "orders-subscription",
        "consumer": "order-worker"
      },
      "eventKey": "evt_pending",
      "timestamp": "2026-10-01T10:59:00Z",
      "outcome": "acknowledged",
      "httpStatus": 200
    },
    {
      "attemptId": "del_partial",
      "scope": {
        "provider": "github",
        "account": "example-repo",
        "subscription": "deployment-subscription",
        "consumer": "deploy-worker"
      },
      "eventKey": "evt_partial",
      "timestamp": "2026-10-01T09:50:00Z",
      "outcome": "acknowledged",
      "httpStatus": 200
    },
    {
      "attemptId": "del_future",
      "scope": {
        "provider": "stripe",
        "account": "acct_example_001",
        "subscription": "orders-subscription",
        "consumer": "order-worker"
      },
      "eventKey": "evt_future",
      "timestamp": "2026-10-01T10:00:00Z",
      "outcome": "acknowledged",
      "httpStatus": 200
    },
    {
      "attemptId": "del_retry_02",
      "scope": {
        "provider": "stripe",
        "account": "acct_example_001",
        "subscription": "orders-subscription",
        "consumer": "order-worker"
      },
      "eventKey": "evt_recovered",
      "timestamp": "2026-10-01T09:11:00Z",
      "outcome": "acknowledged",
      "httpStatus": 200
    }
  ],
  "processing": [
    {
      "recordId": "proc_failed",
      "scope": {
        "provider": "stripe",
        "account": "acct_example_001",
        "subscription": "orders-subscription",
        "consumer": "order-worker"
      },
      "eventKey": "evt_recovered",
      "timestamp": "2026-10-01T09:11:30Z",
      "state": "failed",
      "receivedAt": "2026-10-01T09:11:00Z"
    },
    {
      "recordId": "proc_recovered",
      "scope": {
        "provider": "stripe",
        "account": "acct_example_001",
        "subscription": "orders-subscription",
        "consumer": "order-worker"
      },
      "eventKey": "evt_recovered",
      "timestamp": "2026-10-01T09:12:00Z",
      "state": "succeeded",
      "receivedAt": "2026-10-01T09:11:00Z"
    },
    {
      "recordId": "proc_repeat_01",
      "scope": {
        "provider": "stripe",
        "account": "acct_example_001",
        "subscription": "orders-subscription",
        "consumer": "order-worker"
      },
      "eventKey": "evt_two_successes",
      "timestamp": "2026-10-01T09:41:00Z",
      "state": "succeeded",
      "receivedAt": "2026-10-01T09:40:00Z"
    },
    {
      "recordId": "proc_repeat_02",
      "scope": {
        "provider": "stripe",
        "account": "acct_example_001",
        "subscription": "orders-subscription",
        "consumer": "order-worker"
      },
      "eventKey": "evt_two_successes",
      "timestamp": "2026-10-01T09:42:00Z",
      "state": "succeeded",
      "receivedAt": "2026-10-01T09:40:00Z"
    },
    {
      "recordId": "proc_pending",
      "scope": {
        "provider": "stripe",
        "account": "acct_example_001",
        "subscription": "orders-subscription",
        "consumer": "order-worker"
      },
      "eventKey": "evt_pending",
      "timestamp": "2026-10-01T11:00:00Z",
      "state": "pending",
      "receivedAt": "2026-10-01T10:59:00Z"
    },
    {
      "recordId": "proc_orphan",
      "scope": {
        "provider": "stripe",
        "account": "acct_example_001",
        "subscription": "orders-subscription",
        "consumer": "order-worker"
      },
      "eventKey": "evt_orphan",
      "timestamp": "2026-10-01T10:11:00Z",
      "state": "succeeded",
      "receivedAt": "2026-10-01T10:10:00Z"
    },
    {
      "recordId": "proc_future",
      "scope": {
        "provider": "stripe",
        "account": "acct_example_001",
        "subscription": "orders-subscription",
        "consumer": "order-worker"
      },
      "eventKey": "evt_future",
      "timestamp": "2026-10-01T11:05:00Z",
      "state": "succeeded",
      "receivedAt": "2026-10-01T10:00:00Z"
    }
  ]
}' |
apify call h_murdock/webhook-processing-reconciliation --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,h_murdock/webhook-processing-reconciliation"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/Nvk8ErFzrNn2hgP96/builds/EpvKSz7qKFVCcj2bj/openapi.json
