# Preço Público Comparável — CATMAT/CATSER (`kman-br/preco-publico-comparavel`) Actor

Pesquisa de preços públicos por CATMAT, CATSER ou descrição, direto do Compras.gov.br com conferência no PNCP. Cesta por código e unidade com média, mediana, menor valor e outliers, com link da fonte em cada preço. Você paga só por preços e cestas válidos.

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

## Pricing

Pay per event

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

## Preço Público Comparável

### Português

Pesquise preços públicos por CATMAT, CATSER ou descrição. O Actor consulta o catálogo oficial, coleta preços do Compras.gov.br e confere resultados homologados no PNCP. Entrega preços com proveniência e uma cesta por código e unidade, com média, mediana, menor valor e marcação de outliers.

#### Começar

O exemplo padrão usa o CATMAT **269520 — cesto de lixo plástico, 50 L, sem tampa**. A data final é fixa para que o exemplo continue reproduzível, sem depender da passagem do tempo:

```json
{
  "catmat": "269520",
  "dataReferencia": "2026-10-13",
  "periodoMeses": 12,
  "minPrecos": 3,
  "removerOutliers": true,
  "maxItems": 30,
  "incluirPncp": true,
  "incremental": false
}
```

Para uma pesquisa atual, use `dataReferencia: ""` ou informe outra data. Na coleta de referência, o exemplo retornou três preços reais: R$ 53,21, R$ 55,00 e R$ 27,33. Média: R$ 45,18; mediana: R$ 53,21; menor: R$ 27,33. A disponibilidade e as correções das fontes oficiais podem alterar resultados posteriores.

Para buscar uma descrição, limpe `catmat` e informe, por exemplo, `descricao: "cesto lixo plástico 50 L sem tampa"`. `tipoCatalogo` seleciona `material` ou `servico`. Para um serviço conhecido, limpe `catmat` e informe `catser`, por exemplo `"5380"`. Cada código descoberto permanece em sua própria cesta: revise características, embalagem e especificação antes de utilizar os preços.

#### Filtros e limites

| Campo | Uso |
| --- | --- |
| `catmat` / `catser` | Um código de material ou serviço; nunca ambos. |
| `descricao`, `tipoCatalogo` | Busca textual no catálogo público quando não há código. |
| `ufs` | Lista de UFs; vazia inclui todas. |
| `periodoMeses`, `dataReferencia` | Janela de meses de calendário, com datas inclusivas. Vazio em `dataReferencia` usa hoje em UTC−03:00. |
| `minPrecos` | Mínimo por cesta, a partir de três preços de compras independentes. |
| `removerOutliers` | Exclui outliers somente das estatísticas; mantém as linhas e suas marcações. |
| `maxItems` | Máximo de linhas de preço. Resumos e diagnósticos são adicionais. |
| `incluirPncp`, `maxComprasPncp` | Confere no PNCP um número limitado de compras descobertas no Compras.gov.br. |
| `maxCatalogos`, `maxPages` | Limitam descoberta textual e paginação. Uma busca truncada produz avisos. |
| `incremental` | `false` sempre entrega os resultados disponíveis; `true` permite uma execução sem itens quando a fonte não mudou. |
| `timeoutSecs` | Timeout de cada requisição e leitura da resposta. |

#### Resultado verificável

O dataset tem linhas `tipo: "preco"`, `tipo: "resumo"` e, quando necessário, `tipo: "diagnostico"`. Todas contêm `source_url`, `source_name`, `retrieved_at` em ISO 8601 UTC−03:00, `source_sha256`, `source_urls`, `warnings`, `status` e `error_message`.

Cada preço inclui código, descrição, unidade, preço unitário em reais, quantidade, órgão, UF, datas, fonte e identidade da compra/item. Valores ausentes permanecem `null` com aviso. O PNCP nem sempre publica CATMAT/CATSER: `codigo_catalogo` fica `null`; `catalogo_consultado` registra o contexto comprovado no Compras.gov.br. `source_urls` registra também as fontes auxiliares de unidade, órgão, vínculo e data. Confirmações entre Compras.gov.br e PNCP substituem a linha correspondente, sem contar duas vezes o mesmo preço.

