# Brazil Public Tenders Monitor - PNCP (Licitacoes) (`sadzinn/pncp-licitacoes-monitor`) Actor

Monitor Brazilian government tenders from the official PNCP API. Keyword and region filters, deduplication across runs, and new-only alerts ready for webhooks.

- **URL**: https://apify.com/sadzinn/pncp-licitacoes-monitor.md
- **Developed by:** [Kauã Fernandes Ferreira](https://apify.com/sadzinn) (community)
- **Categories:** Automation, Lead generation, Other
- **Stats:** 2 total users, 1 monthly users, 25.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.01 / 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/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

## Brazil Public Tenders Monitor - PNCP 🇧🇷📋

**Monitor de licitações do PNCP com alerta de novos editais | Brazilian government tender monitoring**

Track every Brazilian government tender (licitação) published on **PNCP** - the official National Public Procurement Portal - filtered by your keywords, state and value range. Built for **scheduled monitoring**: it remembers what it already reported and returns only what is new.

Monitore licitações públicas brasileiras por palavra-chave, estado e faixa de valor. Feito para rodar agendado: guarda o que já avisou e retorna só o que é novo.

### Why this actor / Por que usar

Brazilian tender monitoring services charge monthly subscriptions to do exactly this. This actor gives you the same alert pipeline, as an API you control:

- 🔔 **New-only alerts** - deduplicates across runs, so a daily schedule returns only fresh tenders (no repeated noise)
- 🔍 **Accent-insensitive keyword matching** - `licenca` matches `LICENÇA`, `Licença`, `licença`
- 🚫 **Exclude terms** - cut the noise you never want to see (merenda, combustível...)
- 📍 **Region filters** - state (UF), city (IBGE code) or a specific government body by CNPJ
- 💰 **Value range** - only tenders inside your ticket size
- 🔗 **Webhook ready** - connect Apify webhooks to Slack, n8n, Make, Zapier or your own endpoint and turn it into a real alert system

### How to set up monitoring / Como montar o monitoramento

1. Run once with `daysBack: 30` to backfill and see the volume you get
2. Tune `keywords` / `excludeKeywords` until the results are all relevant
3. Schedule the actor daily with `daysBack: 1` and `onlyNew: true`
4. Add a webhook on "Run succeeded" pointing to Slack/n8n/your API

From then on you get a clean feed of new tenders matching your business, every day, automatically.

### Input

```json
{
    "keywords": ["software", "licenca de uso", "sistema de gestao"],
    "excludeKeywords": ["merenda", "combustivel"],
    "modalidades": ["6", "8"],
    "uf": "SP",
    "minValue": 20000,
    "daysBack": 1,
    "onlyNew": true
}
```

| Field | Description |
|---|---|
| `keywords` | Match tenders containing any of these terms (accent/case insensitive). Empty = everything |
| `excludeKeywords` | Discard tenders containing any of these |
| `modalidades` | Contracting modes: `6` Pregão Eletrônico, `8` Dispensa, `4` Concorrência Eletrônica, `9` Inexigibilidade, `12` Credenciamento and more |
| `uf` / `municipioIbge` / `cnpjOrgao` | Geographic and government body filters |
| `minValue` / `maxValue` | Estimated value range in BRL |
| `daysBack` | Publication window: `1` for daily monitoring, up to `30` for backfill |
| `onlyNew` | Deduplicate across runs (default `true`) |
| `maxPagesPerModalidade` | 50 tenders per page; raise for nationwide scans |

### Output (one item per tender)

```json
{
    "numeroControlePNCP": "46634242000138-1-000120/2026",
    "objetoCompra": "Contratação de empresa para disponibilização de subscrição do pacote Adobe...",
    "modalidade": "Pregão - Eletrônico",
    "situacao": "Divulgada no PNCP",
    "valorTotalEstimado": 41048.0,
    "orgaoNome": "PREFEITURA MUNICIPAL DE APIAI",
    "orgaoCnpj": "46634242000138",
    "unidadeNome": "Secretaria de Administração",
    "municipio": "Apiaí",
    "uf": "SP",
    "dataPublicacaoPncp": "2026-07-29T08:12:00",
    "dataAberturaProposta": "2026-07-30T09:00:00",
    "dataEncerramentoProposta": "2026-08-12T09:00:00",
    "linkPNCP": "https://pncp.gov.br/app/editais/46634242000138-1-000120/2026",
    "linkSistemaOrigem": "https://...",
    "srp": true
}
```

Every item includes a direct `linkPNCP` to the tender page with the full edital and attachments.

### Use cases / Casos de uso

- **Sales/bid teams**: daily feed of tenders matching what your company sells
- **Consultants**: monitor tenders for multiple clients with one scheduled run each
- **Market intelligence**: what governments in your state are buying, and for how much
- **Competitor watch**: track a specific government body (`cnpjOrgao`) continuously

### FAQ

**Where does the data come from?**
The official PNCP consultation API (`pncp.gov.br/api/consulta`), maintained by the Brazilian federal government under Law 14.133/2021. No scraping, no CAPTCHAs.

**How fast do new tenders appear?**
As soon as the government body publishes on PNCP. A daily run catches everything from the previous day; run it more often for near real-time alerts.

**Does the dedup memory persist between runs?**
Yes - it is stored in the actor's key-value store, keyed per actor run configuration. It keeps the last 60,000 tender IDs.

**Can I get the edital PDF?**
The output includes `linkPNCP` and `linkSistemaOrigem`, where the documents live. Attachment download can be added - open an issue if you need it.

**How many results should I expect?**
For reference: Brazil publishes roughly 3,000+ Pregão Eletrônico and 5,000+ Dispensa tenders **per day** nationwide. Keywords are essential.

### Support / Suporte

Need another filter, attachment download or a different output format? Open an issue on the actor page - responses within 24h. Pode escrever em português.

# Actor input Schema

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

Only return tenders whose object contains at least one of these terms. Accent and case insensitive. Leave empty to get everything. Ex: software, licenca, computador

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

Discard tenders containing any of these terms. Useful to cut noise. Ex: merenda, combustivel

## `modalidades` (type: `array`):

Which contracting modes to monitor. Default: Pregao Eletronico + Dispensa (the highest volume ones).

## `uf` (type: `string`):

Two-letter state code to filter, e.g. SP, RJ, MG. Leave empty for the whole country.

## `municipioIbge` (type: `string`):

IBGE municipality code for city-level filtering, e.g. 3550308 for Sao Paulo.

## `cnpjOrgao` (type: `string`):

Filter tenders from one specific government body by CNPJ (digits only).

## `daysBack` (type: `integer`):

How many days of publications to scan. Use 1 for daily scheduled monitoring, 7-30 for a first backfill.

## `minValue` (type: `integer`):

Only tenders with estimated value at or above this. Tenders with no value are skipped when set.

## `maxValue` (type: `integer`):

Only tenders with estimated value at or below this.

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

Remembers every tender already seen and returns only new ones on the next run. This is what makes scheduled runs alert-ready. Turn off to always return the full window.

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

Optional label to isolate the dedup memory of this monitor, e.g. 'client-acme' or 'software-sp'. Leave empty and the state is keyed automatically by your filters, so different filter sets never mix.

## `maxPagesPerModalidade` (type: `integer`):

Each page holds 50 tenders. Raise for wide nationwide scans, lower to cap usage.

## Actor input object example

```json
{
  "keywords": [
    "software",
    "licenca de uso",
    "sistema de gestao"
  ],
  "modalidades": [
    "6",
    "8"
  ],
  "daysBack": 1,
  "onlyNew": true,
  "maxPagesPerModalidade": 20
}
```

# 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": [
        "software",
        "licenca de uso",
        "sistema de gestao"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("sadzinn/pncp-licitacoes-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 = { "keywords": [
        "software",
        "licenca de uso",
        "sistema de gestao",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("sadzinn/pncp-licitacoes-monitor").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 '{
  "keywords": [
    "software",
    "licenca de uso",
    "sistema de gestao"
  ]
}' |
apify call sadzinn/pncp-licitacoes-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=sadzinn/pncp-licitacoes-monitor",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/Xcvwa0JAQmt2vSP38/builds/yCAV8THg1b0LjVEQw/openapi.json
