# Newsletter Sponsor Finder — InboxReads Directory Scraper (`nomad-agent/newsletter-sponsors-scraper`) Actor

Find newsletters that accept sponsorships, cross-promotions or are up for sale — from the InboxReads public directory. Topics, cadence, audience geo, ad-platform and sponsor-contact signals per newsletter. For sponsor prospecting and market research. From $0.004/newsletter, no subscription.

- **URL**: https://apify.com/nomad-agent/newsletter-sponsors-scraper.md
- **Developed by:** [Nomad.Dev](https://apify.com/nomad-agent) (community)
- **Categories:** Marketing, Lead generation
- **Stats:** 1 total users, 1 monthly users, 96.8% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.60 / 1,000 newsletter results

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Newsletter Sponsor Finder — InboxReads Directory Scraper

> **Claude / Codex skill to describe and setup this actor: [SKILL.md](https://github.com/Exdenta/OinkAIJobSearch/blob/main/skill/newsletter-sponsors-scraper/SKILL.md)**

Find newsletters that **accept sponsorships**, are **open to cross-promotion** or are **up for sale** — scraped from the [InboxReads](https://inboxreads.co) public directory (~3,300 newsletters). Per newsletter: topics, send cadence, audience geography, the email/sponsorship tooling it runs on (Paved, BuySellAds, Passionfroot, beehiiv, Mailchimp...), whether a sponsor-contact route exists, and directory popularity ranks. No login, no proxies.

Built for **sponsor prospecting** (media buyers and brands hunting placement inventory), **newsletter competitive research**, and **acquisition scouting** (`onlyForSale`).

### What makes this different

Other InboxReads scrapers return name, description and topics. This one is built around **sponsor intelligence** — a combination of first-class, filterable fields no other newsletter-directory Actor exposes:

- `acceptsSponsorships`, `allowsCrossPromotion`, `isForSale` — filter the directory straight down to buyable / swappable / acquirable inventory.
- `sponsorshipPlatforms` — the ad networks a newsletter actually sells through (Paved, BuySellAds, Passionfroot...), **detected from its tooling stack rather than self-reported**, so you know *where to go buy*. Filter on it directly.
- `hasSponsorContact` / `hasAdvertiseUrl` — whether a contact route / media kit exists.
- `audienceCountries` — reader geography, for market-matched buys.

**On the fields we deliberately leave out:** we do not emit subscriber counts or open/click rates. InboxReads gates those behind its Pro plan on every public listing, so a scraper can only ever return them as `null` (or a fabricated guess). We return what is actually public and skip the always-empty columns — see the FAQ below.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `topics` | array of strings | `["business", "marketing"]` | Only newsletters tagged with at least one of these topics (case-insensitive). Empty list = all topics. Full topic list: [inboxreads.co/topics](https://inboxreads.co/topics). |
| `onlyAcceptingSponsors` | boolean | `false` | Only newsletters whose listing says they accept paid sponsorships/ads (roughly half the directory). |
| `onlyOpenToCrossPromotion` | boolean | `false` | Only newsletters open to cross-promotion swaps. |
| `onlyForSale` | boolean | `false` | Only newsletters marked as up for sale. |
| `sponsorshipPlatforms` | array of strings | *(empty)* | Only newsletters that sell sponsorships through at least one of these platforms (case-insensitive), e.g. `Paved`, `BuySellAds`, `Passionfroot`. Detected from the tooling stack, not self-reported. Empty = any platform. |
| `language` | string | *(empty)* | Only newsletters written in this language, e.g. `english`, `spanish`. Empty = any. |
| `onlyNewSinceLastRun` | boolean | `false` | Only output newsletters not seen in previous runs with this flag — see [Delta mode](#delta-mode). |
| `maxItems` | integer | `100` | Stop after this many newsletters have been returned (= billed results). Filters don't shrink your result count — the scraper keeps scanning until it has this many matches or the directory is exhausted. `0` = no cap (whole directory, ~3,400 listings). |
| `concurrency` *(Advanced)* | integer | `4` | Parallel listing fetches. Keep low — this is a small independent directory site. |

### What newsletter data does this scraper extract?

One flat JSON record per newsletter listing:

| Field | Meaning |
|---|---|
| `id` | Stable id, `inboxreads:<slug>` |
| `source` | Always `inboxreads` |
| `slug` | Listing slug |
| `url` | Listing page on InboxReads |
| `name` | Newsletter name |
| `tagline` | One-line pitch |
| `description` | Longer description |
| `topics` | Topic tags, e.g. `["business", "tech"]` |
| `language` | Language, e.g. `english` |
| `sendIntervalDays` | Send cadence in days (`1` = daily, `7` = weekly) — `null` if not stated |
| `sendFrequency` | Human label derived from the above (`daily`, `weekly`, `biweekly`, ...) |
| `acceptsSponsorships` | `true` if the listing says it accepts paid sponsorships/ads |
| `allowsCrossPromotion` | `true` if open to cross-promo swaps |
| `isForSale` | `true` if the newsletter is listed for sale |
| `paidStatus` | `free` / paid-subscription status of the newsletter itself |
| `hasSponsorContact` | `true` if the directory exposes a contact route for this newsletter |
| `hasAdvertiseUrl` | `true` if the newsletter publishes its own advertise/media-kit link |
| `favourites` | Directory likes — popularity proxy |
| `ranks` | Directory rank overall and per topic, e.g. `{"all": 1, "news": 1}` |
| `audienceCountries` | Top reader countries with relative score, `[{"country", "score"}]` |
| `audienceCountryCount` | How many countries the readership spans |
| `emailTools` | Detected stack, `[{"name", "category"}]` — category `sponsorship` shows which sales platform (Paved, BuySellAds, Passionfroot...) the newsletter sells through |
| `sponsorshipPlatforms` | Flat list of the sponsorship sales platforms from `emailTools`, e.g. `["Paved", "BuySellAds"]` — the actionable "where to go buy" signal, and the `sponsorshipPlatforms` input filters on it |
| `listingCreatedAt` / `listingUpdatedAt` | Listing timestamps (ISO 8601) |
| `relatedSlugs` | Similar newsletters (slugs) — feed them back in as seeds |
| `parseConfidence` | `high` / `medium` / `low` — how cleanly the page parsed |
| `warnings` | Parse warnings, empty when clean |
| `isNew` | `true` on every pushed record — only present when **Only new since last run** is on |

Subscriber counts and open/click rates are **not** included: InboxReads gates them behind its Pro plan on every listing we sampled, and this actor only reads public pages — no always-empty columns, no fabricated numbers.

### How to find newsletter sponsorship inventory with this Actor

1. Set **topics** to your target verticals (`marketing`, `finance`, `ai`, ...) — or leave empty for the whole directory.
2. Turn on **Only newsletters accepting sponsors** to keep just the sponsorable inventory; add **language** if you buy in one market.
3. Read `sponsorshipPlatforms` in the output — the platforms (Paved, BuySellAds, Passionfroot...) where that newsletter actually sells placements, i.e. where to go buy. To target one ad network, put its name in the **Sponsorship platforms** input (e.g. `["Paved"]`) and only newsletters selling through it come back.
4. Turn on **Only new since last run** and schedule the run to monitor newly listed newsletters (new inventory alert).
5. Export JSON, CSV or Excel — or call it over the API:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("nomad-agent/newsletter-sponsors-scraper").call(run_input={
    "topics": ["marketing", "business"],
    "onlyAcceptingSponsors": True,
    "maxItems": 200,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["name"], "|", item["sendFrequency"], "|", item["url"])
```

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/nomad-agent~newsletter-sponsors-scraper/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"topics": ["marketing"], "onlyAcceptingSponsors": true, "maxItems": 100}'
```

### Output example

Real record (fetched 2026-07-02):

```json
{
  "id": "inboxreads:theskimm",
  "source": "inboxreads",
  "slug": "theskimm",
  "url": "https://inboxreads.co/n/theskimm",
  "name": "Daily Skimm",
  "tagline": "The morning newsletter that millions wake up to",
  "description": "Meet, news without all the noise. The Daily Skimm connects the dots on how the day's biggest stories affect your life.",
  "topics": ["news", "business", "sports", "politics", "entertainment"],
  "language": "english",
  "sendIntervalDays": 1,
  "sendFrequency": "daily",
  "acceptsSponsorships": true,
  "allowsCrossPromotion": false,
  "isForSale": false,
  "paidStatus": "free",
  "hasSponsorContact": false,
  "hasAdvertiseUrl": true,
  "favourites": 174,
  "ranks": {"all": 2, "news": 2, "sports": 2, "business": 2, "politics": 2, "entertainment": 1},
  "audienceCountries": [
    {"country": "United States", "score": 191},
    {"country": "India", "score": 22},
    {"country": "Morocco", "score": 14},
    {"country": "Brazil", "score": 12},
    {"country": "Canada", "score": 12}
  ],
  "audienceCountryCount": 1835,
  "emailTools": [
    {"name": "Paved", "category": "sponsorship"},
    {"name": "BuySellAds", "category": "sponsorship"},
    {"name": "Marigold Engage by Sailthru", "category": "email service provider"}
  ],
  "sponsorshipPlatforms": ["Paved", "BuySellAds"],
  "listingCreatedAt": "2017-09-08T16:45:16.000Z",
  "listingUpdatedAt": "2024-09-24T22:30:18.311Z",
  "relatedSlugs": ["axios-am-pm", "need-2-know", "tip-news", "1440-daily-digest", "daily-dose-1", "boardroom-newsletters"],
  "parseConfidence": "high",
  "warnings": []
}
```

`isNew` (delta mode) is added on top of this shape when that input is used.

### Delta mode

Turn on **Only new since last run** (`onlyNewSinceLastRun`) to have the Actor remember which listings it has already returned (keyed by slug) across runs and skip them.

- Skipped (already-seen) listings are **not fetched, not pushed and not billed** — repeat runs only pay for newsletters newly added to the directory.
- Every record pushed with this flag on is tagged `"isNew": true`.
- State is kept in a dedicated key-value store (separate from the run's default store), so it persists across scheduled runs.
- Failed fetches are *not* marked as seen — they retry on the next run.

### Pricing

Pay per event: **$0.004 per newsletter record** pushed (volume discounts down to $0.0026 on higher Apify plans) plus a negligible $0.00005 per Actor start. Filters run before billing — records filtered out are never charged. A typical filtered topic run (`maxItems: 100`) costs **$0.40**; a full-directory sweep (`maxItems: 0`, no filters) is ~3,400 records ≈ **$13.60**.

**Compare:** newsletter-sponsorship prospecting subscriptions run $8–58/month (InboxReads Pro) to $39–199/month (SponsorGap, Passionfroot). One $0.40 run here builds the same prospect list — pay only when you actually pull data, no subscription. This is also the cheapest per-record InboxReads/sponsor-signal Actor on Apify ($0.004 vs $0.007–0.008 elsewhere).

### FAQ

**Where does the data come from?** The public InboxReads directory (inboxreads.co) — listing pages only. The actor respects the site's robots.txt: InboxReads' own media-kit, ad-rate, sponsor-list and API paths are disallowed there and are never fetched.

**Why are there no subscriber counts or CPM prices?** InboxReads gates subscriber/open-rate/click-rate metrics behind its Pro plan, and newsletter rate cards live on each newsletter's own media-kit page. This actor reports what is public: sponsorship acceptance flags, contact/advertise-URL signals and which sponsorship platform each newsletter sells through (`emailTools`) — enough to build a prospect list; pricing conversations happen on the newsletter's own advertise page.

**How fresh is the data?** Each run fetches live pages. `listingUpdatedAt` tells you when the newsletter's listing itself last changed.

**Some fields are null — why?** Newsletters self-report unevenly. Fields the listing doesn't state come back `null` (never guessed); `parseConfidence` + `warnings` flag records where the page shape looked unusual.

**Can I monitor for new newsletters?** Yes — schedule the actor with `onlyNewSinceLastRun: true`. Only newly listed newsletters are pushed (and billed) on each run.

### Integrations

Export results as JSON, CSV or Excel, or wire this Actor into [Make](https://make.com), [Zapier](https://zapier.com) or [n8n](https://n8n.io); call it programmatically with `run-sync-get-dataset-items`; or use it from AI agents via the [Apify MCP server](https://mcp.apify.com).

***

**Found sponsorship inventory with this Actor?** A quick ⭐ review on the [Actor page](https://apify.com/nomad-agent/newsletter-sponsors-scraper) helps other media buyers find it — and tells us which signals to add next. Missing a field or a filter? [Open an issue](https://apify.com/nomad-agent/newsletter-sponsors-scraper/issues) and we usually ship it within days.

# Actor input Schema

## `topics` (type: `array`):

Only newsletters tagged with at least one of these topics (case-insensitive), e.g. <code>business</code>, <code>tech</code>, <code>marketing</code>, <code>finance</code>, <code>ai</code>. Empty = all topics. Browse the full topic list at inboxreads.co/topics.

## `onlyAcceptingSponsors` (type: `boolean`):

Only newsletters whose listing says they accept paid sponsorships/ads. Roughly half the directory qualifies.

## `onlyOpenToCrossPromotion` (type: `boolean`):

Only newsletters open to cross-promotion swaps with other newsletters.

## `onlyForSale` (type: `boolean`):

Only newsletters whose listing is marked as up for sale (acquisition leads).

## `sponsorshipPlatforms` (type: `array`):

Only newsletters that sell sponsorships through at least one of these platforms (case-insensitive), e.g. <code>Paved</code>, <code>BuySellAds</code>, <code>Passionfroot</code>. Detected from each newsletter's tooling stack, not self-reported — see the <code>sponsorshipPlatforms</code> output field. Empty = any platform. Combine with <code>onlyAcceptingSponsors</code> to target buyable inventory sold through a specific ad network.

## `language` (type: `string`):

Only newsletters written in this language, e.g. <code>english</code>, <code>spanish</code>, <code>german</code>. Empty = any language.

## `onlyNewSinceLastRun` (type: `boolean`):

Only output newsletters not seen in previous runs with this flag — new-listing monitoring. Skipped (already-seen) listings are not fetched, pushed or billed.

## `maxItems` (type: `integer`):

Stop after this many newsletters have been returned (= billed results). Filters don't shrink your result count — the scraper keeps scanning the directory until it has this many matching newsletters or the directory is exhausted. 0 = no cap (whole directory, ~3,400 listings).

## `concurrency` (type: `integer`):

How many listing pages to fetch in parallel (clamped to 1-8 at runtime). Keep low — this is a small independent directory site.

## Actor input object example

```json
{
  "topics": [
    "business",
    "marketing"
  ],
  "onlyAcceptingSponsors": false,
  "onlyOpenToCrossPromotion": false,
  "onlyForSale": false,
  "onlyNewSinceLastRun": false,
  "maxItems": 100,
  "concurrency": 4
}
```

# Actor output Schema

## `dataset` (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 = {
    "topics": [
        "business",
        "marketing"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("nomad-agent/newsletter-sponsors-scraper").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 = { "topics": [
        "business",
        "marketing",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("nomad-agent/newsletter-sponsors-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "topics": [
    "business",
    "marketing"
  ]
}' |
apify call nomad-agent/newsletter-sponsors-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=nomad-agent/newsletter-sponsors-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/5nhNZ2iDIPbNUqRX9/builds/hYdWZgTY23fkQqgaz/openapi.json
