# Colombia SECOP II Public Contracts Scraper (`automation-lab/colombia-secop-ii-public-contracts-scraper`) Actor

Search and export official Colombian SECOP II contracts by buyer, supplier, location, status, category, value, and dates.

- **URL**: https://apify.com/automation-lab/colombia-secop-ii-public-contracts-scraper.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Business
- **Stats:** 1 total users, 1 monthly users, 95.8% 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.

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

## Colombia SECOP II Public Contracts Scraper

Search and export official Colombian SECOP II electronic contracts as structured data.

Filter awarded contracts by public buyer, supplier, geography, status, UNSPSC category, procurement method, value, signature date, and end date. Each result combines normalized fields for analysis with the original official source record.

### What does this Actor do?

The Actor queries Colombia's official open-data copy of **SECOP II - Contratos Electrónicos**.

It returns contract and award intelligence rather than only tender notices:

- contracting entity and NIT;
- awarded supplier and document;
- contract and purchase-process identifiers;
- contract status and procurement method;
- UNSPSC category;
- process description and contract object;
- contract, invoiced, paid, and pending values;
- signature and scheduled end dates;
- public SECOP process URL;
- the complete official source record.

Results are ordered by newest signature date first.

### Who is it for?

#### B2G sales teams

Find public buyers that spend in your category, identify incumbent suppliers, and prioritize agencies with upcoming contract end dates.

#### Colombian suppliers

Monitor awards to competitors, build account lists, and find renewal windows without manually searching contract pages.

#### Procurement intelligence teams

Export repeatable buyer, supplier, category, and value slices into a warehouse or dashboard.

#### Journalists and analysts

Build transparent public-spending datasets from the official source with stable contract identifiers and source links.

#### Compliance teams

Review contract status, suppliers, payment values, and underlying official fields for risk-screening workflows.

### Why use this Actor?

- **Official source:** reads the Colombian government's public Socrata dataset.
- **No login required:** the default workflow needs no SECOP account or API token.
- **Contract-focused output:** buyer, awarded supplier, value, payment, and timing fields are normalized.
- **Composable filters:** combine geography, entity, supplier, status, category, method, value, and dates.
- **Low compute:** direct API requests run with 256 MB memory and no browser.
- **Source transparency:** every available record keeps its official source fields and SECOP link.
- **Automation-ready:** schedule runs, call through the API, or connect datasets to downstream tools.

### What data can you extract?

| Field | Meaning |
| --- | --- |
| `contractId` | Stable SECOP contract identifier |
| `contractReference` | Buyer-facing contract reference |
| `purchaseProcessId` | SECOP purchase-process identifier |
| `contractStatus` | Current status reported by SECOP |
| `entityName` | Contracting public entity |
| `entityNit` | Contracting entity tax identifier |
| `department` | Colombian department |
| `city` | Entity city or municipality |
| `sector` | Government sector |
| `categoryCode` | Main UNSPSC category code |
| `processDescription` | Procurement-process description |
| `contractObject` | Contract purpose/object |
| `contractType` | SECOP contract type |
| `procurementMethod` | Procurement method |
| `supplierName` | Awarded supplier |
| `supplierDocumentType` | Supplier document type |
| `supplierDocument` | Supplier document or tax identifier |
| `contractValueCop` | Contract value in COP |
| `invoicedValueCop` | Invoiced value in COP |
| `paidValueCop` | Paid value in COP |
| `pendingPaymentValueCop` | Value pending payment in COP |
| `signatureDate` | Contract signature date |
| `endDate` | Scheduled contract end date |
| `duration` | Human-readable duration |
| `sourceUrl` | Public SECOP process page |
| `sourceDataset` | Official dataset name |
| `scrapedAt` | Collection timestamp |
| `sourceRecord` | Complete original API object |

Source values may be `null` when the public entity did not provide them.

### How to get started

1. Open the Actor input page.
2. Add one or more filters, or leave them blank for the newest contracts.
3. Set `maxItems` to the maximum records you need.
4. Click **Start**.
5. Review the **Contracts** dataset view.
6. Export JSON, CSV, Excel, XML, or RSS from the dataset.
7. Save the task or schedule it for recurring monitoring.

