# Journalist Request Monitor: #JournoRequest & Pitch Calls (`prime619/media-request-monitor`) Actor

Collects fresh journalist source requests (#journorequest), calls for pitches and podcast guest requests from Bluesky and Mastodon. Filter by topic, see parsed deadlines and how to reply, get only new requests on a schedule. CSV, Excel and a text digest. No login or API key.

- **URL**: https://apify.com/prime619/media-request-monitor.md
- **Developed by:** [Philipp Primisser](https://apify.com/prime619) (community)
- **Categories:** News, Lead generation, Social media
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.10 / 1,000 request delivereds

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

## Journalist Request Monitor: #JournoRequest & Pitch Calls

> **Try it free:** Apify's free plan includes monthly platform credit, no credit card needed. One example run with the input below costs about **$0.03** (up to 10 requests at $0.003 each; filtered posts and duplicates are free).

```json
{
  "requestTypes": [
    "journalist",
    "pitches",
    "podcast"
  ],
  "lookbackDays": 7,
  "maxResults": 10
}
```

Paste this into the **JSON** tab of the input form and click **Start**.

Journalists post source requests on Bluesky and Mastodon every day: "looking to speak to a nutritionist", "case study wanted", "deadline Friday". Editors post calls for pitches, and podcast hosts look for guests. These posts scroll away within hours.

This Actor collects them into one list. You choose the topics you care about, it returns each request with the deadline it found in the text, how the author wants to be contacted and a link to the original post. Put it on a daily schedule and you only get the requests you have not seen yet.

No login, no API key and no account on Bluesky or Mastodon needed.

### Who it is for

- PR consultants and agencies who answer media requests for clients
- Founders, experts and authors who want press mentions
- Freelance writers looking for editors who want pitches
- People who want to appear as a guest on podcasts

### What you get for each request

| Field | Example |
|---|---|
| requestType | journalist, pitches or podcast |
| text | "#journorequest looking to talk to parents in Ireland whose children started preschool this year. DM if any thoughts." |
| deadline / deadlineText | 2026-10-24 / "Deadline 24 Oct" |
| daysToDeadline | 17 |
| urgent | true if the post says urgent, ASAP, today and similar |
| replyVia | email, dm, link or reply |
| replyEmail | the address, if the author put one in the post |
| links | links in the post, for example to the full brief |
| authorName / authorHandle / authorProfileUrl | who posted it |
| isAggregator | true for accounts that relay requests from PR request services |
| matchedKeywords | which of your topics matched |
| platform, postedAt, url | where and when it was posted |

Besides the dataset, every run also writes:

- `requests.xlsx`: Excel file with filters, frozen header and clickable links
- `requests.csv`: UTF-8 with BOM, comma or semicolon (for Excel in Germany, Austria and Switzerland)
- `digest.txt`: a short plain-text list you can send by email or post to Slack with an Apify integration
- `RUN_SUMMARY`: how many posts were scanned, skipped as duplicates, filtered out and delivered

### Quick start

1. Leave all three request types selected, or pick only the ones you need.
2. Add a few topics, for example `health`, `nutrition`, `dietitian`. Leave it empty to see everything.
3. Run it. A run usually takes 10 to 30 seconds.

#### Daily feed with only new requests

```json
{
  "requestTypes": ["journalist"],
  "keywords": ["fintech", "banking", "personal finance", "money"],
  "excludeKeywords": ["gift guide"],
  "lookbackDays": 2,
  "onlyNew": true,
  "monitorName": "finance-pr"
}
```

Create an Apify schedule (for example every morning at 7:00) with this input. Each run returns only requests that earlier runs of the `finance-pr` monitor have not delivered. Add the email or Slack integration to the schedule and you have a morning digest.

#### Podcast guest spots

```json
{
  "requestTypes": ["podcast"],
  "keywords": ["entrepreneur", "marketing", "health"],
  "lookbackDays": 14
}
```

### Where the data comes from

- **Bluesky:** the public search API, with searches such as `#journorequest`, `#prrequest`, `#mediarequest`, `"call for pitches"`, `#podcastguest` and a few more. You can add your own with `extraSearchTerms`.
- **Mastodon:** the public hashtag timelines of the servers you list (default: mastodon.social and journa.host).

Only public posts are read. Replies and reposts are skipped. The Actor respects opt-outs: Bluesky accounts that asked not to be shown to logged-out visitors are skipped, and so are Mastodon accounts that did not opt in to being discoverable. It never posts, likes, follows or sends messages.

### How the filtering works

All rules are simple text rules. No AI model is involved, so results are fast and you need no extra key.

- **Real requests only** (on by default): a post must read like a request ("looking for", "wanted", "DM me", "open for pitches" and so on). Posts that only use the hashtag, such as news, complaints or tips about PR, are dropped.
- **Duplicates:** the same post found by several searches, and identical texts posted twice, are delivered once.
- **Deadlines:** dates like "Deadline 24 Oct", "by Friday", "due 2026-11-02" or "by tomorrow" are turned into a date. Requests whose deadline has passed are skipped unless you turn that off.
- **Relay accounts:** some accounts repost requests from PR request services. They stay in the results but are marked with `isAggregator`, and you can drop them with one switch.

### Pricing

You pay per delivered request, see the pricing tab for the current price. Filtered posts, duplicates and requests you already received in a monitor are not charged. Set `maxResults` to cap the cost of a run.

### Limits worth knowing

- Bluesky only allows logged-out searches to return the newest 100 posts per search term. With the default look-back of 7 days this is rarely a limit for these hashtags. For a busy custom search term, run the Actor more often with a shorter look-back.
- Volume depends on what people post. Expect roughly 20 to 50 journalist requests per week on Bluesky, most of them from UK and US media, and fewer pitch calls and podcast requests.
- Deadline parsing reads the common formats. Always check the original post before you reply.
- Requests on X (Twitter), LinkedIn and paid request services are not included.

### Using the results responsibly

The posts belong to their authors. Reply to the request the way the author asked and only when you are a good fit. Do not add the authors to mailing lists or send them unrelated marketing.

### Questions and feedback

Open an issue on the Issues tab. If a search term you care about is missing, tell me which one.

### Related Actors by the same developer

- [Bluesky & Mastodon Keyword Monitor](https://apify.com/prime619/bluesky-mastodon-keyword-monitor): alerts for new posts that mention your brand, product or any keyword, with language filters.

# Changelog

This Actor's version history is a separate document: https://apify.com/prime619/media-request-monitor/changelog.md

# Actor input Schema

## `requestTypes` (type: `array`):

Leave all three selected to get everything.

## `keywords` (type: `array`):

Only keep requests that mention at least one of these words, for example nutrition, fintech, travel, psychologist. Leave empty to get all requests.

## `excludeKeywords` (type: `array`):

Drop requests that mention any of these words, for example gift guide or giveaway.

## `lookbackDays` (type: `integer`):

How far back to search. For a daily schedule 2 days is plenty.

## `languages` (type: `array`):

Two-letter language codes as set by the author, for example en or de. Leave empty for all languages.

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

Upper limit of requests per run, newest first. You pay per delivered request.

## `onlyNew` (type: `boolean`):

Remembers what earlier runs of this monitor delivered and returns only new requests. Use it with an Apify schedule. You are only charged for new requests.

## `monitorName` (type: `string`):

Optional. Give each feed its own name (for example health-pr) so separate schedules keep separate memory. Without a name the memory is tied to your filter settings.

## `strictRequestsOnly` (type: `boolean`):

Drops posts that only use the hashtag, such as general news, complaints or tips. Turn off to see everything the searches find.

## `includeAggregators` (type: `boolean`):

Some accounts repost requests from PR request platforms. They are marked with isAggregator. Turn off to see only posts written by the journalist, editor or host.

## `skipExpired` (type: `boolean`):

Only applies when the post states a deadline we can read.

## `extraSearchTerms` (type: `array`):

Optional extra Bluesky searches, for example #expertrequest or "looking for case studies". Use quotes for exact phrases. Up to 10.

## `includeMastodon` (type: `boolean`):

Also read the public hashtag timelines of the Mastodon servers below.

## `mastodonInstances` (type: `array`):

Server names, up to 5. Posts from accounts that did not opt in to being discoverable are skipped.

## `csvDelimiter` (type: `string`):

The Excel file and the text digest are always included as well.

## Actor input object example

```json
{
  "requestTypes": [
    "journalist",
    "pitches",
    "podcast"
  ],
  "keywords": [],
  "excludeKeywords": [],
  "lookbackDays": 7,
  "languages": [],
  "maxResults": 10,
  "onlyNew": false,
  "strictRequestsOnly": true,
  "includeAggregators": true,
  "skipExpired": true,
  "extraSearchTerms": [],
  "includeMastodon": true,
  "mastodonInstances": [
    "mastodon.social",
    "journa.host"
  ],
  "csvDelimiter": "comma"
}
```

# Actor output Schema

## `requests` (type: `string`):

One row per request with text, deadline, author and how to reply.

## `excel` (type: `string`):

requests.xlsx with filters, frozen header and clickable links.

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

requests.csv (UTF-8 with BOM, comma or semicolon).

## `digest` (type: `string`):

digest.txt, a short plain-text list for email or Slack.

## `summary` (type: `string`):

Searches run, posts scanned, duplicates, filtered out and delivered.

# 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 = {
    "requestTypes": [
        "journalist",
        "pitches",
        "podcast"
    ],
    "lookbackDays": 7,
    "maxResults": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("prime619/media-request-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 = {
    "requestTypes": [
        "journalist",
        "pitches",
        "podcast",
    ],
    "lookbackDays": 7,
    "maxResults": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("prime619/media-request-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 '{
  "requestTypes": [
    "journalist",
    "pitches",
    "podcast"
  ],
  "lookbackDays": 7,
  "maxResults": 10
}' |
apify call prime619/media-request-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,prime619/media-request-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/E3fxUUVWGhGFJSRxa/builds/3pZ7vj59V3gILZCjr/openapi.json
