# OMNIA Partners Contracts Scraper (`gallant_illustration/omnia-partners-scrapper`) Actor

Export OMNIA Partners, NCPA and US Communities cooperative contracts to CSV, Excel or JSON: suppliers, lead agencies, expiration dates, categories and contract PDFs. Filter by program, industry or category and find contracts expiring soon (upcoming rebids).

- **URL**: https://apify.com/gallant\_illustration/omnia-partners-scrapper.md
- **Developed by:** [Alexei Pannicov](https://apify.com/gallant_illustration) (community)
- **Categories:** Lead generation, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 contracts

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

## OMNIA Partners Contracts Scraper

**OMNIA Partners, NCPA & US Communities cooperative contracts** — export the
full OMNIA Partners contract registry to CSV, Excel or JSON: suppliers, lead
agencies, terms and expiration dates, categories, state adoptions and direct
links to contract documents (PDF). Filter by program, industry or category and
**find contracts expiring soon** — the upcoming rebids.

The Actor reads the registry from
[omniapartners.com](https://www.omniapartners.com) — an OMNIA Partners
contract search API alternative — and enriches every contract with supplier
data.

It covers every program listed in the OMNIA contract search — OMNIA Public
Sector, OMNIA Private Sector, NCPA, US Communities and more — including
private-sector contracts.

### What this Actor does

- **Uses OMNIA's own search API** — reads the same JSON the website uses, so
  it is fast, needs no browser, proxy or login, and returns clean, typed data
- **Full registry, not just the first page** — pages through all results and
  reconciles the collected count with the total reported by the API
- **Contract documents** — every document comes with a direct
  `download_url` to the PDF
- **Supplier enrichment** — each contract carries the supplier's website,
  industry, active contract count, first contract date and parent company
- **Rich filtering** — full-text search, 8 server-side filters (industry,
  sector, cooperative, vertical, award structure, subcategory, lead agency,
  state) and 4 client-side filters (category, new only, state-adopted only,
  expiring within N days), plus `maxItems`
- **Apify platform advantages** — run on a schedule, trigger via API,
  connect to integrations, and monitor runs from the Apify Console

### Who is it for

- **Public-sector procurement teams** checking which cooperative contracts
  already cover a need before running their own RFP
- **Supplier sales and business-development teams** tracking competitors,
  lead agencies and contracts coming up for expiration
- **Market-intelligence analysts and consultants** who need an up-to-date,
  machine-readable copy of the OMNIA contract registry

### Use cases

#### NCPA contract list

Every contract awarded through NCPA (National Cooperative Purchasing
Alliance), with lead agency, supplier, expiration date and contract PDFs.

```json
{ "sourcingEntities": ["NCPA"] }
```

#### US Communities contracts

US Communities is now part of OMNIA Partners — its contracts sit in the same
registry and are selected by program.

```json
{ "sourcingEntities": ["US Communities"] }
```

#### Expiring cooperative contracts → upcoming rebids

Contracts that end in the next N days are the ones about to be re-solicited.
Suppliers use this to prepare for the rebid or to reach agencies before the
incumbent's contract runs out.

```json
{ "expiresWithinDays": 90 }
```

#### K-12 and higher-education contracts

School districts, colleges and universities buy through cooperative contracts
heavily. Filter by the industry the contract is open to:

```json
{ "industries": ["k12"] }
```

### ⚡ Ready-made tasks

Start from a preconfigured task — open it, adjust the input if needed, and
click **Start**:

- [NCPA contracts list](https://apify.com/gallant_illustration/omnia-partners-scrapper/examples/omnia-ncpa-contracts)
- [US Communities contracts](https://apify.com/gallant_illustration/omnia-partners-scrapper/examples/omnia-us-communities-contracts)
- [OMNIA contracts expiring in the next 90 days](https://apify.com/gallant_illustration/omnia-partners-scrapper/examples/omnia-contracts-expiring-next-90-days)
- [New OMNIA Partners cooperative contracts](https://apify.com/gallant_illustration/omnia-partners-scrapper/examples/omnia-new-cooperative-contracts)
- [K-12 school contracts](https://apify.com/gallant_illustration/omnia-partners-scrapper/examples/omnia-k12-school-contracts)
- [Higher education contracts](https://apify.com/gallant_illustration/omnia-partners-scrapper/examples/omnia-higher-education-contracts)
- [IT & telecom contracts](https://apify.com/gallant_illustration/omnia-partners-scrapper/examples/omnia-it-telecom-contracts)
- [Construction, architecture & engineering contracts](https://apify.com/gallant_illustration/omnia-partners-scrapper/examples/omnia-construction-contracts)

### 🚀 How to use

1. Open the Actor's **Input** tab. Leave everything empty to get the whole
   registry, or set a search query and filters.
2. Optionally set `maxItems` for a cheap test run.
3. Click **Start**.
4. Open the **Output** tab when the run finishes, or fetch the dataset via
   the API in JSON, CSV, Excel and other formats.

### Input

All input fields are optional. Empty fields mean "no restriction". Within a
list field, values are combined with **OR** (a contract matches if it has at
least one of them); different fields are combined with **AND**.

| Field | Type | Where applied | Description |
|-------|------|---------------|-------------|
| `query` | string | server | Full-text search over contract title and description |
| `industries` | string\[] | server | `government`, `higher_ed`, `k12`, `nonprofit`, `business_commercial`, `private_equity`, `real_estate` |
| `contractSectors` | string\[] | server | `Public`, `Private` |
| `sourcingEntities` | string\[] | server | Cooperative / program: `OMNIA Public Sector`, `OMNIA Private Sector`, `NCPA`, `US Communities`, `BA`, `Prime Advantage`, `National IPA`, `Premier` |
| `verticals` | string\[] | server | e.g. `IT & Telecom`, `Furniture`, `Food and Nutrition` (dropdown) |
| `awardStructures` | string\[] | server | `Single-Award`, `Multi-Award` |
| `subcategories` | string\[] | server | Exact, case-sensitive match, e.g. `Software` |
| `leadAgencies` | string\[] | server | Exact, case-sensitive match, e.g. `Region 4 Education Service Center` |
| `stateAdoptedStates` | string\[] | server | Two-letter state codes, e.g. `UT` |
| `categories` | string\[] | Actor | One or more of 24 OMNIA categories (dropdown) |
| `newOnly` | boolean | Actor | Keep only contracts OMNIA marks as new. `false` means no restriction, not "old only" |
| `stateAdoptedOnly` | boolean | Actor | Keep only contracts adopted by at least one state |
| `expiresWithinDays` | integer ≥ 0 | Actor | Keep only contracts expiring within N days (`0` = today or already expired) |
| `maxItems` | integer ≥ 1 | last | Caps the number of delivered contracts, applied after all filters |

Server-side filters are applied by the OMNIA API before paging, so fewer
requests are made. Actor-side filters are applied after all pages are
collected, because the API does not support them reliably.

### Output

Each dataset item is one contract. Example (documents shortened):

```json
{
  "id": "150457",
  "contract_number": "05-80",
  "supplier_id": "5700",
  "salesforce_id": "0014M00002LlCHKQA3",
  "supplier": "iPARQ",
  "website_display_name": "iParq",
  "contract_title": "Parking Enforcement Software and Equipment",
  "solicitation_number": "S1039",
  "lead_agency": "Region 14 Education Service Center",
  "lead_agency_id": "0016100000O6uSYAAZ",
  "contract_sector": "Public",
  "cooperative_scope": "NCPA",
  "industries": ["k12", "higher_ed", "government", "nonprofit"],
  "categories": ["Information Technology Services"],
  "renewed_until": "2026-11-30",
  "final_expiration": "2026-11-30",
  "initial_term": "2022-09-01",
  "days_to_expiration": 68,
  "current_status": "Active",
  "is_new": false,
  "is_state_adopted": false,
  "state_adopted_states": [],
  "state_adoption_type": null,
  "has_pricing_doc": true,
  "has_executive_summary": true,
  "document_types": ["Evaluation ＆ Award Documents", "Master Agreement Documents"],
  "document_count": 8,
  "documents": [
    {
      "filename": "iParq_Award_Letter.pdf",
      "file_group": "Master Agreement Documents",
      "file_type": "",
      "document_title": "Contract Award Letter",
      "blob_path": "S1039/150457/Master_Agreement_Documents/iParq_Award_Letter.pdf",
      "hidden": false,
      "download_url": "https://www.omniapartners.com/api/document-download?contract=150457&filename=iParq_Award_Letter.pdf"
    }
  ],
  "contract_url": "https://www.omniapartners.com/suppliers/iparq/contracts/05-80",
  "supplier_url": "https://www.omniapartners.com/suppliers/iparq",
  "supplier_website": "www.iparq.com",
  "supplier_industry": "Consumer Services",
  "supplier_active_contract_count": 2,
  "supplier_first_contract_date": "2022-09-01",
  "supplier_parent_name": null
}
```

Key fields:

- `contract_url` — the public contract page; `null` for Private-sector
  contracts, which have no public page on omniapartners.com.
- `documents[].download_url` — direct PDF link; `null` if the document has
  no file name.
- `days_to_expiration` — whole days (UTC) from the run date to
  `final_expiration`; negative for expired contracts, `null` if the date is
  missing or malformed.
- `supplier_*` — supplier enrichment; `null` when the supplier could not be
  matched.

The **Output** tab shows an overview table with the most useful columns;
the full item is available in every export format.

### Input examples

Private-sector contracts for private equity:

```json
{
  "industries": ["private_equity"],
  "contractSectors": ["Private"]
}
```

NCPA contracts expiring in the next 180 days:

```json
{
  "sourcingEntities": ["NCPA"],
  "expiresWithinDays": 180
}
```

Full-text search plus a category, expiring within a year:

```json
{
  "query": "office chairs",
  "categories": ["Furniture & Furnishings"],
  "expiresWithinDays": 365
}
```

A quick test run over the whole registry:

```json
{
  "maxItems": 50
}
```

### How it works

1. The Actor calls OMNIA's public search API (`POST /api/search`) — the same
   endpoint the website uses — with your query and server-side filters. No
   browser is involved.
2. It pages through all results, collecting contracts and suppliers, and
   stops when the collected count matches the total (`found`) reported by
   the API or when a page brings no new contracts. Network errors and 5xx
   responses are retried with backoff.
3. Each contract is normalized and enriched with its supplier's data;
   document download links are built.
4. Actor-side filters are applied, then `maxItems`.
5. Contracts are written to the dataset.

### Pricing

This Actor uses the **Pay Per Event** pricing model — you are not charged for compute time.

- Each contract written to the dataset is charged exactly one `new-item` event, so a run costs exactly as many events as the number of contracts it delivers.
- The exact price per event is listed on the **Pricing** tab of the Actor page.
- If you set a **maximum cost per run** limit in your Apify run settings, the Actor stops delivering contracts once that budget is reached instead of handing out contracts it can no longer charge for.

### Limitations & notes

- Private-sector contracts have `contract_url: null` — OMNIA publishes no
  public page for them.
- `subcategories`, `leadAgencies` and `stateAdoptedStates` require an exact,
  case-sensitive match; there is no autocomplete, so a typo returns nothing
  (the Actor logs `Filter matched no contracts`). Blank values are ignored.
- The OMNIA API silently ignores filter values it does not recognize and
  returns the whole registry instead. When server-side filters don't narrow
  the result, the Actor logs a warning so you can spot it.
- With a text `query`, the API's `found` is only an estimate and is usually a
  bit higher than the number of contracts it actually returns; the Actor
  collects every unique contract the API returns.
- `final_expiration` is returned exactly as published by the source,
  including occasional typos (e.g. `3031-07-31`); the Actor does not
  "correct" source data.
- The registry size changes over time; as of September 2026 it holds about
  860 contracts from about 640 suppliers.

### Legality

This Actor collects only contract data that OMNIA Partners publishes openly
on omniapartners.com; it does not extract private user data. You are
responsible for using the results in line with the source website's terms of
service and the laws that apply to you. If the data you collect includes
personal data, it may be protected by the GDPR or other regulations — consult
your lawyers if you are unsure whether your use is legitimate.

### ❓ FAQ

**Where can I find a list of NCPA contracts?**
NCPA contracts are part of the OMNIA Partners registry. Run the Actor with
`sourcingEntities: ["NCPA"]` (or open the
[NCPA contracts task](https://apify.com/gallant_illustration/omnia-partners-scrapper/examples/omnia-ncpa-contracts)) and export the
dataset to Excel or CSV.

**Is US Communities part of OMNIA?**
Yes — US Communities contracts are published in the OMNIA Partners registry.
Select them with `sourcingEntities: ["US Communities"]`.

**Why is my dataset empty?**
Most often a string filter (`subcategories`, `leadAgencies`,
`stateAdoptedStates`) or a combination of filters matches nothing — these
require an exact, case-sensitive value. The run log shows a
`Filter matched no contracts` warning with the values you passed. Remember
that different fields are combined with AND.

**Why do some contracts have no `contract_url`?**
Private-sector contracts have no public page on omniapartners.com, so the
Actor returns `null` instead of a broken link.

**How do I get the contract PDFs?**
Use `documents[].download_url` — it is a direct download link for each
document.

**How much does a full run cost?**
One `new-item` event per delivered contract, so the whole registry costs
roughly its size in events (about 860 as of September 2026). Use filters or
`maxItems` to pay only for what you need.

**Can I run this on a schedule?**
Yes. Use Apify **Schedules**, for example with `expiresWithinDays` to get a
weekly list of contracts coming up for expiration.

### 📝 Changelog

See the **Changelog** tab (`CHANGELOG.md`) for what changed between releases.

### 🔗 Related procurement Actors

- [**Sourcewell awarded contracts & vendors**](https://apify.com/gallant_illustration/sourcewell-scrapper) — the Sourcewell
  cooperative contract registry with awarded suppliers, categories and an
  expiring-contracts filter. Use both to cover the largest US cooperative
  purchasing programs.
- [**Open government RFPs & bids on Bonfire**](https://apify.com/gallant_illustration/bonfire-procurement-scraper) — open
  solicitations from hundreds of US and Canadian agencies on Bonfire / Euna
  Procurement. Use it to catch the new bid once a contract runs out.

**From expiring contract to new bid:** when a cooperative contract is about to
expire, agencies that bought through it often run their own solicitation —
and many of them publish it on Bonfire. Use `expiresWithinDays` here to see
which contracts are ending, then watch for the rebid with the Bonfire
scraper's keyword filter.

### 🛟 Support & feedback

Bugs and feature requests — via the **Issues** tab on this Actor's page.
For programmatic access, see the **API** tab.

### Development

```bash
npm install
npm run build
npm start          # run the compiled Actor
npm run start:dev  # run from TypeScript sources without building
npm test           # build and run the test suite
apify run          # run locally with the Apify CLI
```

Internal developer documentation (in Russian) lives in the `docs/` folder of
the source repository.

# Changelog

This Actor's version history is a separate document: https://apify.com/gallant\_illustration/omnia-partners-scrapper/changelog.md

# Actor input Schema

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

Leave empty to scrape the whole registry. Full-text search over contract title and description; combined with all other filters (AND).

## `industries` (type: `array`):

Leave empty for no restriction. Filtered server-side by OMNIA. With several values selected, a contract matches if it belongs to at least one of them (OR).

## `contractSectors` (type: `array`):

Leave empty for no restriction. Public = public-sector contracts, Private = private-sector contracts. Several values are combined with OR.

## `sourcingEntities` (type: `array`):

Leave empty for no restriction. The cooperative or program the contract was awarded through. Several values are combined with OR.

## `verticals` (type: `array`):

Leave empty for no restriction. Several values are combined with OR.

## `awardStructures` (type: `array`):

Leave empty for no restriction. Single-Award = one supplier, Multi-Award = several suppliers. Several values are combined with OR.

## `subcategories` (type: `array`):

Leave empty for no restriction. Exact, case-sensitive match against an OMNIA subcategory, e.g. "Software". Values are not validated by the schema, so a typo matches nothing. Several values are combined with OR.

## `leadAgencies` (type: `array`):

Leave empty for no restriction. Exact, case-sensitive match against the agency name, e.g. "Region 4 Education Service Center". Several values are combined with OR.

## `stateAdoptedStates` (type: `array`):

Leave empty for no restriction. Two-letter US state codes, exact case-sensitive match, e.g. "UT". Several values are combined with OR.

## `categories` (type: `array`):

Leave empty for no restriction. Filtered by the Actor after all pages are fetched (not server-side by OMNIA). Several values are combined with OR.

## `newOnly` (type: `boolean`):

Off by default, meaning no restriction (it does NOT mean "old contracts only"). Turn on to keep only contracts that OMNIA marks as new.

## `stateAdoptedOnly` (type: `boolean`):

Off by default, meaning no restriction. Turn on to keep only contracts adopted by at least one state.

## `expiresWithinDays` (type: `integer`):

Leave empty for no restriction. Keeps only contracts with a known expiration date that is at most this many days away (0 = expires today or has already expired).

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

Caps the number of contracts delivered. Applied last, after all filters.

## Actor input object example

```json
{
  "newOnly": false,
  "stateAdoptedOnly": false
}
```

# Actor output Schema

## `dataset` (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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("gallant_illustration/omnia-partners-scrapper").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("gallant_illustration/omnia-partners-scrapper").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 gallant_illustration/omnia-partners-scrapper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,gallant_illustration/omnia-partners-scrapper"
        }
    }
}
```

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/OWEfiwsqhYjVlQfbT/builds/RxzFrWAiNZTLCoWH6/openapi.json
