# Licitações PNCP Brasil — Contratações e Contratos Públicos (`johnatan029/pncp-licitacoes-brasil`) Actor

Licitações, pregões eletrônicos, dispensas e contratos do governo brasileiro direto da API oficial do PNCP (Lei 14.133). Dados públicos, sem login, com filtros por período, modalidade, UF e palavras-chave.

- **URL**: https://apify.com/johnatan029/pncp-licitacoes-brasil.md
- **Developed by:** [Johnn Mottin](https://apify.com/johnatan029) (community)
- **Categories:** Business, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 registro de resultados

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

## Licitações PNCP Brasil — Contratações e Contratos Públicos

**A licitação do seu setor foi publicada ontem — e o seu concorrente já viu.** Monitore **licitações, pregões eletrônicos, dispensas e contratos do governo brasileiro** direto da API oficial de consulta do **PNCP** (Portal Nacional de Contratações Públicas, Lei 14.133/2021). Dados 100% públicos e oficiais — sem login, sem CAPTCHA.

Actor comunitário não-oficial, **sem afiliação com o Governo Federal, o PNCP ou qualquer órgão público**. Os dados vêm da API oficial de consulta e permanecem sujeitos aos termos da fonte.

Para quem é:

- **Fornecedores B2G**: alerta diário de novas oportunidades no seu setor, UF ou município — filtre por palavras-chave no objeto ("merenda", "pavimentação", "software"…).
- **Consultorias de licitação**: acompanhe órgãos específicos por CNPJ e monte inteligência de concorrência com os contratos firmados (fornecedor vencedor + valores).
- **Integradores e agentes**: saída estável em JSON, pronta para n8n, Make, Google Sheets, ou consumo por agentes de IA (schema documentado abaixo).

### Como funciona

O Actor consulta a API oficial `pncp.gov.br/api/consulta` por **janela de datas**:

- **Modo `contratacoes`** (default): licitações/contratações **publicadas** no período — editais abertos, pregões, dispensas, com valores estimados, situação e link para o sistema de origem.
- **Modo `contratos`**: contratos **firmados** no período — com fornecedor vencedor (CNPJ + razão social) e valores inicial/global.

Janelas longas são fatiadas automaticamente em consultas de 3 dias (a API do PNCP instabiliza com janelas grandes), com retry e backoff educados. Falha de fatia não derruba a coleta: entra em `STATS.sliceFailures` com o erro literal, e a run só falha ruidosamente se a maioria das consultas falhar.

### Input

Exemplo — **alerta diário** (recomendado; janela relativa que nunca precisa de manutenção):

```json
{
  "modo": "contratacoes",
  "diasRetroativos": 3,
  "modalidades": [6],
  "uf": "SP",
  "palavrasChave": ["merenda", "alimentação escolar"],
  "maxResults": 500
}
```

| Campo | Tipo | Default | Descrição |
|---|---|---|---|
| `modo` | string | `contratacoes` | `contratacoes` (publicações) ou `contratos` (firmados) |
| `diasRetroativos` | int 1–90 | `3` | Janela relativa (hoje até N-1 dias atrás) quando as datas ficam vazias |
| `dataInicial`/`dataFinal` | AAAAMMDD | — | Janela absoluta (as duas juntas); tem precedência |
| `modalidades` | int\[] | `[6]` | Códigos oficiais PNCP; obrigatório no modo contratações (exigência da API; uma consulta por código). Ex.: 6 = Pregão eletrônico, 8 = Dispensa — tabela completa no [manual da API de consulta do PNCP](https://www.gov.br/pncp/pt-br/central-de-conteudo/manuais) |
| `uf` | string | — | Sigla (ex.: `SP`) — filtrado pela própria API |
| `municipio` | string | — | Nome do município (acentos ignorados) — filtro pós-coleta |
| `cnpjOrgao` | string | — | CNPJ do órgão (14 dígitos; pontuação ignorada) — filtro pós-coleta |
| `palavrasChave` | string\[] | `[]` | Basta UMA casar com o objeto (acentos/caixa ignorados) — filtro pós-coleta |
| `maxResults` | int | `100` | Teto de registros escritos (máx. 10.000) |

**Cobrança justa**: o evento de resultado conta apenas registros **escritos no dataset** — o que os filtros descartam não custa nada para você.

### Output (shape único nos dois modos; ausente = `null`)

Registro real (pregão eletrônico publicado em 29/07/2026 — dado público oficial):

```json
{
  "fonte": "contratacoes",
  "numeroControlePNCP": "87297982000103-1-000233/2026",
  "dataPublicacaoPncp": "2026-07-29T00:00:48",
  "orgaoCnpj": "87297982000103",
  "orgaoRazaoSocial": "MUNICIPIO DE LAJEADO",
  "uf": "RS",
  "municipio": "Lajeado",
  "objeto": "REGISTRO DE PREÇOS PARA A CONTRATAÇÃO, SOB DEMANDA, DE SERVIÇOS COM EQUIPAMENTOS RODOVIÁRIOS...",
  "modalidadeCodigo": 6,
  "modalidadeNome": "Pregão - Eletrônico",
  "situacao": "Divulgada no PNCP",
  "valorTotalEstimado": 10011189.5,
  "dataAberturaProposta": "2026-07-29T08:00:00",
  "dataEncerramentoProposta": "2026-08-08T09:00:00",
  "linkSistemaOrigem": "https://pregaobanrisul.com.br/editais/0041_2026/354183",
  "fornecedorNome": null,
  "valorGlobal": null
}
```

| Campo | Tipo | Presença | Descrição |
|---|---|---|---|
| `fonte` | string | sempre | `contratacoes` ou `contratos` |
| `numeroControlePNCP` | string | sempre¹ | ID oficial único no PNCP |
| `dataPublicacaoPncp` | string | sempre¹ | Data/hora da publicação |
| `objeto` | string | sempre¹ | Objeto da contratação/contrato |
| `orgaoCnpj` / `orgaoRazaoSocial` | string | sempre¹ | Órgão comprador |
| `orgaoPoder` / `orgaoEsfera` | string | alta | Poder (E/L/J/N) e esfera (F/E/M/D) |
| `uf` / `municipio` / `codigoIbge` / `unidadeNome` | string | alta | Localização da unidade compradora |
| `modalidadeCodigo` / `modalidadeNome` | int/string | só contratações | Modalidade oficial |
| `situacao` | string | só contratações | Ex.: "Divulgada no PNCP" |
| `valorTotalEstimado` / `valorTotalHomologado` | number | quando não sigiloso | Valores da contratação |
| `dataAberturaProposta` / `dataEncerramentoProposta` | string | quando aplicável | Prazos de proposta |
| `tipoInstrumento` / `amparoLegal` / `amparoLegalDescricao` / `modoDisputa` / `srp` | vários | só contratações | Enquadramento legal |
| `anoCompra` / `numeroCompra` / `sequencialCompra` / `processo` | vários | alta | Identificação administrativa |
| `fornecedorNi` / `fornecedorNome` | string | só contratos | Fornecedor vencedor |
| `valorInicial` / `valorGlobal` | number | só contratos | Valores contratados |
| `dataAssinatura` / `dataVigenciaInicio` / `dataVigenciaFim` | string | só contratos | Vigência |
| `tipoContrato` / `numeroContrato` / `anoContrato` | vários | só contratos | Identificação do contrato |
| `linkSistemaOrigem` / `linkProcessoEletronico` | string | quando informado | Link para o edital/processo na origem |
| `informacaoComplementar` / `usuarioNome` / `dataAtualizacao` / `scrapedAt` | string | vários | Metadados |

¹ Campos-core monitorados pelo health check: se mais de 50% vierem nulos a run **falha nomeando o campo** (`DEAD_FIELDS`) — você nunca recebe silenciosamente um dataset quebrado. `STATS` (key-value store) traz completude por campo, consultas por fatia, retries e avisos; `ERRORS` traz falhas com código estável (`HTTP_UNAVAILABLE`, `HTTP_TIMEOUT`, `INVALID_INPUT`, `API_CONTRACT_CHANGED`, `SLICE_FAILED`, `EMPTY_RESULTS`, `DEAD_FIELDS`).

Janela sem publicações (ex.: feriado com `diasRetroativos: 1`) é **sucesso legítimo** sinalizado em `STATS.legitimateEmptyWindow` — distinto de falha de coleta, que sempre é ruidosa.

### Exemplo de consumo (API Apify)

```bash
curl -s "https://api.apify.com/v2/acts/<SEU_USUARIO>~pncp-licitacoes-brasil/run-sync-get-dataset-items?token=<SEU_TOKEN>" \
  -X POST -H "Content-Type: application/json" \
  -d '{"diasRetroativos": 1, "modalidades": [6, 8], "uf": "MG", "maxResults": 200}'
```

### Agende na Apify (recomendado — na nuvem, não no seu desktop)

Alerta de licitação é diário: `diasRetroativos: 3` com uma run por dia. **Use os Schedules da própria Apify, não um agendador local** — configure uma vez e roda na nuvem, com o seu computador ligado ou não.

1. Salve o seu input como **Task** (Console → o Actor → *Create task*), ex.: a sua UF, as suas modalidades e as suas palavras-chave.
2. Console → **Schedules → Create schedule**, adicione a Task e defina o cron (ex.: todo dia às 6h → `0 6 * * *`).
3. Ligue o dataset ao n8n, Make, Sheets, Slack ou webhook pelas integrações da Apify.

Como a janela é relativa (`diasRetroativos`), o agendamento nunca precisa de manutenção — cada run recalcula o período sozinha.

### Limites honestos

- A API do PNCP exige modalidade no modo contratações: cada código da lista vira uma consulta própria (custo proporcional).
- **Janelas grandes sob volume não têm garantia de completude.** A API do PNCP aplica rate limit (HTTP 429) sob volume; nesses casos o Actor entrega **resultado parcial transparente**, nunca um dataset silenciosamente incompleto. Em `STATS`: `slicesOk` / `slicesTotal` mostram quantas consultas completaram, cada fatia perdida entra em `sliceFailures[]` com `code`, `message` e a `query` literal (ex.: `code: "HTTP_RATE_LIMITED"`, `message: "HTTP 429 em /v1/contratacoes/publicacao."`), `warnings[]` recebe `"N/M consulta(s) falharam após retries; resultado parcial."` e `qualityAlert` vira `true`. Janelas curtas (alerta diário, o uso recomendado) não são afetadas na prática.
- `municipio`, `cnpjOrgao` e `palavrasChave` filtram **após** a coleta (a API não oferece esses filtros) — o custo de infraestrutura das páginas descartadas é do Actor, nunca cobrado de você.
- Valores podem ser legitimamente nulos (sigilo previsto em lei).

### Perguntas frequentes

**Preciso de login ou chave de API do PNCP?** Não. O Actor consulta a API oficial e pública do PNCP, sem login e sem CAPTCHA.

**Por que a modalidade é obrigatória no modo contratações?** Porque a própria API do PNCP exige o código de modalidade nessa consulta. Cada código da sua lista vira uma consulta separada — por isso o custo cresce com a quantidade de modalidades.

**Pelo que exatamente eu pago?** Por registro escrito no dataset (Pay Per Event) — o que os filtros de município, CNPJ, palavras-chave ou o `maxResults` descartam não custa nada. A aba Pricing desta página é sempre a fonte autoritativa dos valores vigentes e de qualquer taxa por run.

**Dá para agendar?** Sim — é o uso pretendido. Veja "Agende na Apify" acima.

**Tem alguma ligação com o governo?** Não. Actor comunitário não-oficial, sem afiliação com o Governo Federal, o PNCP ou qualquer órgão público; os dados vêm da API oficial de consulta e permanecem sujeitos aos termos da fonte.

***

### English summary

**Brazil public procurement (PNCP) scraper** — official government API, no login. Two modes: published procurement notices (`contratacoes`: tenders, e-auctions, direct purchases, with estimated values, deadlines and source links) and signed contracts (`contratos`: winning supplier + contract values). Date-window queries with relative-window support (`diasRetroativos`) for maintenance-free daily monitoring, server-side UF filter, client-side keyword/municipality/agency filters (you are only charged for records actually written). Stable flat JSON schema (missing = `null`), loud health checks (`DEAD_FIELDS`, `EMPTY_RESULTS`, `API_CONTRACT_CHANGED`), full run diagnostics in `STATS`/`ERRORS`. Built for n8n/Make/Sheets pipelines and AI agents.

# Actor input Schema

## `modo` (type: `string`):

"contratacoes" retorna licitações/contratações publicadas (editais, pregões, dispensas). "contratos" retorna contratos firmados (com fornecedor e valores).

## `diasRetroativos` (type: `integer`):

Usada quando dataInicial/dataFinal estão vazias: busca de hoje até N-1 dias atrás. Default 3 cobre fins de semana e feriados.

## `dataInicial` (type: `string`):

Opcional. Janela absoluta — informe junto com dataFinal. Ex.: 20260701.

## `dataFinal` (type: `string`):

Opcional. Janela absoluta — informe junto com dataInicial. Ex.: 20260731.

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

Obrigatório no modo contratações (exigência da API). Códigos da tabela oficial de modalidades do PNCP — ex.: 6 = Pregão eletrônico, 8 = Dispensa. Uma consulta por código. Ignorado no modo contratos.

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

Sigla de 2 letras (ex.: SP). Filtro aplicado pela própria API.

## `municipio` (type: `string`):

Nome do município (sem acento também funciona). Filtro aplicado após a coleta — você só paga pelos registros que passarem.

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

14 dígitos (pontuação é ignorada). Filtro aplicado após a coleta.

## `palavrasChave` (type: `array`):

Basta uma das palavras aparecer no objeto da contratação/contrato (sem diferença de acento/caixa). Filtro aplicado após a coleta.

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

Teto de registros escritos no dataset (limite: 10.000). Controla o custo da run.

## `debug` (type: `boolean`):

Logs mais verbosos.

## Actor input object example

```json
{
  "modo": "contratacoes",
  "diasRetroativos": 3,
  "modalidades": [
    6
  ],
  "palavrasChave": [],
  "maxResults": 100,
  "debug": false
}
```

# 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 = {
    "diasRetroativos": 3,
    "modalidades": [
        6
    ],
    "maxResults": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("johnatan029/pncp-licitacoes-brasil").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 = {
    "diasRetroativos": 3,
    "modalidades": [6],
    "maxResults": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("johnatan029/pncp-licitacoes-brasil").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 '{
  "diasRetroativos": 3,
  "modalidades": [
    6
  ],
  "maxResults": 100
}' |
apify call johnatan029/pncp-licitacoes-brasil --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

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