# Brazilian Public Tenders API — PNCP (structured JSON) (`syntax_void/radar-editais-pncp`) Actor

Brazilian public tenders API (PNCP / licitações). Query open government procurement tenders as clean, structured JSON — filter by keyword, state (UF) and modality, with built-in dedup returning only new tenders each run. For developers and AI agents building on Brazilian public data. No login.

- **URL**: https://apify.com/syntax\_void/radar-editais-pncp.md
- **Developed by:** [Matheus Martins](https://apify.com/syntax_void) (community)
- **Categories:** Developer tools, Lead generation, Automation
- **Stats:** 1 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-usage

## 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

Brazilian Public Tenders API — PNCP (structured JSON)

A clean diff feed of open Brazilian public tenders — built for AI agents and developers. Query tenders from PNCP (Brazil's official procurement portal, Law 14.133/2021) as structured JSON. Filter by keyword, state (UF) and modality. Built-in deduplication means each run returns only tenders you haven't seen before — a true diff feed, not a dump.

Official government source. No login, no credentials, no scraping fragility — it reads the official public consultation API.

Why this Actor

If you're building for the Brazilian public-sector market — a procurement tool, a monitoring product, a fintech serving suppliers, a proposal-drafting AI agent — you need tender data as a reliable, deduplicated feed, not a website to scrape or a raw API to babysit. This Actor gives you that feed: paginated, normalized, filtered, deduplicated, schedulable.

Deduplication keeps your costs down. Because repeated tenders are filtered out before they reach your dataset, a scheduled daily run only processes and delivers what actually entered the system since your last run.

Use with AI agents (MCP)

This Actor works as a tool for AI agents via the Apify MCP server — Claude, Cursor, VS Code or any MCP-compatible client can discover it, run it and read the results.

Hosted (recommended): add https://mcp.apify.com as a remote MCP connector in your client and authorize via OAuth, or point directly at this Actor:

json
{
"mcpServers": {
"apify": {
"command": "npx",
"args": \[
"mcp-remote",
"https://mcp.apify.com/?tools=syntax\_void/radar-editais-pncp",
"--header",
"Authorization: Bearer \<YOUR\_APIFY\_API\_TOKEN>"
]
}
}
}

Example agent prompts once connected:

"Check for new Brazilian public tenders about 'software' in SP and summarize the top 5 by value."
"Run the PNCP tenders tool daily and alert me when a tender over R$1M matches 'oxigênio'."

This Actor runs with limited permissions, so it is safe to expose to an agent: it reads a public API and writes only to its own dataset and key-value store.

What it does
Fetches contracts with an open proposal-submission window from the PNCP consultation API.
Filters and ranks by relevance (accent-insensitive keyword match on object, agency and municipality). Higher matches rank first; ties break by soonest deadline.
Deduplicates across runs (state in the Key-Value Store) — each run returns only new tenders.
Outputs a structured Dataset plus a DIGEST with the top prioritized items.
Retries transient failures. The PNCP API can be slow at times; requests are retried with exponential backoff so a momentary slowdown does not cost you a run.
Input
Field	What it does
keywords	Terms to filter/rank (object, agency, municipality; accent-insensitive). Empty = all open tenders in the selected modalities.
modalidades	PNCP modality codes. Required by the PNCP API — it rejects queries without at least one modality. Defaults to \["6", "8"] (Electronic Auction and Waiver), which cover most procurement. Full table: 1 Electronic Auction (Leilão), 2 Competitive Dialogue, 3 Contest, 4 Electronic Concurrence, 5 In-person Concurrence, 6 Electronic Trading (Pregão Eletrônico), 7 In-person Trading, 8 Waiver (Dispensa), 9 Non-enforceability, 10 Expression of Interest, 11 Pre-qualification, 12 Accreditation, 13 In-person Auction.
ufs	State codes to monitor (e.g., SP, RJ). Empty = all states.
minScore	0 = a tender needs to match at least one keyword. 1 = it must match all keywords. No effect when no keywords are given.
onlyNew	Return only tenders not seen in previous runs (dedup). Keep it on for a clean diff feed.
maxResults, pageSize, maxPagesPerQuery	Volume and cost controls.
Example input
json
{
"keywords": \["software", "tecnologia da informacao"],
"modalidades": \["6", "8"],
"ufs": \["SP", "RJ"],
"onlyNew": true,
"maxResults": 200
}
Example output (one Dataset item per tender)
json
{
"id": "00394494000136-1-000090/2024",
"objeto": "Contratação de serviços de tecnologia da informação",
"orgao": "MINISTERIO DA JUSTICA E SEGURANCA PUBLICA",
"orgao\_cnpj": "00394494000136",
"uf": "AL",
"municipio": "Maceió",
"modalidade": "Pregão - Eletrônico",
"valor\_estimado": 133931.0,
"abertura\_proposta": "2024-06-25T08:00:00",
"encerramento\_proposta": "2024-07-16T09:00:00",
"situacao": "Divulgada no PNCP",
"link": "https://www.gov.br/compras",
"score": 1.0
}
How to use
Set your keywords, states and modalities (or leave empty for the defaults).
Run once — then schedule it (Apify Schedule) for a daily diff feed.
Consume via API, MCP, webhooks, or export as JSON, CSV, Excel or HTML.
Pricing model

Pay per usage. You are billed for the platform resources a run consumes — there is no subscription and no per-tender surcharge. Runs are cheap: a typical daily run over all states finishes in seconds and costs a fraction of a cent. Deduplication keeps that cost stable over time, because repeated tenders are filtered out instead of being reprocessed and re-delivered.

See the Pricing tab for the current rates.

Limitations
Ranking is keyword-relevance based, not semantic — LLM summarization per tender is on the roadmap (V2).
Covers the PNCP. State portals that don't publish to PNCP are out of scope for now.
The underlying data is public; the value here is the clean, deduplicated, agent-ready feed — not exclusive access.
minScore is a coarse switch (0 or 1), not a continuous threshold.
Responsible use & compliance

Reads only public, official PNCP data (companies/agencies and administrative acts — no personal data). It does not replace the official consultation and performs no bidding or participation actions — data retrieval and monitoring only.

FAQ
Do I need a token or login for PNCP? No. The PNCP consultation API is public.
How do I get only today's new tenders? Keep onlyNew on — that's the default.
Do I have to set the modality? No, but the PNCP API requires one, so the Actor defaults to \["6", "8"] if you leave the field empty. Set it explicitly to target other modalities.
Can my AI agent call this tool? Yes — via the Apify MCP server, as shown above. Note that autonomous payment by an agent requires pay-per-event pricing, which this Actor does not use today; your agent calls it under your own Apify account and token.
Can I get tenders opening in the future? It returns tenders whose proposal window is currently open; future-window filtering is a possible extension.

# Actor input Schema

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

Termos para filtrar/ranquear editais (busca no objeto, orgao e municipio; ignora acento/caixa). Vazio = traz todos os editais em aberto das modalidades selecionadas.

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

OBRIGATORIO pela API do PNCP: o endpoint /contratacoes/proposta rejeita a consulta (HTTP 422) sem ao menos uma modalidade. Codigos: 1=Leilao Eletronico, 2=Dialogo Competitivo, 3=Concurso, 4=Concorrencia Eletronica, 5=Concorrencia Presencial, 6=Pregao Eletronico, 7=Pregao Presencial, 8=Dispensa de Licitacao, 9=Inexigibilidade, 10=Manifestacao de Interesse, 11=Pre-qualificacao, 12=Credenciamento, 13=Leilao Presencial. Padrao 6 e 8 cobrem a maior parte das contratacoes.

## `ufs` (type: `array`):

Siglas dos estados a monitorar (ex.: SP, RJ, BA). Vazio = todas as UFs.

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

0 = basta casar uma palavra-chave. 1 = o edital precisa casar TODAS as palavras-chave. Sem efeito quando nenhuma palavra-chave e informada.

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

Se ligado, ignora editais ja entregues em execucoes anteriores (estado no Key-Value Store).

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

Numero maximo de editais retornados por execucao.

## `pageSize` (type: `integer`):

Registros por pagina na API do PNCP (max. 500).

## `maxPagesPerQuery` (type: `integer`):

Limite de paginas por modalidade/UF, para controlar custo de execucao.

## Actor input object example

```json
{
  "keywords": [
    "tecnologia da informacao",
    "software"
  ],
  "modalidades": [
    "6",
    "8"
  ],
  "ufs": [],
  "minScore": 0,
  "onlyNew": true,
  "maxResults": 200,
  "pageSize": 50,
  "maxPagesPerQuery": 10
}
```

# 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": [
        "tecnologia da informacao",
        "software"
    ],
    "modalidades": [
        "6",
        "8"
    ],
    "ufs": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("syntax_void/radar-editais-pncp").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": [
        "tecnologia da informacao",
        "software",
    ],
    "modalidades": [
        "6",
        "8",
    ],
    "ufs": [],
}

# Run the Actor and wait for it to finish
run = client.actor("syntax_void/radar-editais-pncp").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": [
    "tecnologia da informacao",
    "software"
  ],
  "modalidades": [
    "6",
    "8"
  ],
  "ufs": []
}' |
apify call syntax_void/radar-editais-pncp --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,syntax_void/radar-editais-pncp"
        }
    }
}

```

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/seoifF5D8o8zed4hw/builds/HojcdY4jR8WkOoCoy/openapi.json
