# Brazil Public Tenders & Procurement (Licitações BR) (`kman-br/licitacoes-br`) Actor

Licitações e contratações públicas do Brasil direto do PNCP oficial. Filtros por período, UF, município, modalidade, palavras-chave e CNPJ do órgão. Você paga só pelas licitações retornadas, com link da fonte oficial.

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

## Pricing

$0.90 / 1,000 licitação retornadas

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

## Licitações BR — PNCP

**Português** · [English](#english)

Busca licitações e contratações públicas do Brasil direto do **PNCP — Portal Nacional de Contratações Públicas**, a fonte oficial da Lei 14.133/2021. Você filtra por período, UF, município, modalidade, palavras-chave e CNPJ do órgão e recebe registros estruturados, cada um com o link para conferir na fonte.

### O que você recebe

Cada licitação vira um registro com:

| Campo | O que é |
|---|---|
| `orgao`, `cnpj` | Órgão comprador e CNPJ |
| `objeto` | O que está sendo contratado |
| `valorEstimado` | Valor total estimado (R$), quando a fonte informa |
| `modalidade`, `modoDisputa`, `situacao` | Ex.: "Pregão - Eletrônico", "Aberto", "Divulgada no PNCP" |
| `valorHomologado` | Valor total homologado (R$); `null` com aviso enquanto a licitação não foi homologada |
| `numeroCompra`, `processo` | Número da compra e do processo administrativo, como na fonte |
| `dataPublicacao`, `dataAbertura`, `dataEncerramentoProposta` | Horário de Brasília, como na fonte |
| `uf`, `municipio`, `codigoMunicipioIbge`, `unidade` | Onde fica a unidade compradora |
| `linkEdital` | Página do edital no PNCP |
| `linkSistemaOrigem` | Sistema onde a disputa acontece, quando informado |
| `numeroControlePNCP` | Identificador único no PNCP |

E, em **todo** registro, os campos de verificação:

| Campo | O que é |
|---|---|
| `source_url` | URL do registro na API oficial do PNCP, para conferir |
| `source_name` | `PNCP - API de Consulta` |
| `retrieved_at` | Data e hora da coleta (ISO 8601, horário de Brasília) |
| `status` | `ok`, `sem_resultado`, `fonte_indisponivel` ou `erro` |
| `warnings[]` | Avisos sobre o registro (ex.: valor não informado); vazio se não houver |
| `error_message` | Motivo, quando o status não é `ok` |

**Sem resultado não é o mesmo que fonte fora do ar.** Se a busca não encontrar nada, o dataset recebe um registro `sem_resultado`. Se o PNCP falhar (timeout, erro 5xx ou limite de requisições) mesmo depois das novas tentativas, o dataset recebe um registro `fonte_indisponivel` com a mensagem e a consulta que falhou. O Actor nunca devolve um dataset vazio em silêncio. O resumo da execução fica no key-value store, na chave `RESUMO`.

### Filtros

| Input | Como funciona |
|---|---|
| `dataInicial`, `dataFinal` | Período de publicação (AAAA-MM-DD). Padrão: últimos 7 dias. Acima de 365 dias, o período é dividido automaticamente (máx. 5 anos) |
| `uf` | Sigla do estado |
| `municipio` | Código IBGE de 7 dígitos (filtro direto na fonte, recomendado) ou nome (filtro após a coleta; informe a UF junto) |
| `queryType` | `publicacao` (padrão): licitações publicadas no período. `proposta`: **somente licitações com recebimento de propostas aberto**; só `dataFinal` vale (teto do encerramento das propostas; padrão hoje + 30 dias) e `dataInicial` é ignorada |
| `modalidades` | **Lista** de modalidades da Lei 14.133, buscadas de uma vez (ex.: pregão eletrônico e dispensa). Vazio = todas (publicação, começando por pregão eletrônico e dispensa) ou uma consulta única sem filtro (propostas abertas) |
| `modalidade` | Campo antigo, mantido por compatibilidade: uma modalidade. Se informado junto com `modalidades`, as duas se somam |
| `palavrasChave` | Retorna se o objeto ou a informação complementar contiver **qualquer** uma das palavras, como trecho de texto (sem diferenciar acentos e maiúsculas). "computador" também encontra "computadorizado" |
| `cnpjOrgao` | CNPJ do órgão comprador |
| `maxItems` | Para ao atingir este número de licitações |
| `maxPaginasPorConsulta` | Avançado: limite de páginas de 50 registros por modalidade e período |
| `intervaloMs` | Avançado: ritmo mínimo entre chamadas ao PNCP (padrão 1,2 s) |

Exemplo:

```json
{ "dataInicial": "2026-10-01", "dataFinal": "2026-10-02", "uf": "SP", "modalidade": "6", "palavrasChave": ["software", "computador"], "maxItems": 50 }
```

### Bom saber

- **Fonte oficial e pública.** Só são coletados dados públicos de contratação publicados no PNCP. Nenhum dado pessoal é enriquecido nem cruzado com outras fontes (LGPD).
- **Texto livre da fonte.** O campo `objeto` (e outros textos livres) vem exatamente como o PNCP publica e pode conter dados pessoais publicados pelo próprio órgão público; o Actor não filtra, enriquece nem cruza esses dados.
- **Ritmo respeitoso.** A API do PNCP limita rajadas (HTTP 429). O Actor espera entre chamadas, respeita `Retry-After` e tenta de novo em erros temporários.
- **Palavras-chave e município por nome** são filtros feitos depois da coleta: em períodos longos, sem UF, eles podem varrer muitas páginas. Para buscas grandes, prefira UF, código IBGE ou modalidade.
- **Valor 0** aparece em orçamentos sigilosos e registros de preços; o registro traz um aviso.

### Tempo limite do run

O Actor acompanha o tempo limite da execução e encerra a coleta cerca de 45 segundos antes dele, sem iniciar novas esperas de nova tentativa que passariam do prazo. O que já foi coletado é entregue: o run termina com status `parcial` e `motivo: tempo_limite_run` no resumo (`RESUMO`) e na mensagem de status, com um aviso indicando onde a coleta parou. Se o prazo chegar antes de qualquer licitação, o dataset recebe um registro de status `fonte_indisponivel` com a mensagem `tempo limite do run se aproximando`; esse registro não é cobrado. Para evitar a parada, reduza o período ou as modalidades, ou aumente o timeout do run.

### Preço

Pagamento por evento (`licitacao-retornada`): **US$ 0,0009 por item (US$ 0,90 por 1.000)**, somente itens com `status: ok`. Registros de status (`sem_resultado`, `fonte_indisponivel`, `erro`) não são cobrados. Não há cobrança por início de execução. O teto de gasto definido por você é respeitado: ao atingi-lo, a execução para.

***

<a id="english"></a>

## Licitações BR — Brazilian public procurement (PNCP)

Fetches Brazilian public tenders and contracts straight from **PNCP — Portal Nacional de Contratações Públicas**, the official source under Law 14.133/2021. Filter by date range, state (UF), municipality, procurement method, keywords and buyer CNPJ, and get structured records, each with a link to check it at the source.

### Output

Each tender becomes a record with the buyer (`orgao`, `cnpj`), object (`objeto`), estimated value in BRL (`valorEstimado`), method and status (`modalidade`, `situacao`), dates in Brasília time (`dataPublicacao`, `dataAbertura`, `dataEncerramentoProposta`), location (`uf`, `municipio`, `codigoMunicipioIbge`, `unidade`), the PNCP notice page (`linkEdital`), the bidding system link (`linkSistemaOrigem`) and the PNCP id (`numeroControlePNCP`).

Every record also carries verification fields: `source_url` (the record in the official PNCP API), `source_name`, `retrieved_at` (ISO 8601, Brasília time), `status` (`ok` | `sem_resultado` | `fonte_indisponivel` | `erro`), `warnings[]` and `error_message`.

**No results is not the same as source down.** An empty search yields one `sem_resultado` record. A PNCP outage (timeout, 5xx, rate limit) that persists after retries yields a `fonte_indisponivel` record with the message and the failed query. The dataset is never silently empty. A run summary is saved under the `RESUMO` key.

### Input

`dataInicial` / `dataFinal` (YYYY-MM-DD; default last 7 days; with `queryType: "proposta"` only `dataFinal` applies, as the cap for the proposal deadline, default today + 30 days, and `dataInicial` is ignored; ranges over 365 days are split automatically, up to 5 years), `uf`, `municipio` (7-digit IBGE code, or name filtered after fetching), `modalidade` (1–13; empty = all), `palavrasChave` (matches ANY keyword as a substring in the object or complementary info, accent- and case-insensitive), `cnpjOrgao`, `maxItems`, plus advanced `maxPaginasPorConsulta` and `intervaloMs`.

**New in v2:** `queryType` (`publicacao` = by publication date, default; `proposta` = only tenders still open for proposals) and `modalidades` (a list of methods queried in one run; the old single `modalidade` still works and is added to the list). New output fields: `valorHomologado`, `modoDisputa`, `numeroCompra`, `processo` (`null` plus a warning when the source omits them).

### Notes

- Only public procurement data published by PNCP; no personal-data enrichment (LGPD).
- The `objeto` field and other free-text fields are copied as published by PNCP and may contain personal data that the public agency itself published; this Actor does not filter, enrich or cross-reference it.
- PNCP rate-limits bursts (HTTP 429); the Actor paces requests, honors `Retry-After` and retries transient errors.
- Keyword and municipality-name filters run after fetching; for large searches, narrow by state, IBGE code or method.
- A value of 0 usually means a confidential budget or a price registration; the record carries a warning.

### Run time limit

The Actor watches the run timeout and stops collecting about 45 seconds before it, never starting a retry wait that would pass the deadline. Everything already collected is delivered: the run ends with status `parcial` and `motivo: tempo_limite_run` in the `RESUMO` summary and the status message, plus a warning showing where it stopped. If the deadline arrives before any tender is found, the dataset gets one free (not charged) status record `fonte_indisponivel` with the message `tempo limite do run se aproximando`. To avoid it, narrow the period or modalities, or raise the run timeout.

### Pricing

Pay per event (`licitacao-retornada`): **US$ 0.0009 per item (US$ 0.90 per 1,000)**, only for items with `status: ok`. Status records (`sem_resultado`, `fonte_indisponivel`, `erro`) are free. No run-start charge. Your spending limit is respected: the run stops when it is reached.

### Related Actors

More Actors from the same publisher:

- [Brazil Expiring Gov Contracts PNCP (Contratos a Vencer)](https://apify.com/kman-br/contratos-a-vencer): PNCP public contracts ending within a chosen window of days, with the current supplier (company CNPJ) and value.
- [Brazil Framework Agreements PNCP (Atas para Carona)](https://apify.com/kman-br/atas-carona-pncp): Active PNCP price registration agreements (Atas de Registro de Preço) open to adhesion, with items, prices and validity.
- [Brazil Public Tender Prices CATMAT/CATSER (Preço Público)](https://apify.com/kman-br/preco-publico-comparavel): Public purchase prices by CATMAT, CATSER or description from Compras.gov.br, cross-checked on PNCP.
- [EU TED Tenders Scraper (Licitações da UE)](https://apify.com/kman-br/eu-ted-tenders): EU public procurement notices from the TED Search API v3, normalized: title, buyer, country, CPV, value and deadline.
- [Brazil CNPJ Bulk Lookup - Receita Federal (CNPJ em Lote)](https://apify.com/kman-br/cnpj-lote): Bulk lookup of Brazilian company CNPJs in Receita Federal open data. Companies only, no partners or contacts.

Browse the full catalog: [kman-br.github.io](https://kman-br.github.io/) ([Português](https://kman-br.github.io/pt/)).

# Actor input Schema

## `queryType` (type: `string`):

publicacao (padrão): licitações publicadas no período dataInicial..dataFinal. proposta: somente licitações com recebimento de propostas ABERTO; nesse modo só dataFinal vale (teto do encerramento das propostas; padrão: hoje + 30 dias) e dataInicial é ignorada.

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

Início do período de publicação no PNCP (AAAA-MM-DD). Padrão: 6 dias antes da data final. Ignorado em queryType=proposta. Períodos acima de 365 dias são divididos automaticamente (máx. 5 anos).

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

Fim do período de publicação (AAAA-MM-DD). Padrão: hoje, no horário de Brasília. Em queryType=proposta: teto do encerramento das propostas (padrão: hoje + 30 dias).

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

Sigla do estado da unidade compradora. Vazio = todo o Brasil.

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

Código IBGE de 7 dígitos (filtro direto na API, recomendado) ou nome do município (filtro após a coleta; informe também a UF).

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

Uma ou mais modalidades da Lei 14.133/2021, consultadas de uma vez. Vazio = todas (publicação, em ordem de volume) ou uma consulta única sem filtro de modalidade (propostas abertas).

## `modalidade` (type: `string`):

Campo antigo, mantido por compatibilidade: uma única modalidade. Prefira "Modalidades"; se os dois forem informados, as modalidades são somadas.

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

Retorna licitações cujo objeto ou informação complementar contenha QUALQUER uma das palavras (sem diferenciar acentos e maiúsculas). Filtro aplicado após a coleta.

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

CNPJ do órgão comprador (14 dígitos; pontuação é ignorada).

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

Para ao atingir este número de licitações retornadas (cada uma é um evento cobrado).

## `maxPaginasPorConsulta` (type: `integer`):

Proteção de custo e de carga na fonte: páginas de 50 registros lidas por modalidade e janela de datas. Relevante quando há palavras-chave ou município por nome.

## `intervaloMs` (type: `integer`):

Ritmo mínimo entre chamadas à API do PNCP, que limita rajadas (HTTP 429).

## Actor input object example

```json
{
  "queryType": "publicacao",
  "maxItems": 100,
  "maxPaginasPorConsulta": 20,
  "intervaloMs": 1200
}
```

# Actor output Schema

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

Itens do dataset padrão.

# 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("kman-br/licitacoes-br").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("kman-br/licitacoes-br").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 kman-br/licitacoes-br --silent --output-dataset

```

## MCP server setup

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

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/3iZ1T1va17YSvHQKa/builds/8PrCM0V1bIXezWg7w/openapi.json