A useful first run is:

```json
{
  "department": "Antioquia",
  "signedFrom": "2026-01-01",
  "maxItems": 100
}
```

### Input parameters

| Input | Type | Description |
| --- | --- | --- |
| `query` | string | Full-text keywords for descriptions and contract objects |
| `entity` | string | Partial buyer/entity name |
| `entityNit` | string | Exact buyer NIT |
| `supplier` | string | Partial awarded-supplier name |
| `supplierDocument` | string | Exact supplier document |
| `department` | string | Department, such as `Antioquia` |
| `city` | string | City or municipality |
| `status` | string | Partial contract status |
| `categoryCode` | string | Exact main UNSPSC code |
| `procurementMethod` | string | Partial procurement-method name |
| `minContractValue` | number | Minimum contract value in COP |
| `maxContractValue` | number | Maximum contract value in COP |
| `signedFrom` | date | Earliest signature date, inclusive |
| `signedTo` | date | Latest signature date, inclusive |
| `endingFrom` | date | Earliest end date, inclusive |
| `endingTo` | date | Latest end date, inclusive |
| `maxItems` | integer | Maximum records, from 1 to 50,000 |
| `appToken` | string | Optional datos.gov.co Socrata app token |

Dates use `YYYY-MM-DD`.

Text filters are case-insensitive. Exact identifier filters avoid accidental partial matches.

### Useful input recipes

#### Find contracts awarded to a supplier

```json
{
  "supplier": "Microsoft",
  "signedFrom": "2025-01-01",
  "maxItems": 500
}
```

#### Find high-value contracts ending soon

```json
{
  "minContractValue": 100000000,
  "endingFrom": "2026-09-01",
  "endingTo": "2026-12-31",
  "maxItems": 1000
}
```

#### Build a category dataset

```json
{
  "categoryCode": "80111600",
  "department": "Bogotá D.C.",
  "maxItems": 2000
}
```

### Output example

A current result has this shape:

```json
{
  "contractId": "CO1.PCCNTR.8266601",
  "contractReference": "368-2025",
  "purchaseProcessId": "CO1.BDOS.8409837",
  "contractStatus": "Modificado",
  "entityName": "EMPRESA DE VIVIENDA DE ANTIOQUIA-VIVA",
  "entityNit": "811032187",
  "department": "Antioquia",
  "city": "Medellín",
  "categoryCode": "V1.72111000",
  "supplierName": "IDOM CONSULTING, ENGINEERING, ARCHITECTURE S.A.U., Sucursal Colombia.",
  "contractValueCop": 12207395392,
  "signatureDate": "2026-07-24T00:00:00.000",
  "endDate": "2026-12-31T00:00:00.000",
  "sourceUrl": "https://community.secop.gov.co/Public/Tendering/OpportunityDetail/Index?noticeUID=CO1.NTC.8434013",
  "sourceDataset": "SECOP II - Contratos Electrónicos",
  "scrapedAt": "2026-07-27T03:30:00.000Z",
  "sourceRecord": {
    "id_contrato": "CO1.PCCNTR.8266601",
    "estado_contrato": "En ejecución"
  }
}
```

The shortened `sourceRecord` above is illustrative. Dataset items preserve every field returned by the official API.

### How much does it cost to export Colombia SECOP II contracts?

The Actor charges a **$0.005 run-start fee** plus **$0.000041071 per saved contract on the FREE tier**, with lower per-record prices on higher Apify tiers:

| Saved contracts | FREE-tier event cost, including start |
| ---: | ---: |
| 100 | $0.0091 |
| 1,000 | $0.0461 |
| 10,000 | $0.4157 |

Apify platform usage may also apply according to your account plan. Empty results and rejected or duplicate records are not charged as contract events; the one-time start event still applies.

### Scheduling and monitoring workflows

Create a saved task for each market slice you monitor:

1. one task per department or buyer portfolio;
2. one task per supplier or competitor name;
3. one task for contracts ending in the next quarter;
4. one task per important UNSPSC category.

