# Brazil PNCP Procurement Notices Scraper (`automation-lab/brazil-pncp-procurement-notices-scraper`) Actor

Search Brazil's official PNCP procurement notices by date, modality, buyer, location, status, and keywords. Export deadlines, values, and source links.

- **URL**: https://apify.com/automation-lab/brazil-pncp-procurement-notices-scraper.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Business
- **Stats:** 2 total users, 1 monthly users, 83.3% 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use 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 PNCP Procurement Notices Scraper

Find public-sector sales opportunities across Brazil from the official **Portal Nacional de Contratações Públicas (PNCP)**.

This Apify Actor searches structured procurement notices by date, modality, buyer, location, status, and keywords. It exports buyer details, proposal deadlines, estimated values, legal basis, and official source links to a clean dataset.

Use it for daily tender monitoring, supplier lead generation, bid pipeline enrichment, market research, or historical procurement exports—without maintaining your own PNCP API integration.

### What does Brazil PNCP Procurement Notices Scraper do?

The Actor queries Brazil's official nationwide PNCP consultation API first. If that service is unavailable, it automatically switches to the official PNCP portal search index so temporary consultation-API failures do not stop otherwise valid searches.

It can:

- 🔎 Search notices by publication, proposal, or update date
- 🏛️ Select one or more PNCP procurement modalities
- 📍 Filter by state (UF) and municipality
- 🧾 Target an exact public organization CNPJ
- 💬 Match keywords in the object, details, process, buyer, and unit
- 🚦 Filter by source status text
- 💰 Export estimated and awarded values in BRL
- ⏰ Capture publication, proposal opening, and closing dates
- 🔗 Include official PNCP and source-system links
- ♻️ Deduplicate results by the PNCP control number

### Why use this PNCP scraper?

PNCP contains procurement opportunities from organizations throughout Brazil, but repeated manual searches do not fit a sales or bidding workflow.

This Actor turns the public source into scheduled, integration-ready data.

- **Save time:** collect many notices in one run.
- **Find relevant opportunities:** combine location, modality, and keyword filters.
- **Build alerts:** run daily and send new deadlines to email, Slack, or a database.
- **Keep provenance:** every row includes its PNCP control ID and official portal URL.
- **Scale safely:** result and page limits control large or sparse searches.

### Who is it for?

#### Brazilian suppliers

Monitor notices related to your products or services and prioritize upcoming deadlines.

#### Bid and tender consultancies

Build recurring client-specific searches by UF, municipality, CNPJ, status, or procurement topic.

#### Procurement software teams

Use normalized JSON as an input to opportunity feeds, qualification tools, and customer alerts.

#### Sales and business development teams

Treat public buyers and active purchases as account and intent signals for CRM enrichment.

#### Researchers and journalists

Export reproducible PNCP records for analysis of buyers, modalities, values, and regions.

### Data you can extract

| Field group | Example fields |
|---|---|
| Identifiers | `noticeId`, `purchaseNumber`, `processNumber` |
| Opportunity | `object`, `additionalInformation`, `status` |
| Buyer | `organizationCnpj`, `organizationName`, `unitName` |
| Geography | `state`, `stateName`, `municipality`, `ibgeCode` |
| Procedure | `modality`, `disputeMode`, `legalBasis`, `instrumentType` |
| Dates | `publicationDate`, `proposalOpenDate`, `proposalCloseDate`, `updatedAt` |
| Values | `estimatedValueBrl`, `awardedValueBrl` |
| Provenance | `sourcePublisher`, `sourceSystemUrl`, `pncpUrl`, `scrapedAt` |

Optional fields are omitted when PNCP does not provide them, rather than emitted as misleading empty values.

### How to scrape PNCP procurement notices

1. Open the Actor in Apify Console.
2. Choose a start and end date in `YYYY-MM-DD` format.
3. Select publication, proposal, or update date semantics.
4. Optionally enter modality codes, keywords, UFs, municipality, buyer CNPJ, or status.
5. Set the maximum number of notices.
6. Click **Start**.
7. Export the dataset as JSON, CSV, Excel, XML, or another supported format.

