# Poland Service Leads & Oferteo Job Requests (`jabol1983/intent-signals-apify`) Actor

Find fresh buyer-intent leads and service requests across Poland from Oferteo. Search by trade, service, city, or region and get ranked sales opportunities with buyer type, urgency, freshness, and match reasons. Built for lead generation, CRM, n8n, Make, MCP, and AI agents.

- **URL**: https://apify.com/jabol1983/intent-signals-apify.md
- **Developed by:** [IntentSignals](https://apify.com/jabol1983) (community)
- **Categories:**
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 results

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?

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

Find fresh Oferteo job requests that match the service you sell, then return only the strongest public opportunities — ranked by relevance, freshness, urgency, buyer type, and scope.

Enter a service such as **electrician**, **hydraulik**, **web design**, **sprzątanie**, or **accounting**, optionally add a location, and the Actor handles the Oferteo category targeting and qualification for you.

> **Important:** this Actor reads public Oferteo request-listing data only. It does not log in, unlock paid contact details, bypass CAPTCHAs, or automate Oferteo's paid contact flow. Oferteo may require its own account or fees to contact a requester. This Actor is an independent tool and is not affiliated with or endorsed by Oferteo.

### Why use this Actor?

A generic Oferteo feed can contain hundreds of unrelated requests. This Actor turns that feed into a shortlist you can actually act on.

It automatically:

- resolves the right Oferteo request category for the service you sell,
- targets a city or region when supplied,
- rejects requests that do not contain a real service match,
- removes stale requests using a hard freshness cutoff,
- optionally filters by company/private buyer,
- scores commercial fit from 0–100,
- explains why each request matched,
- sorts the best opportunities first,
- returns clean JSON/CSV/Excel-ready output for automations, CRMs, n8n, Make, agents, and scripts.

### Quick start

#### Electrician leads in Warsaw

```json
{
  "service": "electrician",
  "location": "Warszawa",
  "hoursBack": 48,
  "maxResults": 25
}
```

Polish service names work too:

```json
{
  "service": "elektryk",
  "location": "Piaseczno",
  "hoursBack": 24
}
```

#### Website projects across Poland

```json
{
  "service": "web design",
  "hoursBack": 168,
  "buyerType": "company",
  "maxResults": 50
}
```

#### Cleaning jobs with an exclusion

```json
{
  "service": "sprzątanie",
  "location": "Kraków",
  "hoursBack": 72,
  "excludeKeywords": ["pranie tapicerki"]
}
```

### Supported service shortcuts

The Actor has verified category routing and expanded Polish service vocabulary for common high-demand areas:

- electrician / elektryk
- plumber / hydraulik
- web design / tworzenie stron internetowych
- roofing / dekarz
- painting / malowanie
- renovation / remont
- cleaning / sprzątanie
- accounting / księgowość
- legal / prawnik / adwokat
- solar / fotowoltaika
- heat pumps / pompy ciepła
- air conditioning / klimatyzacja
- moving / przeprowadzki
- marketing / reklama

SEO/pozycjonowanie, grants/dotacje, and other service phrases also work through dynamic category discovery plus request-level keyword validation.

### Input

| Field | Required | Default | What it does |
|---|---:|---:|---|
| `service` | Yes | — | Trade/service to find opportunities for. Polish or English. |
| `location` | No | Poland | City or region to target. |
| `hoursBack` | No | `48` | Hard maximum age of a request in hours. |
| `buyerType` | No | `any` | `any`, `company`, or `private`. |
| `minScore` | No | `55` | Minimum commercial opportunity score, 0–100. |
| `maxResults` | No | `25` | Maximum qualified results returned. |
| `keywords` | No | `[]` | Extra positive terms that raise relevance. |
| `excludeKeywords` | No | `[]` | Terms that strongly penalize unwanted work. |

Advanced API callers can also supply supported internal options such as explicit public Oferteo start URLs and proxy settings, but the Store UI intentionally keeps the main workflow simple.

### Output

Each dataset row is one **qualified opportunity**, not one arbitrary scraped card.

Example:

```json
{
  "decision": "APPLY",
  "score": 93,
  "title": "Zlecenie dla elektryka na montaż instalacji elektrycznej w mieszkaniu, 11-25pkt. el.",
  "location": "Warszawa",
  "ageMinutes": 18,
  "ageLabel": "18 min",
  "customerType": "private",
  "urgencyText": "najbliższy wolny termin",
  "matchedServiceTerms": ["elektryk", "elektrycz", "pkt. el"],
  "whyMatched": [
    "Service match: elektryk, elektrycz, pkt. el",
    "Location match: warszawa",
    "Fresh request: 18 min",
    "Specific scope: 11-25pkt. el.",
    "Verified request"
  ],
  "targetService": "electrician",
  "targetLocation": "Warszawa",
  "url": "https://www.oferteo.pl/zlecenia-elektryczne/warszawa"
}
```

The default dataset view keeps the sales decision fields first. A second `api` dataset view exposes the fuller structured record for downstream systems.

### How qualification works

Service relevance is a **hard gate**. A fresh, urgent request cannot pass merely because it appears on a broad Oferteo page. The request's own public text must contain a recognized signal for the requested service.

After that gate, the deterministic scorer rewards:

- service and extra keyword matches,
- location matches,
- freshness,
- urgency,
- measurable/specific scope,
- verified requests,
- company buyers when requested.

Excluded keywords are strongly penalized. Buyer-type and age filters are applied before scoring.

No LLM is required, so results are fast, explainable, and inexpensive to produce.

### Pricing

This Actor is designed for **pay per event** pricing.

- `apify-actor-start` — Apify's synthetic run-start event, kept at the recommended default **$0.00005** for runs using up to 1 GB RAM
- `qualified-opportunity` — **$0.02** for each qualified opportunity delivered to the default dataset

Platform usage should remain included in the event prices. Users can set a maximum run charge in Apify. A run that finds no qualified opportunities therefore incurs only the tiny synthetic start charge.

### Automation and API use

The Actor works well as a data source for:

- daily lead alerts,
- Google Sheets exports,
- CRM ingestion,
- n8n / Make workflows,
- sales-agent tools,
- scheduled territory monitoring,
- MCP/AI-agent workflows through Apify.

Because the output is deterministic structured JSON, downstream systems do not need to understand Oferteo page markup.

### Responsible-use boundary

The Actor only processes information visible on public Oferteo request-list pages. It intentionally does **not**:

- reveal or reconstruct masked phone numbers or emails,
- log into a user's Oferteo account,
- purchase/unlock contacts,
- submit offers,
- bypass access controls or CAPTCHA challenges.

Users are responsible for complying with applicable laws, Oferteo's terms, and their own outreach obligations.

### Troubleshooting

**No results:** increase `hoursBack`, lower `minScore`, broaden the location, or check whether Oferteo currently has fresh requests for that service.

**Wrong service result:** report the returned title and requested service through the Actor's Issues tab. The service hard gate is designed to reject unrelated requests and can be expanded with new service vocabulary.

**Category changed:** the Actor validates known category pages and falls back to dynamic discovery. If Oferteo changes a route, a run should fall back rather than silently trusting an unrelated page.

### Local development

```bash
npm install
npm test
npm start
```

### Deployment

Connect this GitHub repository to an Actor in Apify Console or deploy with:

```bash
apify login
apify push
```

# Actor input Schema

## `service` (type: `string`):

Required. Enter the trade or service you want leads for. Polish or English works, for example electrician, elektryk, hydraulik, web design, roofing, sprzątanie, accounting, legal, solar, heat pump, or air conditioning.

## `location` (type: `string`):

Optional city or region, for example Warszawa, Piaseczno, Kraków, or Mazowieckie. Leave empty to search across Poland.

## `hoursBack` (type: `integer`):

Only consider requests posted within this many hours. The default 48 hours favors leads that are still fresh.

## `buyerType` (type: `string`):

Choose whether to accept all public requests, companies only, or private individuals only.

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

Only return requests scoring at least this value from 0 to 100. The default 55 balances recall and quality.

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

Maximum number of highest-scoring qualified opportunities to return. You are only charged for delivered qualified opportunities when pay-per-event is enabled.

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

Optional extra words or phrases that should raise relevance, for example Wordpress, instalacja, sklep internetowy, or serwis.

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

Optional words or phrases that strongly disqualify a lead, for example serwis if you only want new installations.

## Actor input object example

```json
{
  "hoursBack": 48,
  "buyerType": "any",
  "minScore": 55,
  "maxResults": 25,
  "keywords": [],
  "excludeKeywords": []
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

## `runSummary` (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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("jabol1983/intent-signals-apify").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("jabol1983/intent-signals-apify").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 '{}' |
apify call jabol1983/intent-signals-apify --silent --output-dataset

```

## MCP server setup

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

```

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/gFaaVbOR3L1HsfSNo/builds/hI3yduRngAi2Qdih2/openapi.json