Run tasks weekly or monthly. Use a webhook to notify your pipeline when the run succeeds, then deduplicate on `contractId` in your destination.

Because SECOP records can be updated after first publication, retain the latest row per `contractId` when building historical snapshots.

### Export and integrations

The default dataset works with:

- JSON and CSV downloads;
- Google Sheets and Microsoft Excel;
- Make and Zapier;
- webhooks;
- Python, JavaScript, and REST clients;
- BigQuery, Snowflake, PostgreSQL, or another warehouse;
- BI tools such as Power BI and Tableau.

Use `contractId` as the preferred stable key. Use `sourceUrl` when an analyst needs to inspect the public process page.

### API usage with cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~colombia-secop-ii-public-contracts-scraper/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "department": "Antioquia",
    "signedFrom": "2026-01-01",
    "maxItems": 100
  }'
```

To wait for completion and return dataset items:

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~colombia-secop-ii-public-contracts-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"supplier":"Microsoft","maxItems":100}'
```

### API usage with JavaScript

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor(
  'automation-lab/colombia-secop-ii-public-contracts-scraper'
).call({
  minContractValue: 100000000,
  endingFrom: '2026-09-01',
  endingTo: '2026-12-31',
  maxItems: 1000,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

### API usage with Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor(
    "automation-lab/colombia-secop-ii-public-contracts-scraper"
).call(run_input={
    "query": "servicios de salud",
    "signedFrom": "2026-01-01",
    "maxItems": 500,
})

items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)
```

### Use with Apify MCP

Add the Actor to Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/colombia-secop-ii-public-contracts-scraper"
```

#### Claude Desktop, Cursor, and VS Code setup