A narrow first run—one week, one modality, 20 results—is recommended while refining a workflow.

### Input

```json
{
  "startDate": "2026-07-01",
  "endDate": "2026-07-07",
  "dateType": "publication",
  "modalityCodes": ["6"],
  "states": ["SP", "MG"],
  "keywords": "serviços médicos",
  "maxItems": 100,
  "maxPagesPerModality": 100
}
````

#### Input fields

| Field | Type | Description |
|---|---|---|
| `startDate` | string | Inclusive first date, `YYYY-MM-DD` |
| `endDate` | string | Inclusive last date, up to 365 days after the start |
| `dateType` | string | `publication`, `proposal`, or `update` |
| `modalityCodes` | string\[] | PNCP modality codes `"1"`–`"13"`; omitted means all |
| `keywords` | string | All words must appear in searchable notice text |
| `states` | string\[] | Optional two-letter UF codes |
| `municipality` | string | Accent-insensitive partial municipality match |
| `organizationCnpj` | string | Exact buyer CNPJ; punctuation is ignored |
| `status` | string | Case- and accent-insensitive partial status match |
| `maxItems` | integer | Maximum matching unique notices to save |
| `maxPagesPerModality` | integer | Safety cap for sparse client-side filters |

### PNCP modality codes

PNCP assigns numeric codes to procurement modalities.

Common searches include code `6` for **Pregão - Eletrônico**. The Actor accepts any valid PNCP code from 1 through 13.

Leave `modalityCodes` empty to search all modalities. For large periods, selecting only relevant modalities reduces requests and run time.

Source modality names are preserved in Portuguese in the output.

### Date filtering modes

Choose the date field that matches your workflow:

- **Publication:** find notices published during the period.
- **Proposal:** find notices associated with proposal dates during the period.
- **Update:** monitor notices changed during the period.

For daily alerting, `update` can capture changed records while `publication` focuses on newly published opportunities.

### Keyword matching

The keyword filter is applied locally to structured PNCP records.

Every entered word must appear somewhere across:

- procurement object
- additional information
- process number
- organization name
- organization unit

Matching ignores case and accents. For example, `servicos medicos` can match `SERVIÇOS MÉDICOS`.

Use fewer words when a query is too restrictive.

### Output example

```json
{
  "noticeId": "80881915000192-1-000044/2026",
  "purchaseNumber": "PR35",
  "processNumber": "PR35/2026",
  "object": "CONTRATAÇÃO DE EMPRESA PARA ...",
  "organizationCnpj": "80881915000192",
  "organizationName": "MUNICIPIO DE LINDOESTE",
  "unitName": "Prefeitura Municipal de Lindoeste",
  "state": "PR",
  "municipality": "Lindoeste",
  "modalityCode": 6,
  "modality": "Pregão - Eletrônico",
  "status": "Divulgada no PNCP",
  "estimatedValueBrl": 300543,
  "proposalCloseDate": "2026-07-07T08:00:01",
  "pncpUrl": "https://pncp.gov.br/app/editais/80881915000192/2026/44",
  "scrapedAt": "2026-07-20T03:30:00.000Z"
}
```

### How much does it cost to scrape Brazil PNCP notices?

The Actor uses pay-per-event pricing:

- one small **search start** charge per run
- one **procurement notice** charge for each unique row saved

You never pay per page requested. Platform subscription tiers receive automatic volume discounts on per-notice pricing.

Before starting a large export, use `maxItems` to estimate the upper bound from the current pricing panel in Apify Console.

### Scheduling daily PNCP monitoring

Apify schedules can run the Actor automatically.

A practical daily workflow is:

1. Set `startDate` and `endDate` to the monitoring day in a saved task.
2. Use `dateType: "update"` or `publication`.
3. Add business-specific keywords and regions.
4. Schedule the task once per day.
5. Connect a webhook or integration to process the resulting dataset.

For rolling dates, generate task input through the Apify API or an automation platform.

### Integrations

#### Google Sheets

Use the Google Sheets integration to append qualified notices for a bidding team.

#### Slack or email alerts

Trigger an alert when a row meets value, region, or deadline rules.

#### CRM enrichment

Map `organizationCnpj` and `organizationName` to accounts, then add the procurement object as an intent signal.

#### Data warehouse

Export JSON or CSV to BigQuery, Snowflake, PostgreSQL, or object storage for longitudinal analysis.

#### Webhooks

Send a run-finished webhook to your application and retrieve dataset items through the API.

### Use with the Apify API — JavaScript

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/brazil-pncp-procurement-notices-scraper').call({
  startDate: '2026-07-01',
  endDate: '2026-07-07',
  modalityCodes: ['6'],
  maxItems: 50,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

### Use with the Apify API — Python

```python
from apify_client import ApifyClient

