# Buyer Intent AI (`danielmichalek/buying-intent-lead-scorer`) Actor

Score forum posts against your product and inspect the source evidence. Use rules or optional AI to prioritize declared buying questions. Ready to review your next batch?

- **URL**: https://apify.com/danielmichalek/buying-intent-lead-scorer.md
- **Developed by:** [Daniel Michałek](https://apify.com/danielmichalek) (community)
- **Categories:** Lead generation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 85.7% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$100.00 / 1,000 completed intent reports

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

## Buyer Intent AI

Rank supplied discussion posts against the product or service you sell. Start with reproducible rules, or enable optional AI to assess semantic product fit. Every result keeps locally copied source evidence and an explicit explanation of how it was assessed.

### What it does

This is a scoring layer for posts you already collected, including Reddit exports. It detects declared recommendation requests, switching, comparisons, problem descriptions and explicit budget mentions. It flags suspected vendor promotion, resolved needs and known stale posts before prioritizing possible business inquiries. It does not find contact details, crawl sites, send messages or promise a sale.

Rules use literal keyword matches and transparent signal weights. AI can assess semantic fit for the strongest eligible questions, while deterministic caps still apply. A post with no declared buying question cannot exceed20; promotion, a resolved need or a known stale post cannot exceed10. Scores are rankings, not purchase probabilities or proof of budget or decision-making authority.

### Input

The Console starts with six clearly synthetic demo posts from example.com and Rules mode, without a model request. These rows demonstrate the report; they are not real prospects. Replace the sample with your own posts. To use datasetId instead, clear the prefilled posts field first. Direct API calls do not receive hidden demo data: provide your own posts or a dataset.

Provide `productProfile`, 1-12 `keywords`, and either `posts` or `datasetId`. Source rows may have `id` or `postId`, `title`, `text`, `body` or `selftext`, and `url`, `sourceUrl` or a Reddit `permalink`. A supplied `createdAt` date or numeric `created_utc` enables the age filter; unknown dates stay unknown.

Only the first `maxPosts` source rows are sampled, before filtering; default and maximum30. Larger datasets are marked truncated. A selector requests READ permission only for the chosen dataset. Invalid rows are skipped with a count; conflicting duplicates fail rather than silently changing the score.

The positive screening excerpt and AI text are limited to800UTF-8 bytes per post. Negative disclosures are checked against the full provided source before clipping, up to a hard20000-byte source limit. Longer sources fail rather than hiding a qualifying suffix. Email and phone-like patterns are redacted; this is not a complete anonymization service. The model receives pseudonymous IDs and prepared excerpts, not source URLs or author/contact fields. Product profiles are limited to1500UTF-8 bytes.

`analysisMode` defaults to `rules`. To use AI, select `ai` and enable `allowPaidAI` after reviewing credit usage. Default6 and maximum8 eligible candidates are assessed in one model call. Remaining posts retain rules assessments. `language` supports English and Polish explanations. `minScore` defaults to30, and `maxAgeDays` to30; set the age limit to0 to disable it.

### Output

One dataset item contains the complete report. `leads` contains records above the chosen threshold; `assessments` contains all processed rankings for audit. Each record has the original source ID and URL, priority score, fit score, actual analysis mode, signals, keyword matches, freshness, flags and an evidence object copied from prepared source text.

The priority formula is base signal score multiplied by `0.25 + 0.75 * fitScore /100`, rounded and capped by the negative filters. Base weights are35 for recommendation requests,25 for switching,20 for comparisons,15 for problems and15 for budget mentions, capped at100. A rules keyword match gives80 fit points and two matches100; AI supplies an integer semantic fit score. These are product rules, not a statistical conversion model.

`modeRequested`, `modeUsed` and `aiStatus` expose what actually ran. AI errors fail without a completed report by default. If `allowRulesFallback` was explicitly enabled, the completed rules report is labelled `failed_rules_fallback` and is billable at the same report price. If no candidates are eligible, no unnecessary model request is made. The key-value store contains `RANKING`, `REPORT`, `OUTPUT`, and provider usage or response records when available.

### Pricing and cost control

The intended Store fee is0.10USD per completed report under `intent-report`, regardless of how many posts or leads it contains. A report with no qualifying leads is still a completed analysis. Failed input validation emits no completed report. The fee is charged once after the dataset write succeeds.

AI mode uses one fixed `openai/gpt-4o-mini` request through Apify's AI proxy, with a12000-byte prompt ceiling,1200 output tokens,45-second request timeout and no automatic retry. Available Apify credits and current proxy/model pricing apply; no additional model API key is requested. Credit use can occur even if an AI response later fails validation. A maximum Actor charge of0.10USD caps the report event, not a substitute for checking AI credit usage. Rules mode makes no inference request. Development runs stay inside the verified free-credit limit; no paid plan, proxy or campaign is required by this Actor.

### Limitations and fair use

Use source material you may process. Quotes come from normalized, redacted and possibly clipped source text; flags are signals to inspect rather than independently verified facts. Rules are conservative, can miss phrasing and can exclude genuine inquiries. AI interpretations may be wrong and require human review. Late positive statements outside the excerpt can be missed even though late negative disclosures remain protected. Missing source dates cannot establish that someone still needs a solution.

The Actor does not collect personal profiles, infer personal attributes, verify purchasing authority, alter a CRM or send outreach. It returns potential business questions and product-fit interpretations only. Its output is not evidence that a person will buy or that any revenue has been earned.

### Example

```json
{
  "productProfile": "Example service implementing n8n workflows for small teams",
  "keywords": ["n8n", "automation"],
  "posts": [{"id": "demo-1", "text": "Looking for n8n automation. Manual work is too expensive and we have a budget.", "url": "https://example.com/thread"}],
  "analysisMode": "rules"
}
```

For optional AI, change `analysisMode` to `ai` and explicitly set `allowPaidAI` to true. For dataset input, omit `posts` and supply the selected `datasetId`. Sample input and output are available in the source package.

# Actor input Schema

## `productProfile` (type: `string`):

Describe the business problem you solve. Maximum1500 UTF-8 bytes. Do not provide confidential or unnecessary personal data.

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

1-12 literal words or short phrases for the reproducible screening pass. AI may assess semantic fit beyond these keywords.

## `posts` (type: `array`):

Synthetic demo posts are prefilled for the first Console run. Replace them with your own posts, or clear this field before selecting datasetId. Objects may contain id, title, text, body or selftext, URL and timestamp. No sites are crawled; demo rows are not real prospects.

## `datasetId` (type: `string`):

Alternative to posts. Only the first maxPosts rows are sampled; a larger source is marked truncated. Select only a dataset you may process.

## `analysisMode` (type: `string`):

Rules is deterministic. AI adds product-fit assessments for the strongest eligible candidates using one model request.

## `allowPaidAI` (type: `boolean`):

Required for AI mode. The Apify AI proxy consumes available credits under current provider pricing, even if validation later fails. One request, no automatic retry. No external API key is requested.

## `allowRulesFallback` (type: `boolean`):

If an AI attempt fails, return a completed, billable rules report labelled failed_rules_fallback. Default false fails without emitting a completed report.

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

Language of AI fit explanations and readable report labels.

## `maxPosts` (type: `integer`):

Sample at most30 source rows before filtering. Text is clipped to800 UTF-8 bytes with a visible count.

## `maxAiCandidates` (type: `integer`):

At most8 eligible buying questions receive AI fit assessment. Remaining posts keep their rules assessment.

## `minScore` (type: `integer`):

0-100 ranking threshold. This is not calibrated buying probability. All processed assessments remain in the report for audit.

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

Known older posts are capped at10. Missing or invalid timestamps remain unknown. Set0 to disable this age filter.

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

Exactly one completed report is one billable event, regardless of the number of posts or returned leads.

## Actor input object example

```json
{
  "productProfile": "We build n8n automation workflows for small businesses.",
  "keywords": [
    "n8n",
    "automation"
  ],
  "posts": [
    {
      "id": "demo-buyer-1",
      "title": "Looking for n8n automation help",
      "text": "Our manual spreadsheets are too expensive to maintain. We have a budget and need a workflow provider.",
      "url": "https://example.com/demo/buyer-1"
    },
    {
      "id": "demo-buyer-2",
      "text": "Looking for an alternative to our n8n automation setup. Comparing providers, willing to pay for help with manual work.",
      "url": "https://example.com/demo/buyer-2"
    },
    {
      "id": "demo-promotion",
      "text": "Looking for n8n automation? Try our new app and use a discount code.",
      "url": "https://example.com/demo/promotion"
    },
    {
      "id": "demo-unrelated",
      "text": "Looking for hiking shoes. Budget available. Which software compares boots?",
      "url": "https://example.com/demo/unrelated"
    },
    {
      "id": "demo-noise",
      "text": "A useful guide to n8n automation for hobby projects.",
      "url": "https://example.com/demo/noise"
    },
    {
      "id": "demo-buyer-pl",
      "text": "Szukam n8n automation dla malej firmy. Robimy to recznie, budzet jest ustalony. Potrzebuje pomocy.",
      "url": "https://example.com/demo/buyer-pl"
    }
  ],
  "analysisMode": "rules",
  "allowPaidAI": false,
  "allowRulesFallback": false,
  "language": "en",
  "maxPosts": 30,
  "maxAiCandidates": 6,
  "minScore": 30,
  "maxAgeDays": 30,
  "maxItems": 1
}
```

# Actor output Schema

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

No description

## `ranking` (type: `string`):

No description

## `report` (type: `string`):

No description

## `aiUsage` (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 = {
    "productProfile": "We build n8n automation workflows for small businesses.",
    "keywords": [
        "n8n",
        "automation"
    ],
    "posts": [
        {
            "id": "demo-buyer-1",
            "title": "Looking for n8n automation help",
            "text": "Our manual spreadsheets are too expensive to maintain. We have a budget and need a workflow provider.",
            "url": "https://example.com/demo/buyer-1"
        },
        {
            "id": "demo-buyer-2",
            "text": "Looking for an alternative to our n8n automation setup. Comparing providers, willing to pay for help with manual work.",
            "url": "https://example.com/demo/buyer-2"
        },
        {
            "id": "demo-promotion",
            "text": "Looking for n8n automation? Try our new app and use a discount code.",
            "url": "https://example.com/demo/promotion"
        },
        {
            "id": "demo-unrelated",
            "text": "Looking for hiking shoes. Budget available. Which software compares boots?",
            "url": "https://example.com/demo/unrelated"
        },
        {
            "id": "demo-noise",
            "text": "A useful guide to n8n automation for hobby projects.",
            "url": "https://example.com/demo/noise"
        },
        {
            "id": "demo-buyer-pl",
            "text": "Szukam n8n automation dla malej firmy. Robimy to recznie, budzet jest ustalony. Potrzebuje pomocy.",
            "url": "https://example.com/demo/buyer-pl"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("danielmichalek/buying-intent-lead-scorer").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 = {
    "productProfile": "We build n8n automation workflows for small businesses.",
    "keywords": [
        "n8n",
        "automation",
    ],
    "posts": [
        {
            "id": "demo-buyer-1",
            "title": "Looking for n8n automation help",
            "text": "Our manual spreadsheets are too expensive to maintain. We have a budget and need a workflow provider.",
            "url": "https://example.com/demo/buyer-1",
        },
        {
            "id": "demo-buyer-2",
            "text": "Looking for an alternative to our n8n automation setup. Comparing providers, willing to pay for help with manual work.",
            "url": "https://example.com/demo/buyer-2",
        },
        {
            "id": "demo-promotion",
            "text": "Looking for n8n automation? Try our new app and use a discount code.",
            "url": "https://example.com/demo/promotion",
        },
        {
            "id": "demo-unrelated",
            "text": "Looking for hiking shoes. Budget available. Which software compares boots?",
            "url": "https://example.com/demo/unrelated",
        },
        {
            "id": "demo-noise",
            "text": "A useful guide to n8n automation for hobby projects.",
            "url": "https://example.com/demo/noise",
        },
        {
            "id": "demo-buyer-pl",
            "text": "Szukam n8n automation dla malej firmy. Robimy to recznie, budzet jest ustalony. Potrzebuje pomocy.",
            "url": "https://example.com/demo/buyer-pl",
        },
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("danielmichalek/buying-intent-lead-scorer").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 '{
  "productProfile": "We build n8n automation workflows for small businesses.",
  "keywords": [
    "n8n",
    "automation"
  ],
  "posts": [
    {
      "id": "demo-buyer-1",
      "title": "Looking for n8n automation help",
      "text": "Our manual spreadsheets are too expensive to maintain. We have a budget and need a workflow provider.",
      "url": "https://example.com/demo/buyer-1"
    },
    {
      "id": "demo-buyer-2",
      "text": "Looking for an alternative to our n8n automation setup. Comparing providers, willing to pay for help with manual work.",
      "url": "https://example.com/demo/buyer-2"
    },
    {
      "id": "demo-promotion",
      "text": "Looking for n8n automation? Try our new app and use a discount code.",
      "url": "https://example.com/demo/promotion"
    },
    {
      "id": "demo-unrelated",
      "text": "Looking for hiking shoes. Budget available. Which software compares boots?",
      "url": "https://example.com/demo/unrelated"
    },
    {
      "id": "demo-noise",
      "text": "A useful guide to n8n automation for hobby projects.",
      "url": "https://example.com/demo/noise"
    },
    {
      "id": "demo-buyer-pl",
      "text": "Szukam n8n automation dla malej firmy. Robimy to recznie, budzet jest ustalony. Potrzebuje pomocy.",
      "url": "https://example.com/demo/buyer-pl"
    }
  ]
}' |
apify call danielmichalek/buying-intent-lead-scorer --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,danielmichalek/buying-intent-lead-scorer"
        }
    }
}
```

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/Tw6mfEAjR1maTtEAd/builds/k80mtUQxEyfUw7csG/openapi.json
