# Journalist Requests Scraper - #journorequest Media Requests (`dami_studio/journalist-requests-scraper`) Actor

Open journalist requests for expert sources from Bluesky and Mastodon, plus optional UK and US calls for evidence, with deadlines, sections and your topics matched.

- **URL**: https://apify.com/dami_studio/journalist-requests-scraper.md
- **Developed by:** [Dami's Studio](https://apify.com/dami_studio) (community)
- **Categories:** Marketing, News, Social media
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.70 / 1,000 requests

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

**Find open journalist requests for expert sources (#journorequest)**: run it and you get every open request posted
on Bluesky in the last 30 days, each with its deadline when the post states one, a section, who is asking, and your
topics matched and ranked first. Switch on the UK Parliament, GOV.UK and US Federal Register lists and you also get open
calls for expert evidence, with their real closing dates.

The honest part first: journalists post only a handful of requests a day under these tags. Across all of Bluesky we
counted 6 in one full day of posts (27 Oct 2026), and most came from services that relay requests and link to their own
site. A run gives you days or weeks of requests, not hundreds a day.

| | |
|---|---|
| **Input** | Nothing required. Optionally your topics, sections, countries and sources |
| **Output** | One row per open request: title, full text, link, deadline, days left, section, who is asking, your matched topics |
| **Ceiling** | 2,000 requests per run |
| **Speed** | 1 to 3 seconds a run in our tests, every source together included |
| **Account needed** | None from you |
| **Price** | $1.70 per 1,000 requests, flat on every plan. The free plan's $5 a month covers about 2,900 |

| Using an AI agent? | |
|---|---|
| Actor | `dami_studio/journalist-requests-scraper` |
| Set one field | `keywords`, labelled "Your topics" in the Console |
| Cap the bill | `maxTotalChargeUsd` on the run, for example `0.10`: it never charges past that |
| MCP, one link | `https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/journalist-requests-scraper` |
| How often | Daily, with `onlyNewRequests` on, so each morning brings only requests you have not seen |

### 🔍 What Journalist Requests Scraper does

It reads the public #journorequest and #prrequest posts on Bluesky, keeps the ones from the last 30 days, and turns
each into a row you can sort and filter. A post's own words decide its section, the deadline (only when the post names
one, such as "Deadline 28 Oct, 17:00" or "by Friday") and who is asking. Requests that mention one of your topics are
tagged in `matchedKeywords` and come first, then the rest by soonest deadline.

Mastodon is there too, but its request tags have been quiet since September 2026, so it is off unless you tick it.

The three government sources are a different kind of request. UK Parliament committees asking for written evidence,
GOV.UK consultations and US Federal Register requests for information all want expert input by a fixed date. They
are not journalists, so they are off by default, but a published response with your name on it is the kind of thing
some people answer journalist requests to get.

Each post is fetched fresh on every run, so a request its author has deleted is gone from your results too.

### 📋 What data you get from each journalist request

| What you want | Field |
|---|---|
| The request | `title`, `summary` (the full text) |
| Where to answer it | `url` |
| Deadline | `deadline` (UTC), `deadlineText` (as written), `daysLeft`, `isOpen` |
| Who is asking | `requesterName`, `requesterType`, `outlet` (only when named plainly) |
| Topic | `industry` (one of twelve sections), `matchedKeywords` |
| Where it came from | `source`, `authorHandle`, `authorUrl`, `datePosted`, `language`, `country` |
| For scheduled runs | `isNew` |
| Licence line on government rows | `attribution` |

### ▶️ How to scrape journalist requests

1. Open the actor and press **Try for free**.
2. Type the subjects you can speak on into **Your topics**, for example `pensions` or `cybersecurity`.
3. Leave **Where to look** on Bluesky, or tick the government lists as well.
4. Press **Start**. Open the **Output** tab and the **Requests** view.
5. To get a fresh list every morning, schedule it daily with **Only new requests** switched on.

### 💰 How much does it cost to scrape journalist requests?

$1.70 per 1,000 requests, the same on the Free, Starter, Scale and Business plans, plus $0.00005 when a run starts. The
free plan's $5 a month covers about 2,900 requests. Requests left out by your filters are not charged, and neither are
the note rows that say a source did not answer or nothing matched.

### 📥 What you give it

| Field | What it does | Default |
|---|---|---|
| `keywords` | Your topics. Matches are tagged and listed first. A single word also matches plain endings: `finance` finds "financial" | none |
| `keywordsOnly` | Leave out requests that match none of your topics | `false` |
| `excludeKeywords` | Leave out requests that mention any of these | none |
| `onlyOpenDeadlines` | Hide requests past their deadline. A post with no stated deadline counts as open for 30 days | `true` |
| `maxAgeDays` | Only requests posted in the last this many days | no limit |
| `maxRequests` | Stop after this many | `200` |
| `sources` | `bluesky`, `mastodon`, `uk_parliament`, `gov_uk`, `us_federal_register` | `["bluesky"]` |
| `industries` | Keep only these sections | all |
| `countries` | Keep only requests about these countries | all |
| `onlyNewRequests` | Only requests not returned to you before | `false` |

```json
{
  "keywords": ["pensions", "personal finance"],
  "sources": ["bluesky", "gov_uk"],
  "onlyOpenDeadlines": true,
  "maxRequests": 200
}
```

### 📤 What you get back

![Real run output](https://api.apify.com/v2/key-value-stores/BTBHU3DdiuoF4JOsK/records/journalist-requests-scraper-output.png)

One full row from a run on 28 Oct 2026. A Bluesky row has the same fields, with `authorHandle` and `authorUrl` filled
and `attribution` empty.

```json
{
  "source": "GOV.UK",
  "requestId": "gov-uk:/government/consultations/land-use-statistics-in-england-methodology-changes",
  "title": "Consultation: Land use statistics in England: methodology changes",
  "summary": "We are seeking views on a new methodology for the collection of MHCLG's land use statistics for England.",
  "url": "https://www.gov.uk/government/consultations/land-use-statistics-in-england-methodology-changes",
  "industry": "General",
  "requesterName": "Ministry of Housing, Communities and Local Government",
  "requesterType": "Government consultation",
  "country": "United Kingdom",
  "datePosted": "2026-09-16T09:00:00.000Z",
  "deadline": "2026-10-28T23:59:00.000Z",
  "deadlineText": "Closes 2026-10-28",
  "daysLeft": 0,
  "isOpen": true,
  "matchedKeywords": [],
  "isNew": false,
  "attribution": "Contains public sector information licensed under the Open Government Licence v3.0."
}
```

| Field | Read it like this |
|---|---|
| `deadline` | UTC. On a post it is the day the post names, end of day when no time is given. A time in the post is taken as written, since posts rarely say which time zone |
| `daysLeft` | Whole days to the deadline; 0 means it closes today. Empty when no deadline is stated |
| `summary` | E-mail addresses and phone numbers in a post are replaced with "\[e-mail in the original post]". The link takes you to the post itself |
| `requesterType` | Journalist, Podcaster, Blogger, Author, PR Pro, or Request service for accounts that relay requests and link to their own site. Read from the post and the poster's profile |
| `outlet` | Filled only when the post names the publication plainly, such as "for Newsweek features". Often empty |
| `isNew` | Whether this request was returned to your account before |

### 🧾 Reading the output

A real request row has no `_diagnostic` field. A note row has `_diagnostic: true`, costs nothing, and carries a
`status`:

| `status` | Meaning |
|---|---|
| `NO_RESULTS` | Nothing was found, or your filters left everything out. `leftOut` counts the reasons |
| `NOT_SERVED` | One source did not answer this run. The others still came back |
| `TIME_LIMIT` | The run's time limit came first; `sourcesNotFinished` names what was left |
| `COST_LIMIT` | The maximum cost you set for the run was reached |
| `BAD_INPUT` | No source was picked |

To keep only requests, filter out rows where `_diagnostic` is true.

### 💡 What people use it for

- An expert or a founder who wants to be quoted: put your subjects in `keywords`, schedule it daily with
  `onlyNewRequests`, and read the morning's list over coffee.
- A PR team answering requests for several clients: one task per client, each with its own `keywords`, sent to a sheet.
- A consultancy that answers government consultations: tick `gov_uk` and `uk_parliament`, filter by `industries`, and
  sort by `deadline`.

A recipe that chains three of our actors: run this one on your subjects, open the `url` of each matched request, then
run [Google News Scraper](https://apify.com/dami_studio/google-news-scraper) on the same subject to see what that
outlet and others have already published before you pitch.

### 🚧 What it does not do

- **It is not a high-volume feed.** The public request tags carry a handful of posts a day, and most come from services
  that relay requests.
- **No contact details.** Addresses and numbers in a post are masked; you answer through the post or the link in it.
- **No X (Twitter), LinkedIn, Facebook or Reddit requests**, and no request boards that need an account.
- **Sections and requester types are read from the words**, so a mixed request can land in the wrong section.
- **Most posts name no country**, so the `countries` filter leaves most posts out.
- It is not an official Bluesky, Mastodon, UK Parliament, GOV.UK or Federal Register tool. Dami's Studio is independent and is not affiliated with or endorsed by Bluesky, Mastodon, UK Parliament, GOV.UK or the Federal Register, or by any other company named on this page.

### 🧭 Which scraper do you need?

| If you want | Use |
|---|---|
| Open journalist requests and calls for evidence | This one |
| Any keyword on Bluesky, or a person's posts | [Bluesky Scraper](https://apify.com/dami_studio/bluesky-scraper) |
| Hashtags and accounts on Mastodon | [Mastodon Scraper](https://apify.com/dami_studio/mastodon-scraper) |
| What the press has already written on a subject | [Google News Scraper](https://apify.com/dami_studio/google-news-scraper) |
| Newsletter posts from a Substack publication | [Substack Scraper](https://apify.com/dami_studio/substack-publication-scraper) |

### ❓ Questions people ask

#### Do I need a Bluesky account to get journalist requests?

No. You don't need a Bluesky or Mastodon account. It reads public posts the way a signed-out visitor sees them.

#### Why is a request I saw on Bluesky not in my results?

Either it was posted without one of the request tags, its deadline has passed (or it is over 30 days old with none
stated), or your filters left it out. The `NO_RESULTS` note row counts what each filter removed.

#### How do I get only new requests each day?

Schedule a daily run with **Only new requests** on. The ids it returned are kept in a store named
`journalist-requests-seen` in your own account; delete that store to start over.

#### Can I call it from code or connect it to an AI assistant?

The [API tab](https://apify.com/dami_studio/journalist-requests-scraper/api/python) has code for Python, JavaScript and
the CLI. MCP clients like Claude and ChatGPT use
`https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/journalist-requests-scraper`. Both bill your Apify
account at the same price.

```python
## pip install apify-client
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("dami_studio/journalist-requests-scraper").call(
    run_input={
        "keywords": ["pension", "health"],
        "maxRequests": 40,
    },
    max_total_charge_usd=0.10,  # the most this run may spend
)
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    if row.get("ok") is False:  # free note rows, not requests
        continue
    print(row["deadline"], row["title"], row["url"])
```

#### Is scraping journalist requests legal?

The posts are public and read without an account, and nothing private is collected. They still carry personal data,
such as the poster's name and handle, so GDPR and similar laws apply to what you keep, and the rules on unsolicited
contact apply to how you reply. Each site's own terms apply to what you do with the rows. Apify's write-up on
[the legality of web scraping](https://blog.apify.com/is-web-scraping-legal/) is a good start, and we are not lawyers.

### 🆘 If something breaks

Open the **Issues** tab on the actor page. Send the input you used and the run ID, and the `status` of any note row.

# Actor input Schema

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

The subjects you can speak on, in plain words, like `cybersecurity`, `pensions` or `interior design`. Requests that mention one are tagged in `matchedKeywords` and listed first. A single word also matches its plain endings, so `finance` finds "financial". Leave it empty to get every request.

## `keywordsOnly` (type: `boolean`):

Leave out every request that mentions none of your topics. Needs at least one topic above.

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

Words that rule a request out, like `giveaway` or `crypto`. Matched the same way as your topics.

## `onlyOpenDeadlines` (type: `boolean`):

Keep only requests whose deadline has not passed. A post that states no deadline counts as open for 30 days after it was posted.

## `maxAgeDays` (type: `integer`):

Only requests posted in the last this many days. Empty means no age limit beyond the 30-day rule above. Calls for evidence count from the day they opened.

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

Stop after this many, the most useful first: your topics, then the soonest deadline, then the newest.

## `sources` (type: `array`):

Bluesky carries the journalists' own requests. Mastodon's request tags have been quiet for months, so it is off unless you tick it. The three government lists are not journalists: they are open calls for expert evidence, with real closing dates, for when being quoted in a report or a consultation response is useful to you.

## `industries` (type: `array`):

Keep only requests in these sections. Each request gets its section from its own words, so a mixed request lands in the one it talks about most. Empty keeps every section.

## `countries` (type: `array`):

Keep only requests about these countries. Government rows always have one; a post has one only when it names exactly one country, so most posts are left out by this filter.

## `onlyNewRequests` (type: `boolean`):

Return only requests this actor has not returned to you before, so a daily schedule gives you a fresh list each morning. It keeps the ids it returned in a store named `journalist-requests-seen` in your own account; delete that store to start over.

## Actor input object example

```json
{
  "keywords": [
    "marketing",
    "finance",
    "health"
  ],
  "keywordsOnly": false,
  "onlyOpenDeadlines": true,
  "maxRequests": 200,
  "sources": [
    "bluesky"
  ],
  "industries": [],
  "countries": [],
  "onlyNewRequests": false
}
```

# Actor output Schema

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

One row per open request. Free note rows (`_diagnostic: true`) say when a source did not answer, the run stopped early, or nothing matched.

# 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 = {
    "keywords": [
        "marketing",
        "finance",
        "health"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("dami_studio/journalist-requests-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 = { "keywords": [
        "marketing",
        "finance",
        "health",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("dami_studio/journalist-requests-scraper").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 '{
  "keywords": [
    "marketing",
    "finance",
    "health"
  ]
}' |
apify call dami_studio/journalist-requests-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dami_studio/journalist-requests-scraper"
        }
    }
}
```

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/TwUd5tfLTaGkh68xC/builds/iYjxxTVqR6cbmjd7S/openapi.json