client = ApifyClient('YOUR_APIFY_TOKEN')
run = client.actor('automation-lab/brazil-pncp-procurement-notices-scraper').call(run_input={
    'startDate': '2026-07-01',
    'endDate': '2026-07-07',
    'states': ['SP'],
    'maxItems': 50,
})
items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)
```

### Use with the Apify API — cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~brazil-pncp-procurement-notices-scraper/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"startDate":"2026-07-01","endDate":"2026-07-07","modalityCodes":["6"],"maxItems":50}'
```

### Use PNCP data with MCP

Connect Apify's MCP server so an AI assistant can run the Actor and inspect datasets.

MCP endpoint:

```text
https://mcp.apify.com/?tools=automation-lab/brazil-pncp-procurement-notices-scraper
```

Example prompts for Claude Code or another MCP client:

- “Find electronic auctions published in São Paulo this week involving laboratory equipment.”
- “Export 100 updated PNCP notices for this buyer CNPJ and summarize the deadlines.”
- “Compare estimated procurement value by municipality from this dataset.”

#### Claude Code setup

```bash
claude mcp add --transport http apify "https://mcp.apify.com/?tools=automation-lab/brazil-pncp-procurement-notices-scraper"
```

#### Claude Desktop and Cursor setup

Add this `mcpServers` JSON to Claude Desktop or Cursor, then provide your Apify token as required by the MCP server:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com/?tools=automation-lab/brazil-pncp-procurement-notices-scraper"
    }
  }
}
```

#### VS Code setup

Open the MCP configuration in VS Code, add the same HTTP endpoint, and enable the `automation-lab/brazil-pncp-procurement-notices-scraper` tool.

### Tips for reliable searches

- Start with one modality and a short date period.
- Use two-letter uppercase UF codes such as `SP`, `RJ`, or `PR`.
- Remove keywords if a filtered search unexpectedly returns zero rows.
- Increase `maxPagesPerModality` for a very selective buyer or keyword search.
- Split date ranges longer than 365 days into multiple runs.
- Keep the PNCP control number as your downstream deduplication key.

### Pagination and limits

The Actor requests up to 50 source notices per API page.

`maxItems` limits saved matches, not source records inspected. A narrow client-side keyword or CNPJ filter may require scanning many source records before finding matches.

`maxPagesPerModality` prevents an unexpectedly sparse search from running indefinitely. If the cap is reached, refine the date/modalities or intentionally increase it.

### Error handling

Each official PNCP request has a 12-second timeout. If the consultation API returns an error, the Actor switches to the official portal search index. Search-index requests use up to eight bounded attempts with a short delay between attempts.

Invalid dates, reversed periods, overlong periods, and invalid modality codes fail closed with a clear error.

A consultation-API outage alone does not fail the run. The run fails only if the fallback search path also cannot complete, rather than reporting an apparently complete empty dataset.

A valid search that completes successfully but genuinely has no matching records succeeds with an empty dataset.

### Data quality and provenance

PNCP is the source of truth for the returned fields.

The Actor preserves Portuguese names and descriptions instead of translating or inferring legal meaning. It normalizes only field names and matching behavior.

Values and dates may be absent when the publisher did not provide them. Always follow `pncpUrl` or `sourceSystemUrl` for the authoritative current notice.

### Is it legal to scrape PNCP?

PNCP is an official public procurement portal, and the Actor uses its anonymous public consultation and portal search endpoints.

Users are responsible for complying with applicable laws, PNCP terms, data-protection rules, and their own use-case obligations.

Do not treat extracted data as legal advice or as a substitute for checking the current official notice before submitting a proposal.

### FAQ

#### Does the Actor require a PNCP account or API key?

No. The supported consultation endpoints are public and anonymous.

#### Does it use a browser or proxy?

No. It uses official structured HTTPS endpoints—the consultation API and, when needed, the portal search index—which keeps runs lightweight.

#### Why did my keyword search return no notices?

All keyword terms must match. Try fewer words, a broader date range, more modalities, or a higher page cap.

#### Why are some value or deadline fields missing?

The source does not populate every optional field for every notice. Missing fields are omitted rather than fabricated.

#### Can I export historical data?

Yes. Run multiple periods of up to 365 days each and combine datasets using `noticeId` as the deduplication key.

#### Can I monitor one public buyer?

Yes. Set `organizationCnpj` to the exact buyer CNPJ; punctuation is optional.

### Related scrapers

Explore other public-data and lead-generation Actors from [automation-lab](https://apify.com/automation-lab):

- [SAM.gov Scraper](https://apify.com/automation-lab/sam-gov-scraper) for US federal opportunities, when available
- [Company Information Scraper](https://apify.com/automation-lab/company-information-scraper) for business enrichment, when available
- [Government Data Scrapers](https://apify.com/automation-lab) for additional official public sources

Choose this Actor when the required source is Brazil's official PNCP procurement portal.

### Support

If a run behaves unexpectedly, include:

- the Apify run URL
- a redacted copy of the input
- the expected date, modality, and filters
- one example PNCP notice you expected to find

That context makes source changes and filter behavior easier to diagnose.

# Actor input Schema

## `startDate` (type: `string`):

First date to include, in YYYY-MM-DD format.

## `endDate` (type: `string`):

Last date to include, in YYYY-MM-DD format. The range may span up to 365 days.

## `dateType` (type: `string`):

Choose publication, current/upcoming proposal, or last-update dates. Proposal searches require an end date of today or later.

## `modalityCodes` (type: `array`):

Optional PNCP modality codes (1–13). Leave empty to search every modality.

## `keywords` (type: `string`):

Optional words that must all occur in the notice object, additional information, process, buyer, or unit.

## `states` (type: `array`):

Optional two-letter UF codes such as SP, RJ, or MG.

## `municipality` (type: `string`):

Optional municipality name or partial name, accent-insensitive.

## `organizationCnpj` (type: `string`):

Optional exact buyer CNPJ. Punctuation is ignored.

## `status` (type: `string`):

Optional status text such as Divulgada or Encerrada.

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

Stop after this many matching, unique procurement notices.

## `maxPagesPerModality` (type: `integer`):

Safety cap for sparse client-side filters. Each API page contains up to 50 notices.

## Actor input object example

```json
{
  "startDate": "2026-07-01",
  "endDate": "2026-07-07",
  "dateType": "publication",
  "modalityCodes": [
    "6"
  ],
  "keywords": "serviços",
  "states": [],
  "maxItems": 20,
  "maxPagesPerModality": 20
}
```

# Actor output Schema

## `overview` (type: `string`):

API link to the run's filtered procurement notice records.

# 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 = {
    "startDate": "2026-07-01",
    "endDate": "2026-07-07",
    "dateType": "publication",
    "modalityCodes": [
        "6"
    ],
    "keywords": "serviços",
    "states": [],
    "maxItems": 20,
    "maxPagesPerModality": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/brazil-pncp-procurement-notices-scraper").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 = {
    "startDate": "2026-07-01",
    "endDate": "2026-07-07",
    "dateType": "publication",
    "modalityCodes": ["6"],
    "keywords": "serviços",
    "states": [],
    "maxItems": 20,
    "maxPagesPerModality": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/brazil-pncp-procurement-notices-scraper").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 '{
  "startDate": "2026-07-01",
  "endDate": "2026-07-07",
  "dateType": "publication",
  "modalityCodes": [
    "6"
  ],
  "keywords": "serviços",
  "states": [],
  "maxItems": 20,
  "maxPagesPerModality": 20
}' |
apify call automation-lab/brazil-pncp-procurement-notices-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=automation-lab/brazil-pncp-procurement-notices-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Brazil PNCP Procurement Notices Scraper",
        "description": "Search Brazil's official PNCP procurement notices by date, modality, buyer, location, status, and keywords. Export deadlines, values, and source links.",
        "version": "0.1",
        "x-build-id": "M6NBRU8Ug9MbkazPx"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/automation-lab~brazil-pncp-procurement-notices-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-automation-lab-brazil-pncp-procurement-notices-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/automation-lab~brazil-pncp-procurement-notices-scraper/runs": {
            "post": {
                "operationId": "runs-sync-automation-lab-brazil-pncp-procurement-notices-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/automation-lab~brazil-pncp-procurement-notices-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-automation-lab-brazil-pncp-procurement-notices-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "startDate",
                    "endDate"
                ],
                "properties": {
                    "startDate": {
                        "title": "📅 Start date",
                        "type": "string",
                        "description": "First date to include, in YYYY-MM-DD format.",
                        "default": "2026-07-01"
                    },
                    "endDate": {
                        "title": "End date",
                        "type": "string",
                        "description": "Last date to include, in YYYY-MM-DD format. The range may span up to 365 days.",
                        "default": "2026-07-07"
                    },
                    "dateType": {
                        "title": "Date field",
                        "enum": [
                            "publication",
                            "proposal",
                            "update"
                        ],
                        "type": "string",
                        "description": "Choose publication, current/upcoming proposal, or last-update dates. Proposal searches require an end date of today or later.",
                        "default": "publication"
                    },
                    "modalityCodes": {
                        "title": "🏛️ PNCP modality codes",
                        "type": "array",
                        "description": "Optional PNCP modality codes (1–13). Leave empty to search every modality.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "keywords": {
                        "title": "Keywords",
                        "type": "string",
                        "description": "Optional words that must all occur in the notice object, additional information, process, buyer, or unit."
                    },
                    "states": {
                        "title": "Brazilian states (UF)",
                        "type": "array",
                        "description": "Optional two-letter UF codes such as SP, RJ, or MG.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "municipality": {
                        "title": "Municipality",
                        "type": "string",
                        "description": "Optional municipality name or partial name, accent-insensitive."
                    },
                    "organizationCnpj": {
                        "title": "Organization CNPJ",
                        "type": "string",
                        "description": "Optional exact buyer CNPJ. Punctuation is ignored."
                    },
                    "status": {
                        "title": "Notice status",
                        "type": "string",
                        "description": "Optional status text such as Divulgada or Encerrada."
                    },
                    "maxItems": {
                        "title": "📦 Maximum notices",
                        "minimum": 1,
                        "maximum": 100000,
                        "type": "integer",
                        "description": "Stop after this many matching, unique procurement notices.",
                        "default": 100
                    },
                    "maxPagesPerModality": {
                        "title": "Maximum pages per modality",
                        "minimum": 1,
                        "maximum": 10000,
                        "type": "integer",
                        "description": "Safety cap for sparse client-side filters. Each API page contains up to 50 notices.",
                        "default": 100
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
