# Atlassian & Stripe: Subprocessor Change Monitor (`felixgoldwin/atlassian-stripe-subprocessor-monitor`) Actor

Track changes in Atlassian and Stripe subprocessor, service-provider and affiliate tables. Compare supplied snapshots for added, removed and changed entries with before/after evidence and source links. Unofficial; Stripe countries identify entities, not processing locations.

- **URL**: https://apify.com/felixgoldwin/atlassian-stripe-subprocessor-monitor.md
- **Developed by:** [Felix GoldWin](https://apify.com/felixgoldwin) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 scoped-company evidences

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

## Atlassian & Stripe Vendor Change Monitor

Track source-backed changes to the two supported vendors' published organization tables. Each run emits normalized company evidence with exact before/after objects, source links, observation time, and complete-scan diagnostics. Supply a previous `SNAPSHOT` to compare; no global or cross-user state is used.

### Supported coverage

| Source | Supported tables | Meaning of location |
| --- | --- | --- |
| [Atlassian](https://www.atlassian.com/legal/sub-processors) | Third-party subprocessors, Government Cloud subprocessors, Atlassian Group subprocessors | Published processing location, including regions and qualifications |
| [Stripe](https://stripe.com/legal/service-providers) | Sub-processors, service providers, affiliates | Published **entity country**, not proof of processing location |

These are bounded source-specific adapters. They do not crawl linked security pages, inaccessible trust centers, arbitrary vendors, or customer accounts. Stripe's table labels remain `sub-processors`, `service providers`, and `affiliates`; they are not relabeled into one legal category. Source cells can list a category or multiple organizations; that exact company-cell text remains one record.

Company identity is the exact normalized company text **within its table section/group**. The same organization appearing in multiple groups produces separate records. Atlassian rowspan entries and repeated company rows are retained as product/purpose/location entries in their scoped record. A company rename or section move is an added row plus a removed row, not a verified legal-entity change.

This is evidence for human review, not a compliance certification. A listed party may not apply to every customer's services. A removal only means the company text was absent from the same supported page sections; it does not prove the relationship ended. No messages are sent.

### Run and compare

```json
{"vendors":["atlassian","stripe"],"maxResults":200,"maxRequests":10,"maxChargeUsd":0.5}
```

Read the default dataset for `baseline`, `unchanged`, `added`, `changed`, or `removed` rows. `before` and `after` preserve full normalized table evidence without silent truncation. Whitespace, mobile labels, markup and hyperlink targets are excluded; security-measure links are not tracked. `changedFields` indicates which normalized fields differ; entries contain `products`, `purpose`, `location`, and `personalDataCategories`. The latter is a published category description, never individual personal data. Missing cells stay null.

The key-value store `OUTPUT` records scan completeness, exact source URLs, final same-origin URLs, response SHA-256, source date and its label, request/byte counts, budget, and source limitations. Atlassian publishes an **Effective Starting** date; Stripe publishes **Last updated**. Neither is replaced with the retrieval date. A date-only edit appears in diagnostics/snapshot metadata, not as a company change.

Download `SNAPSHOT` and pass its JSON as `previousSnapshot` on the next run. It must use the same vendor/parser scope and contain only your own complete snapshots. Caller evidence is structurally validated and explicitly labeled as not independently authenticated. No prior URLs are fetched. Keep the last verified complete snapshot for each vendor if a later scan fails; failed vendors are omitted from the new snapshot. There is no automatic merge with a previous run.

Unknown headers, missing tables, empty groups, malformed spans, duplicate entries, source denials, exceeded bounds, or changed section coverage suppress that vendor's comparison and reusable snapshot. If a legitimate group is added or removed, review and update the parser/scope before establishing a new baseline. A full vendor's rows must fit the result and charge capacity; that vendor is otherwise withheld. Other vendors can still succeed. Always check both `complete` and each diagnostic's `outputComplete`.

### Bounds and billing

Defaults: 200 dataset rows; 10 HTTP requests including redirects/retries; 120 seconds of source work; 20 seconds/request; 1.5 MB/response; 4 MB total response bodies; 2 retries. Hard maxima: 1,000 rows, 20 requests, 300 seconds source work, 30 seconds/request, 3 MB/response and 6 MB total. Input is capped at 3 MB, reusable snapshots at 2 MB, and each parser at 300 scoped companies, 50 entries/company, and 10,000 characters/cell. Overlong evidence fails instead of truncating. Source work is sequential; SDK initialization and dataset storage add runtime. Set Apify's run timeout and charge limits too.

HTTP 403/401 and other access denials stop; no proxy, login, or bypass is used. At most two redirects are accepted and only to the fixed vendor's approved HTTPS legal-page paths. Retry-After over 10 seconds stops. There is no pagination on these complete HTML tables; table/group validation replaces pagination completeness checks.

User-approved listing pricing, **not configured by this source package**: automatic `apify-actor-start` at $0.005 per platform memory unit of up to 1 GB, plus `vendor-evidence-row` at $0.002 per emitted scoped-company row. Baseline, unchanged, added, changed, and removed rows all count. Multiple entries in a scoped company record do not add charges. This unit pays for the recurring complete table check and preserved comparison evidence; it is not a claim that only changed companies cost work. At the observed 140-row baseline, these rates total approximately $0.285 including one start unit. Pages and row counts change.

Runtime reads actual configured prices, honors both the custom cap (default $0.50) and platform capacity, includes prior charges plus any pending automatic start reservation, and refuses positive synthetic dataset-item charges or unknown paid events to prevent double billing. Automatic starts are never manually charged. A zero custom cap prevents source requests, but cannot refund an already automatic platform start. Outside pay-per-event mode the custom cap does not control platform compute/storage costs. Platform deployment and paid billing remain unverified.

### Local development

Node.js 22 or newer:

```sh
npm ci --ignore-scripts
npm test
npm run validate:schema
npm run smoke
npm start
```

`smoke` makes two bounded public page requests and saves only hashes, counts, source diagnostics and a few normalized rows in `artifacts/live-smoke.json`; it does not store source HTML. For `npm start`, place input in `storage/key_value_stores/default/INPUT.json`. See [QA.md](QA.md), [NOTICE.md](NOTICE.md), and [PUBLISHING.md](PUBLISHING.md).

### Hosted verification update — 2026-10-11 UTC

This update supersedes the original builder-only deployment status above. Apify build 0.0.1 succeeded with Node 22. Two owner-account runs at 256 MB, 180 seconds and a $0.30 platform cap each delivered 140 rows from two HTTP requests: 49 Atlassian and 91 Stripe records. Baseline OUTPUT confirmed both vendors complete, outputComplete and reusable snapshots. The repeat run accepted that snapshot and emitted unchanged observations. Peak memory was 83.3 MB across these small tests. Configured listing prices are $0.005 automatic start per up-to-1-GB unit plus $0.002 per emitted scoped-company row; the synthetic paid dataset event is removed. Baseline and unchanged rows are billable. Customer PPE pricing includes platform usage. Runtime used platform_pay_per_event and verified custom-event count increases per row. Owner usage was $0.001 per run, rounded by Console; this is not a customer invoice test or maximum-load guarantee. The listing is unofficial and is not affiliated with Atlassian or Stripe.

# Actor input Schema

## `vendors` (type: `array`):

All recognized tables on the selected pages are scanned; no arbitrary URLs or trust centers.

## `previousSnapshot` (type: `object`):

Paste your own previous SNAPSHOT JSON. Vendor/parser scope must match. No credentials or private data. Whole input maximum 3 MB.

## `maxResults` (type: `integer`):

Includes baseline, unchanged, added, changed and removed rows. Each vendor is withheld if its whole comparison does not fit.

## `maxRequests` (type: `integer`):

Global bound including same-origin redirects and retries.

## `maxRunSeconds` (type: `integer`):

Bounds source fetching and parsing; SDK startup and dataset writes are additional.

## `requestTimeoutSeconds` (type: `integer`):

Includes response-body streaming.

## `maxResponseBytes` (type: `integer`):

Decompressed streamed HTML bound; source HTML is never stored.

## `maxTotalBytes` (type: `integer`):

Global downloaded HTML bound.

## `maxRetries` (type: `integer`):

429, server and network errors only. No access-denial retries. Retry-After beyond 10 seconds stops.

## `maxChargeUsd` (type: `number`):

Conservative PPE cap includes automatic start units and prior event charges. Zero stops source work. Platform charge cap also applies. Does not cap non-PPE compute/storage charges.

## Actor input object example

```json
{
  "vendors": [
    "atlassian",
    "stripe"
  ],
  "maxResults": 200,
  "maxRequests": 10,
  "maxRunSeconds": 120,
  "requestTimeoutSeconds": 20,
  "maxResponseBytes": 1500000,
  "maxTotalBytes": 4000000,
  "maxRetries": 2,
  "maxChargeUsd": 0.5
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `diagnostics` (type: `string`):

No description

## `snapshot` (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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("felixgoldwin/atlassian-stripe-subprocessor-monitor").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("felixgoldwin/atlassian-stripe-subprocessor-monitor").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 '{}' |
apify call felixgoldwin/atlassian-stripe-subprocessor-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,felixgoldwin/atlassian-stripe-subprocessor-monitor"
        }
    }
}
```

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/PBhuHGeXQV8SwQqCV/builds/LQhtJZtp9u5gumqpe/openapi.json