Cada cesta reúne o mesmo código consultado e a mesma unidade normalizada. Caixa, pacote e unidade permanecem separados; tamanhos de embalagem são preservados e não há conversão automática. Média e mediana são simples, sem ponderar quantidades. O método de outliers é IQR 1,5, com quartis interpolados e pelo menos quatro observações. Com menos de quatro, `outlier` é `null` com aviso. A metodologia e os preços usados nas estatísticas ficam no resumo.

`atende_in65` verifica o mínimo quantitativo, compras independentes, unidade e coleta sem truncamento ou erro de fonte. Ele não certifica conformidade com toda a [IN SEGES/ME 65/2021](https://www.gov.br/compras/pt-br/acesso-a-informacao/legislacao/instrucoes-normativas/instrucao-normativa-seges-me-no-65-de-7-de-julho-de-2021). A decisão sobre comparabilidade, atualidade, condições comerciais e justificativas cabe ao responsável pela pesquisa.

| Status | Significado |
| --- | --- |
| `ok` | Registro completo e sem avisos. |
| `parcial` | Dados utilizáveis com campos ausentes, ressalvas ou limites. |
| `sem_resultado` | Consulta concluída sem correspondências. |
| `fonte_indisponivel` | Timeout, rate limit ou falha transitória esgotou as tentativas. |
| `erro` | Input inválido, layout alterado ou outra falha de processamento. |

Uma falha de fonte sempre gera diagnóstico e mensagem. `RUN_SUMMARY` no Key-Value Store contém contagens, erros, URLs, hashes, cestas, limites e eventos solicitados/cobrados.

#### Repetição, custo e privacidade

O cache usa código/descrição, mês de referência e filtros em um Key-Value Store nomeado. No modo incremental, a primeira página de cada consulta é verificada: contagem **e hash** devem permanecer iguais, e o estado ter menos de sete dias. Nesse caso, a execução grava zero itens e `RUN_SUMMARY.status` é `sem_mudanca`. Falhas, truncamentos e teto de gasto impedem avanço do estado. Alterações em páginas posteriores ou no PNCP que não mudem a primeira página podem ser detectadas apenas após a expiração; deixe `incremental: false` para repetir a coleta completa.

Os eventos são `preco`, por preço válido, e `cesta`, por cesta que satisfaz os critérios quantitativos. Diagnósticos, erros, linhas sem requisitos de validade e cestas incompletas são gratuitos. A aplicação verifica o teto `ACTOR_MAX_TOTAL_CHARGE_USD` antes dos eventos e para ao receber `eventChargeLimitReached`. Quando o teto permite os preços mas não a cesta, entrega o resumo gratuitamente, com aviso. O preço vigente aparece na aba Pricing da Apify Store.

São usadas apenas APIs oficiais públicas. Não há coleta de documentos de pessoas, contatos ou enriquecimento pessoal. Nomes e identificadores de fornecedores e responsáveis são omitidos, incluindo pessoa física; CPFs em texto são mascarados.

O PNCP é consultado por compras vinculadas ao Compras.gov.br. A cobertura não corresponde a uma varredura de todas as contratações nacionais; resultados com unidade, quantidade, código ou preço divergentes ficam sinalizados, sem duplicar a compra. Atas e preços estimados não são tratados como novos preços homologados. Os dados são apoio à pesquisa e devem ser conferidos no processo administrativo.

Fontes: [API Compras.gov.br](https://dadosabertos.compras.gov.br/swagger-ui/index.html), [catálogo CATMAT/CATSER](https://catalogo.compras.gov.br/cnbs-web/busca), [manual de itens PNCP](https://pncp.gov.br/manual/pt-br/2.5/contratacao/consultar_itens_de_uma_contratacao.html).

#### Preço

**US$ 2 por 1.000 preços válidos** (US$ 0,002 por evento `preco`) **+ US$ 0,05 por cesta válida** (evento `cesta`, com pelo menos o mínimo de preços de compras independentes). Exemplo: 3 preços + 1 cesta = US$ 0,056. Diagnósticos, erros, linhas inválidas e cestas incompletas são gratuitos. Sem cobrança por início de execução e sem custo de plataforma para o usuário. O teto de gasto definido por você é respeitado.

### English

Search Brazilian public procurement prices by CATMAT material code, CATSER service code or description. The Actor resolves the official catalogue, collects Compras.gov.br prices and checks awarded item results in PNCP. It returns source-linked price records and a basket for each catalogue code and supply unit, with mean, median, minimum and outlier flags.

The default example is CATMAT **269520**, a plastic 50-litre waste bin without a lid. It uses a fixed end date, `2026-10-13`, and a twelve-month window. The reference collection returned BRL 53.21, 55.00 and 27.33; mean BRL 45.18, median BRL 53.21 and minimum BRL 27.33. Official source availability and corrections may change later results. Set `dataReferencia` to an empty string for today's date in UTC−03:00.

Use the input above to reproduce the example. Clear `catmat` before entering a `catser` or searching `descricao`; use `tipoCatalogo: "material"` or `"servico"` for description searches. `ufs` filters Brazilian states; an empty list includes all states. `maxItems`, `maxPages`, `maxCatalogos` and `maxComprasPncp` bound the collection. Truncated searches are explicitly marked.

Every dataset record includes an exact queried `source_url`, `source_name`, ISO 8601 `retrieved_at` with `-03:00`, response hash, auxiliary source links, warnings, status and error message. Missing fields are `null` with warnings. Status distinguishes a successful empty search (`sem_resultado`), unavailable sources (`fonte_indisponivel`), errors (`erro`) and usable records with caveats (`parcial`). Source failures produce free diagnostics. `RUN_SUMMARY` in the Key-Value Store records counts, source receipts, failures, baskets and billing limits.

Different catalogue codes, units and package sizes are never silently combined. Statistics are unweighted. Outliers use 1.5 IQR with linearly interpolated quartiles and at least four observations; smaller samples have `outlier: null` and a warning. Removing outliers excludes them only from statistics, while retaining the price rows. The `atende_in65` flag checks quantitative minimums, independent purchases and collection completeness, and is not a legal compliance certificate. The procurement officer must review item specifications and commercial conditions.

PNCP results are discovered through officially linked Compras.gov.br purchases, within the configured limit. Matching results replace the corresponding row, avoiding double counting. PNCP may omit its catalogue code; the field stays `null`, while the verified lookup context is retained separately. This is a bounded lookup, not a complete national procurement crawl. Estimated prices and price-registration minutes are not counted as additional awarded prices.

`incremental: false` returns available records on each run. With `true`, a named Key-Value Store retains state for up to seven days: all first-page counts and hashes must match before a zero-item `sem_mudanca` run is allowed. Later-page or PNCP-only changes may not be detected until expiration. Failed or truncated runs do not advance the state.

Billing events are `preco` for a valid price and `cesta` for a qualifying basket. Errors, diagnostics and incomplete baskets are free. The Actor checks `ACTOR_MAX_TOTAL_CHARGE_USD` and stops at `eventChargeLimitReached`. Supplier identities and personal contact fields are omitted; CPF identifiers in text are masked.

Data sources: official Compras.gov.br and PNCP public APIs. This Actor is independent and not affiliated with the Brazilian government.

**Pricing:** **US$2 per 1,000 valid prices** (US$0.002 per `preco` event) **+ US$0.05 per qualifying basket** (`cesta` event). Example: 3 prices + 1 basket = US$0.056. Diagnostics, errors, invalid rows and incomplete baskets are free. No start fee and no platform usage cost for users. Your spending limit is respected.

# Actor input Schema

## `catmat` (type: `string`):

Código de material. Limpe este campo para pesquisar apenas por descrição ou usar CATSER.

## `catser` (type: `string`):

Código de serviço. Não combine com CATMAT.

## `descricao` (type: `string`):

Quando não há código, busca termos no catálogo oficial. Códigos encontrados são cestas separadas; confira a especificação.

## `tipoCatalogo` (type: `string`):

Para busca textual: CATMAT (material) ou CATSER (servico). Um código CATSER determina o tipo automaticamente.

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

Vazio inclui todas as UFs. A UF ausente na fonte não é inferida.

## `periodoMeses` (type: `integer`):

Janela anterior à data de referência, inclusive.

## `dataReferencia` (type: `string`):

AAAA-MM-DD. O exemplo fixa 2026-10-13 para evitar que envelheça. Vazio usa hoje em UTC−03:00.

## `minPrecos` (type: `integer`):

Mínimo por cesta de mesmo código e unidade. IN 65: indicador quantitativo, sem certificação jurídica.

## `removerOutliers` (type: `boolean`):

IQR 1,5 com quartis interpolados; requer pelo menos quatro preços. As linhas continuam visíveis e marcadas.

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

Limite de linhas de preço; resumos e diagnósticos são adicionais. Limitado também por maxPages.

## `incluirPncp` (type: `boolean`):

Rastreia compras encontradas ao PNCP e lê resultados homologados. Uma compra corroborada não é contada duas vezes.

## `maxComprasPncp` (type: `integer`):

Limita a descoberta e conferência no PNCP por execução.

## `maxCatalogos` (type: `integer`):

Descrições podem corresponder a vários códigos. Nunca agrega códigos diferentes numa cesta.

## `maxPages` (type: `integer`):

Busca e preços têm paginação limitada; interrupção é registrada e impede avanço incremental.

## `incremental` (type: `boolean`):

false sempre entrega preços. true pula a entrega após conferir a primeira página se contagem e hash não mudaram, por até sete dias. Usa KV nomeado.

## `timeoutSecs` (type: `integer`):

Inclui a leitura da resposta. Retentativas limitadas para 429, 5xx e falhas de conexão, respeitando Retry-After.

## Actor input object example

```json
{
  "catmat": "269520",
  "catser": "",
  "descricao": "",
  "tipoCatalogo": "material",
  "ufs": [],
  "periodoMeses": 12,
  "dataReferencia": "2026-10-13",
  "minPrecos": 3,
  "removerOutliers": true,
  "maxItems": 30,
  "incluirPncp": true,
  "maxComprasPncp": 3,
  "maxCatalogos": 3,
  "maxPages": 10,
  "incremental": false,
  "timeoutSecs": 30
}
```

# Actor output Schema

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

No description

## `summary` (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 = {
    "catmat": "269520",
    "catser": "",
    "descricao": "",
    "tipoCatalogo": "material",
    "ufs": [],
    "periodoMeses": 12,
    "dataReferencia": "2026-10-13",
    "minPrecos": 3,
    "removerOutliers": true,
    "maxItems": 30,
    "incluirPncp": true,
    "maxComprasPncp": 3,
    "maxCatalogos": 3,
    "maxPages": 10,
    "incremental": false,
    "timeoutSecs": 30
};

// Run the Actor and wait for it to finish
const run = await client.actor("kman-br/preco-publico-comparavel").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 = {
    "catmat": "269520",
    "catser": "",
    "descricao": "",
    "tipoCatalogo": "material",
    "ufs": [],
    "periodoMeses": 12,
    "dataReferencia": "2026-10-13",
    "minPrecos": 3,
    "removerOutliers": True,
    "maxItems": 30,
    "incluirPncp": True,
    "maxComprasPncp": 3,
    "maxCatalogos": 3,
    "maxPages": 10,
    "incremental": False,
    "timeoutSecs": 30,
}

# Run the Actor and wait for it to finish
run = client.actor("kman-br/preco-publico-comparavel").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 '{
  "catmat": "269520",
  "catser": "",
  "descricao": "",
  "tipoCatalogo": "material",
  "ufs": [],
  "periodoMeses": 12,
  "dataReferencia": "2026-10-13",
  "minPrecos": 3,
  "removerOutliers": true,
  "maxItems": 30,
  "incluirPncp": true,
  "maxComprasPncp": 3,
  "maxCatalogos": 3,
  "maxPages": 10,
  "incremental": false,
  "timeoutSecs": 30
}' |
apify call kman-br/preco-publico-comparavel --silent --output-dataset

```

## MCP server setup

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

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/8EJncnjRROHg8eySv/builds/hepQlHyVcKSYU7SS6/openapi.json
