# Amazon Promo Leak Monitor - Flag Leaks with Proof (`steadyworks/amazon-promo-leak-monitor`) Actor

Monitor Amazon promo and coupon codes against public leak sources with allow-list comparison and evidence rows for every flag.

- **URL**: https://apify.com/steadyworks/amazon-promo-leak-monitor.md
- **Developed by:** [steadyworks](https://apify.com/steadyworks) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $18.00 / 1,000 verified leak or stack alerts

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Amazon Promo Leak Monitor - Flag Leaks with Proof

Extract leaked Amazon promo and coupon codes from public deal pages into evidence rows. Paste one seller allow-list in, get one row per verified leak or stack abuse with source URL, timestamps, and a verify-before-act notice — clean polls stay silent at $0.

> Click **Try for free** — input opens prefilled. Start as-is, check rows, then raise the allow-list.

### What it does

Monitors your private, influencer, and email promo codes against public coupon and deal pages, and flags every allow-list match as a typed evidence row. Built for Amazon sellers who run promo-code campaigns and need proof — not rumors — before acting.

- **Allow-list leak flags** — private or email codes spotted on public pages, one row per code with evidence URL
- **Stack-abuse flags** — code-plus-coupon combinations with worst-case stack math attached
- **Clean polls stay silent** — no code visible means zero rows at $0, never a guessed price
- **Expired codes ignored** — expired allow-list entries are decorative and never bill
- **Evidence on every row** — source URL, first-seen and checked timestamps, verify-before-act notice
- **Per-run spend cap** — a dollar cap that stops spend and holds state when tripped
- **Free one-shot check** — one code plus one deal page, $0, before you commit to the full watch

### Quick start

1. Click **Try for free** — the input opens with a demo allow-list prefilled (a $0 first run).
2. Replace the demo ASINs and codes with your own allow-list (keep `checkHours: 6`).
3. Leave `observed` empty for the first run: it returns zero rows, $0, quiet — proof the actor boots.
4. Click **Save & Start**, then open the **Dataset** tab for evidence rows and the **Key-value store** `OUTPUT` record for the run summary.
5. Re-run with your full allow-list: every caught leak bills $0.03 per row, clean polls stay $0, capped at $3 per run.

### Input

Minimal copy-paste input (required fields only, matches the Console prefill exactly):

```json
{
  "configId": "demo-seller-01",
  "brandAsins": ["B012345678", "B0ABCDEFGH"],
  "groupCodes": [
    { "code": "SAVE20", "scope": "private", "expiresAt": "2027-06-01T00:00:00.000Z" },
    { "code": "INFLU10", "scope": "influencer", "expiresAt": "2027-06-01T00:00:00.000Z" }
  ],
  "checkHours": 6,
  "stackWatch": true,
  "maxTotalChargeUsd": 3
}
```

Full input with all optional fields:

```json
{
  "configId": "demo-seller-01",
  "brandAsins": ["B012345678", "B0ABCDEFGH"],
  "groupCodes": [
    { "code": "SAVE20", "scope": "private", "expiresAt": "2027-06-01T00:00:00.000Z" },
    { "code": "INFLU10", "scope": "influencer", "expiresAt": "2027-06-01T00:00:00.000Z" }
  ],
  "checkHours": 6,
  "stackWatch": true,
  "maxTotalChargeUsd": 3,
  "capMode": "capped",
  "sellerRef": "demo-seller-ref",
  "observed": {
    "checkedAt": "2026-09-28T12:00:00.000Z",
    "observations": [
      { "code": "SAVE20", "codeScope": "private", "sourceUrl": "https://deals.example.invalid/t/save20-leak-4821" }
    ]
  }
}
```

| field | type | required | default | units | limits |
|---|---|---|---|---|---|
| `configId` | string | yes | — | — | lowercase letters, digits, dashes; 1–64 chars; scope/state key, use a fresh value per watch list |
| `brandAsins` | array of string | yes | — | ASINs | 1–30 items; each `B0` + 8 uppercase letters/digits |
| `groupCodes` | array of object | yes | — | codes | max 50; each needs `code` (1–64 chars), `scope` (`email`, `influencer`, `private`), `expiresAt` (RFC 3339 UTC) |
| `checkHours` | integer | yes | `6` | hours | only `6` accepted (fixed 6-hour sweep cadence) |
| `stackWatch` | boolean | yes | `true` | — | `false` = leak flags only, stack math suppressed |
| `maxTotalChargeUsd` | number | yes | `3` | USD | 0–3; per-run spend cap and cost ceiling |
| `capMode` | enum | no | `capped` | — | `capped` (default, max $3 for up to 100 rows) or `complete-input` (entire allow-list; worst case $Y = codes × $0.03 quoted before any charge, never above the frozen $1.50 ceiling) |
| `sellerRef` | string | no | — | — | max 64 chars; opaque reference, never a credential |
| `observed` | object | no | — | — | frozen observation replay for smoke/demo runs only (`checkedAt` + `observations` of `code`/`codeScope`/`sourceUrl` plus optional `couponPercent`/`codePercent`); omit for the quiet boot |

Job-titled recipes (one line each):

- `quiet boot` — the minimal JSON above with no `observed`: zero rows, $0, quiet
- `seller leak audit` — minimal JSON plus `observed` with your frozen observation set: leak + stack rows with proof
- `leak-only watch` — same as audit with `"stackWatch": false`: stack math suppressed, leaks only
- `expired-code cleanup check` — include an expired entry in `groupCodes`: it is ignored and never bills

### Output

Every run writes one summary record to the default **key-value store** (`OUTPUT` key: rows, per-config report, billing tally, typed misses, quiet flag) and mirrors each verified leak/stack row as a typed evidence item to the **default dataset** (quiet runs write zero dataset rows).

Alias map: KV `rowType` means dataset `leakClass` (`leak` = allow-list code seen off-list with evidence, `stack` = code plus verified coupon with worst-case math); KV `sourceUrl` means dataset `evidenceUrl` (the same evidence page URL). Canonical for all new keys is `leakClass` + `evidenceUrl`.

Dataset item fields (one item per verified flag):

| field | type | notes |
|---|---|---|
| `rowId` | string | stable row key `{configId}:{code}:{codeScope}` |
| `sellerRef` | string | your opaque reference echoed back |
| `asin` | string | representative brand ASIN (first allow-list entry) |
| `code` | string | promo code text exactly as observed |
| `codeScope` | enum | `email`, `influencer`, or `private` |
| `leakClass` | enum | `leak` or `stack` |
| `evidenceUrl` | string | public page where the code was seen |
| `firstSeenAt` | string | first-seen timestamp (UTC) |
| `checkedAt` | string | verification timestamp (UTC) |
| `notice` | string | verify-before-act notice |
| `billableEvent` | string | `verified-leak-or-stack-alert` |
| `billedAmountUsd` | number | `0.03` per row |
| `discountDepth` | number | stack rows only; observed discount percent, never estimated |
| `worstCaseStackMath` | string | stack rows only; worst-case combination math |

Real example rows (shortened for viewing — timestamps and notice text abridged):

```json
{ "rowId": "demo-seller-01:SAVE20:private", "code": "SAVE20", "codeScope": "private", "leakClass": "leak", "evidenceUrl": "https://deals.example.invalid/t/save20-leak-4821", "firstSeenAt": "2026-09-28T06:00:00.000Z", "checkedAt": "2026-09-28T12:00:00.000Z", "notice": "allow-list leak with evidence URL — verify-before-act", "billableEvent": "verified-leak-or-stack-alert", "billedAmountUsd": 0.03 }
```

<details>
<summary>Full example: KV OUTPUT row + stack row with worst-case math</summary>

```json
{
  "rowId": "demo-seller-01:SAVE20:private",
  "rowType": "leak",
  "code": "SAVE20",
  "codeScope": "private",
  "onAllowList": true,
  "sourceUrl": "https://deals.example.invalid/t/save20-leak-4821",
  "firstSeenAt": "2026-09-28T06:00:00.000Z",
  "checkedAt": "2026-09-28T12:00:00.000Z",
  "notice": "allow-list leak with evidence URL, checked at 2026-09-28T12:00:00.000Z - verify-before-act",
  "billable": true,
  "billableEvent": "verified-leak-or-stack-alert",
  "unitPriceUsd": 0.03
}
```

```json
{
  "rowId": "demo-seller-01:INFLU10:influencer",
  "rowType": "stack",
  "code": "INFLU10",
  "codeScope": "influencer",
  "onAllowList": true,
  "sourceUrl": "https://deals.example.invalid/c/influ10-stack-9917",
  "firstSeenAt": "2026-09-28T06:00:00.000Z",
  "checkedAt": "2026-09-28T12:00:00.000Z",
  "notice": "worst-case stack math with evidence URL, checked at 2026-09-28T12:00:00.000Z - verify-before-act",
  "discountDepth": 10,
  "worstCaseStackMath": "code 10% + coupon 10% stack worst-case 19% (1-(0.90*0.90))",
  "billable": true,
  "billableEvent": "verified-leak-or-stack-alert",
  "unitPriceUsd": 0.03
}
```

</details>

*Rows shortened for viewing. The KV `OUTPUT` record carries `sourceUrl` per row; the dataset mirror carries the same URL as `evidenceUrl` plus `sellerRef`, `asin`, and the per-row billing stamp. Walled, dead, or timed-out sources are reported as typed misses in the `OUTPUT` record — never a guessed row. Malformed input is rejected at the schema gate before any spend; a run with no loaded config reports a rejection detail and bills nothing.*

### How much will it cost?

**From $30.00 per 1,000 verified rows.** The billable event is `verified-leak-or-stack-alert`: one unit bills per evidence row published. Clean polls, typed misses, expired-code observations, and seed runs emit zero rows and bill $0.

| plan | $ per 1,000 verified rows |
|---|---|
| Free / Starter / Scale / Business | $30.00 / $30.00 / $30.00 / $30.00 |

Single meter on all plans; the Console Pricing tab is authoritative.

Worked math:

- Small run, 2 flags (1 leak + 1 stack): 2 × $0.03 = **$0.06 per run**
- Quiet week, 0 new flags: **$0.00** (silence is the correct output, not a failure)
- Busy run, 10 flags: 10 × $0.03 = **$0.30**, still far under the cap
- Monthly projection, one sweep a day averaging 1 flag: ~30 rows ≈ **$0.90/mo**
- Worst case per run: the $3 cap holds at most **100 rows per run** — spend stops, state is held, and counts are still published when the cap trips
- Complete-my-input run, full 50-code allow-list: worst case 50 × $0.03 = **$1.50**, quoted before any charge, never above the frozen $1.50 ceiling

Cap, floor, and quiet costs: `maxTotalChargeUsd` (max $3) is the cost ceiling — set it lower to bound any run further. Billing respects the platform max-charge setting and stops on the charge limit. There is no minimum per run beyond the platform floor; failed, empty, and quiet runs are not billed for rows. Quiet costs disclosed: each run start carries the platform actor-start event plus standard compute units — row charges ($0.03 each) apply only to published evidence rows.

Completeness mode (`capMode`): `capped` (default) keeps the promise above verbatim — max $3 for up to 100 rows, trip lands SUCCEEDED with counts only. `complete-input` processes your entire allow-list in one run: the run's first log line and the OUTPUT record quote your actual worst case $Y (your codes × $0.03) before anything bills, and spend never exceeds the frozen $1.50 ceiling (50 codes × $0.03 — $Y above $1.50 fails closed to capped). One click, no billing field, no human; your billing pin still lowers any run, and schedules/task runs always run capped. Every trip lands SUCCEEDED with counts only and state held.

`event:verified-leak-or-stack-alert | $/1k 30.00/30.00/30.00/30.00 | includes_usage:true | billed_on_empty:false | caps:[maxTotalChargeUsd] | quiet:[actor-start]`

### Trial

Start free: run once with **1 allow-list code plus 1 deal page** as a one-shot check per watch list — **$0**, no card required. The free check returns the same evidence-row shape as the paid watch, so you can verify the output before spending anything.

- First use per watch list runs the free check ($0, nothing charged, state recorded).
- A second check on the same list runs as the full watch: $0.03 per verified row, clean polls $0, per-run cap $3.00.
- As a yardstick, $5 of platform credit covers about **166 verified rows** at this meter.

> Click **Try for free** — input opens prefilled. Start as-is, check rows, then raise the allow-list.

### Compatibility

Works with any public promo or coupon page you allow-list. Verified live:

- **Private-scope leak flag — lululemon Like New, Oct 2026** — one allow-list leak flagged with proof
- **Influencer-scope stack flag — NVIDIA promo page, Oct 2026** — one stack flagged with proof, worst-case math attached
- **Clean pages stay silent — verified quiet pair, Oct 2026** — no code visible means zero rows at $0, never a guessed price

Not covered: login-walled or bot-walled deal sources, dead or timed-out transports. These return typed misses — never a guessed price. Every flag carries source URL, timestamps, and a verify-before-act notice.

*Not affiliated with NVIDIA or lululemon; third-party names belong to their owners, no endorsement or sponsorship implied.*

### What people use it for

- **Seller promo-leak watch** — daily sweep of your private codes against public coupon pages
- **Influencer-code abuse check** — catch influencer codes stacked with site coupons, with worst-case math
- **Pre-campaign baseline** — quiet boot first, so later runs emit only new leaks
- **Leak-only monitoring** — `stackWatch: false` for sellers who want leaks without stack math
- **Allow-list hygiene** — expired codes surface as ignored, so you can prune them

### What this Actor does NOT do

- Does not change your codes, prices, or listings — read-only comparison with evidence
- Does not read login-walled or bot-walled deal sources — those return typed misses, never guessed rows
- Does not edit Amazon listings or pull codes down — every flag ends with a verify-before-act notice
- Does not guess discount percentages — stack math appears only when both percentages are observed

### Use with schedules, webhooks, API, and MCP

Schedule a daily watch (alert only when new rows appear):

```json
{ "configId": "my-shop-watch", "brandAsins": ["B012345678"], "groupCodes": [{ "code": "SAVE20", "scope": "private", "expiresAt": "2027-06-01T00:00:00.000Z" }], "checkHours": 6, "stackWatch": true, "maxTotalChargeUsd": 3 }
```

Webhook pattern — fire downstream only when rows exist (pseudo-code on the run's `OUTPUT` record):

```js
const output = await keyValueStore.getRecord('OUTPUT');
if (!output.quiet && output.rows.length > 0) await notify(output.rows);
```

Call the API (one-liners):

```bash
curl -X POST "https://api.apify.com/v2/acts/steadyworks~amazon-promo-leak-monitor/runs?token=$APIFY_TOKEN" -H "Content-Type: application/json" -d '{"configId":"my-shop-watch","brandAsins":["B012345678"],"groupCodes":[{"code":"SAVE20","scope":"private","expiresAt":"2027-06-01T00:00:00.000Z"}],"checkHours":6,"stackWatch":true,"maxTotalChargeUsd":3}'
```

```python
run = client.actor("steadyworks/amazon-promo-leak-monitor").call(run_input={...})
rows = run["defaultDatasetId"] and client.dataset(run["defaultDatasetId"]).list_items().items
```

```js
const run = await client.actor('steadyworks/amazon-promo-leak-monitor').call({ ...input });
```

Connect via MCP (agent dispatcher config):

```json
{ "mcpServers": { "apify": { "command": "npx", "args": ["-y", "@apify/mcp-server"], "env": { "APIFY_TOKEN": "<your-token>" } } } }
```

Then call the `steadyworks/amazon-promo-leak-monitor` Actor through the Apify MCP tools with the input above. Note: actor calls return immediately — poll the run or use a webhook for completion, never block longer than ~45 seconds waiting.

### Troubleshooting

| symptom | cause | fix |
|---|---|---|
| 0 rows on first run | Fresh key boots quietly by design (zero rows, $0) | Expected — re-run with the `observed` replay or your live allow-list to see flags |
| 0 rows every run | No code visible on the checked pages (clean poll) | Correct output, billed $0 — verify the observation set covers the right pages |
| Input rejected, run ends immediately | ASIN pattern, `checkHours` not `6`, or missing required field | Match the Input table: ASINs `B0` + 8 chars, `checkHours: 6`, RFC 3339 `expiresAt` |
| Run stops at the spend cap | `maxTotalChargeUsd` tripped (spend stops, state held, counts published) | Lower the allow-list size or raise-and-rerun with a fresh `configId` |
| Expired code never flags | Expired entries are decorative by design | Renew or remove the code; it will never bill |
| Walled/dead source, no row | Login wall, bot wall, or dead transport → typed miss | Check the `OUTPUT` record `misses`; use a public readable page — misses never bill |

### FAQ

**Does this change my data?** No — read-only. It compares your allow-list against observed public pages and writes evidence rows; it never edits listings, codes, or prices.

**How much does one check cost?** The free one-shot check (1 code + 1 deal page) is $0. After that, $0.03 per verified row; a 2-flag run is $0.06; quiet runs are $0; no run exceeds the $3 cap.

**What are the limits?** Up to 30 ASINs and 50 group codes per run; `checkHours` fixed at 6; at most 100 billed rows per run under the $3 cap.

**Does it work behind logins?** No. Login-walled or bot-walled sources return typed misses, never guessed rows.

**What personal data does it process?** None beyond what you supply: promo-code strings, ASINs, and public page URLs. No buyer credentials are ever requested or stored.

**Is scraping these pages allowed?** The actor reads only public pages and never bypasses access controls. Every flag carries a verify-before-act notice — confirm a leak on the live page before acting, and respect each site's terms.

### Legality

Reads public promo and coupon pages only; no login bypass, no credential handling, no personal-data collection. Store names in the Compatibility block belong to their owners — no affiliation, endorsement, or sponsorship implied. Verify each flag on the live page before acting.

### Other Actors you might need

| need | what to do instead |
|---|---|
| One-off single-code check | Run this Actor once with 1 ASIN + 1 code (the free check) |
| Leaks only, no stack math | Same Actor with `"stackWatch": false` (leak-only mode) |
| Restock or price tracking | Search the Apify Store for a restock or price monitor — this Actor covers promo-code leaks only |
| Full-site coupon crawl | This Actor compares an allow-list against observations; it is not a general site crawler |

### Changelog and support

[Changelog](./CHANGELOG.md) — 2026-10-02 entries cover the adoption baseline and the dataset evidence mirror. Questions or wrong-fit reports: use the Issues tab on the Store listing.

# Changelog

This Actor's version history is a separate document: https://apify.com/steadyworks/amazon-promo-leak-monitor/changelog.md

# Actor input Schema

## `brandAsins` (type: `array`):

Seller-typed ASIN allow-list: B0 + 8 uppercase alphanumerics. Max 30.

## `capMode` (type: `string`):

Spend ceiling mode. Capped (default): max $3.00 for up to 100 verified rows at $0.03/row — when the cap is reached, spend stops and counts are still reported. Complete-input: processes your entire allow-list; your worst-case total (codes x $0.03) is quoted before any charge and never exceeds the $1.50 ceiling (50 codes x $0.03) — totals above $1.50 stay capped; your max charge setting still lowers any run; scheduled and saved-task runs always use capped.

## `checkHours` (type: `integer`):

Fixed 6h sweep cadence. Only 6 is accepted.

## `configId` (type: `string`):

Watch-list name: lowercase letters, digits, dashes, max 64 chars. Use a fresh value per watch list.

## `groupCodes` (type: `array`):

Private/influencer/email code groups with expiry. Expired codes are ignored and never bill. Max 50.

## `maxTotalChargeUsd` (type: `number`):

Per-run spend cap, 0-3 USD. When the cap is reached, spend stops and counts are still reported.

## `observed` (type: `object`):

Optional: paste a past observation set to re-check it (checked time plus observations with code, audience, page URL, optional percents). Leave empty for a first check with zero flags and $0. Never live buyer data.

## `sellerRef` (type: `string`):

Seller reference, max 64 chars. Use any label for your shop; never a password or key.

## `stackWatch` (type: `boolean`):

Also flag combined savings when both the code percent and the verified coupon percent are readable.

## Actor input object example

```json
{
  "brandAsins": [
    "B012345678",
    "B0ABCDEFGH"
  ],
  "capMode": "capped",
  "checkHours": 6,
  "configId": "demo-seller-01",
  "groupCodes": [
    {
      "code": "SAVE20",
      "expiresAt": "2027-06-01T00:00:00.000Z",
      "scope": "private"
    },
    {
      "code": "INFLU10",
      "expiresAt": "2027-06-01T00:00:00.000Z",
      "scope": "influencer"
    }
  ],
  "maxTotalChargeUsd": 3,
  "observed": {
    "checkedAt": "2026-09-28T12:00:00.000Z",
    "observations": [
      {
        "code": "SAVE20",
        "codeScope": "private",
        "sourceUrl": "https://deals.example.invalid/t/save20-leak-4821"
      }
    ]
  },
  "sellerRef": "demo-seller-ref",
  "stackWatch": true
}
```

# Actor output Schema

## `findingRows` (type: `string`):

Verified evidence rows (page URL plus first-seen/checked times plus verify-before-act note per row; $0.03 per row). Empty when no flags are found.

## `OUTPUT` (type: `string`):

The run summary record: flagged rows plus totals plus billing. Read each row's page URL for evidence and the totals for the run count and charge.

# 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 = {
    "brandAsins": [
        "B012345678",
        "B0ABCDEFGH"
    ],
    "capMode": "capped",
    "checkHours": 6,
    "configId": "demo-seller-01",
    "groupCodes": [
        {
            "code": "SAVE20",
            "expiresAt": "2027-06-01T00:00:00.000Z",
            "scope": "private"
        },
        {
            "code": "INFLU10",
            "expiresAt": "2027-06-01T00:00:00.000Z",
            "scope": "influencer"
        }
    ],
    "maxTotalChargeUsd": 3,
    "stackWatch": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("steadyworks/amazon-promo-leak-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 = {
    "brandAsins": [
        "B012345678",
        "B0ABCDEFGH",
    ],
    "capMode": "capped",
    "checkHours": 6,
    "configId": "demo-seller-01",
    "groupCodes": [
        {
            "code": "SAVE20",
            "expiresAt": "2027-06-01T00:00:00.000Z",
            "scope": "private",
        },
        {
            "code": "INFLU10",
            "expiresAt": "2027-06-01T00:00:00.000Z",
            "scope": "influencer",
        },
    ],
    "maxTotalChargeUsd": 3,
    "stackWatch": True,
}

# Run the Actor and wait for it to finish
run = client.actor("steadyworks/amazon-promo-leak-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 '{
  "brandAsins": [
    "B012345678",
    "B0ABCDEFGH"
  ],
  "capMode": "capped",
  "checkHours": 6,
  "configId": "demo-seller-01",
  "groupCodes": [
    {
      "code": "SAVE20",
      "expiresAt": "2027-06-01T00:00:00.000Z",
      "scope": "private"
    },
    {
      "code": "INFLU10",
      "expiresAt": "2027-06-01T00:00:00.000Z",
      "scope": "influencer"
    }
  ],
  "maxTotalChargeUsd": 3,
  "stackWatch": true
}' |
apify call steadyworks/amazon-promo-leak-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,steadyworks/amazon-promo-leak-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/cVJK1ck89MmGRqX8j/builds/h0VY0ElvveiVCU4zS/openapi.json