Claude Desktop, Cursor, and VS Code can use this equivalent remote MCP configuration:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/colombia-secop-ii-public-contracts-scraper"
    }
  }
}
```

Example prompts:

- “Export 200 SECOP II contracts signed in Antioquia since January 2026.”
- “Find Colombian public contracts above COP 100 million ending next quarter.”
- “Build a CSV of awards to this supplier and group them by buyer entity.”

### Performance and limits

The Actor requests up to 1,000 records per upstream page and stops as soon as `maxItems` is reached.

Requests use deterministic ordering and deduplicate contract IDs within a run.

Transient network errors, HTTP 429 responses, and server errors receive bounded exponential retries.

The Actor does not enable a proxy or browser. Those would increase cost without unlocking a different official dataset.

The optional `appToken` belongs to the user and is sent only to datos.gov.co as `X-App-Token`.

The maximum input limit is 50,000 records per run. Split very broad historical exports into date windows if the official API times out.

### Data freshness and limitations

- Freshness follows the official SECOP II open-data dataset.
- Public entities control the completeness and accuracy of source fields.
- Some older or incomplete records omit supplier, payment, location, or date values.
- The Actor covers electronic contract records in this official dataset; it does not claim to include every Colombian procurement system or every document attachment.
- Full-text search behavior follows Socrata indexing.
- Contract updates may change values or status after an earlier run.
- A Socrata app token can improve rate limits but does not grant private data access.

### Troubleshooting

#### My run returned no records

Remove filters one at a time. Check identifier spelling, use `YYYY-MM-DD` dates, and confirm that `signedFrom` is not later than `signedTo`.

#### The official API timed out

Use a narrower signature-date range, department, entity, or supplier filter. For frequent large exports, provide your own datos.gov.co Socrata app token.

#### I see null fields

Null means the field was absent or empty in the official record. Inspect `sourceRecord` and `sourceUrl` before making compliance or financial decisions.

#### Can I resume from an offset?

The public input intentionally exposes business filters rather than raw SoQL or offsets. Use date windows and stable `contractId` deduplication for repeat exports.

#### Does the Actor scrape PDF attachments?

No. It exports contract-level structured data and the public process URL. Attachment extraction is outside this Actor's scope.

### Responsible use and legality

SECOP II contract data is public procurement information, but public availability does not remove every legal or ethical obligation.

Use the data for legitimate procurement, research, transparency, compliance, and business-intelligence purposes. Follow applicable Colombian law, datos.gov.co terms, Apify terms, and your organization's retention policies.

Supplier and representative identifiers may be personal data in some contexts. Minimize collection, secure exports, and avoid using records for harassment, discrimination, or unsupported allegations.

Always verify consequential decisions against the linked official record. This Actor is a data-access tool, not legal, procurement, sanctions, or financial advice.

### Related Automation Lab Actors

- [SAM.gov Government Contracts Scraper](https://apify.com/automation-lab/samgov-government-contracts-scraper) for United States federal opportunities.
- [World Bank Procurement Notices Scraper](https://apify.com/automation-lab/world-bank-procurement-notices-scraper) for international development procurement.
- [UK Find a Tender Scraper](https://apify.com/automation-lab/uk-find-a-tender-scraper) for United Kingdom notices.

These Actors cover different sources and should not be treated as substitutes for official Colombian SECOP II contract records.

### FAQ

#### Is a SECOP account required?

No. The Actor uses the anonymous official open-data endpoint.

#### Is a Socrata app token required?

No. It is optional for users who need higher upstream request limits.

#### Are values converted to USD?

No. Monetary values remain in Colombian pesos so the output matches the official record.

#### Can I filter by buyer and supplier together?

Yes. All provided filters are combined, so the result must match both.

#### Can I monitor renewals?

Use `endingFrom`, `endingTo`, and optionally `minContractValue`. Schedule the task and deduplicate by `contractId` downstream.

#### Does an empty run cost contract events?

No. The Actor charges the `contract` event only for records saved to the default dataset.

#### Does the Actor publish or modify procurement data?

No. It only reads and normalizes the official public dataset.

#### What should I use as a database key?

Use `contractId` when present. Keep `contractReference` and `purchaseProcessId` for joining and analyst review.

# Actor input Schema

## `query` (type: `string`):

Text found in the process description or contract object.

## `entity` (type: `string`):

Partial buyer/entity name, case-insensitive.

## `entityNit` (type: `string`):

Exact contracting entity tax identifier (NIT).

## `supplier` (type: `string`):

Partial awarded supplier name, case-insensitive.

## `supplierDocument` (type: `string`):

Exact supplier document or tax identifier.

## `department` (type: `string`):

Colombian department, such as Antioquia or Bogotá D.C.

## `city` (type: `string`):

Contracting entity city or municipality.

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

Partial SECOP contract status, such as En ejecución or Modificado.

## `categoryCode` (type: `string`):

Exact main UNSPSC category code from SECOP.

## `procurementMethod` (type: `string`):

Partial procurement method name, case-insensitive.

## `minContractValue` (type: `number`):

Minimum contract value in Colombian pesos.

## `maxContractValue` (type: `number`):

Maximum contract value in Colombian pesos.

## `signedFrom` (type: `string`):

Earliest signature date, inclusive (YYYY-MM-DD).

## `signedTo` (type: `string`):

Latest signature date, inclusive (YYYY-MM-DD).

## `endingFrom` (type: `string`):

Earliest contract end date, inclusive (YYYY-MM-DD).

## `endingTo` (type: `string`):

Latest contract end date, inclusive (YYYY-MM-DD).

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

Maximum number of matching contract records to save.

## `appToken` (type: `string`):

Optional datos.gov.co app token for higher upstream rate limits. The default workflow does not require one.

## Actor input object example

```json
{
  "department": "Antioquia",
  "signedFrom": "2026-01-01",
  "maxItems": 20
}
```

# Actor output Schema

## `dataset` (type: `string`):

Default dataset containing normalized SECOP II contracts.

# 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 = {
    "department": "Antioquia",
    "signedFrom": "2026-01-01",
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/colombia-secop-ii-public-contracts-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 = {
    "department": "Antioquia",
    "signedFrom": "2026-01-01",
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/colombia-secop-ii-public-contracts-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 '{
  "department": "Antioquia",
  "signedFrom": "2026-01-01",
  "maxItems": 20
}' |
apify call automation-lab/colombia-secop-ii-public-contracts-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=automation-lab/colombia-secop-ii-public-contracts-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/l7vJeshjR3p9x0dkM/builds/vk0rpxpMNoC4X7fzd/openapi.json
