跳到正文
DEV Community· 4robot·· 3 小時前AI 評分50

Apify Actors:如何在 5 分鐘內透過 API 取得政府招標、公司登記及商業資料

Public tenders, company registers and business data via API in 5 minutes

AI 導讀

作者將七個公共資料來源封裝為 Apify Actors,讓用戶以統一 JSON 格式透過 API、curl、Python 或 MCP 存取。來源涵蓋 TED、SAM.gov、NPPES、Companies House 及墨西哥商業與招聘資料,支援 maxResults 結果上限與 onlyNewSinceLastRun 增量擷取。費用按結果計算,只有存入數據集的項目會收費。

正文

Most of the data that sales, procurement and research teams need already exists in official, free sources: the EU's tender journal, the US federal contracting portal, the UK company register, the US healthcare provider registry, Mexico's statistical business directory. The problem is never access. It is that every source has its own API quirks, pagination caps, encodings and field names, and nobody wants to maintain seven different clients.

This post shows how we packaged seven of those sources as Apify Actors with one consistent JSON shape, and how to call them from curl, Python, or directly from an AI agent through MCP. Everything below runs against the official sources and is billed per result, so a test costs cents.

What is in the box

Actor Source What you get Price
EU Tenders (TED) Scraper TED Search API, no key Contract notices and awards by keyword, country, CPV code, date; buyer, deadline, estimated value $5.00 / 1,000
SAM.gov Opportunities Scraper SAM.gov public daily extract, no key US federal solicitations, sources sought, awards by keyword, NAICS, set-aside, agency, state $5.00 / 1,000
US Healthcare Providers (NPI Registry) Scraper NPPES API, no key Clinics, hospitals, pharmacies, practices by specialty, city, state, ZIP; address, phone, taxonomy $1.50 / 1,000
UK Companies House Scraper Companies House API, your free key Companies and new incorporations by name, SIC code, location, date; profile and officers optional $2.00 / 1,000 + $1.00 / 1,000 detail requests
Mexico Business Directory (DENUE / INEGI) INEGI DENUE API 5M+ Mexican establishments with activity, size, address, GPS $2.00 / 1,000
OCC Mundial Jobs Scraper occ.com.mx Mexican job listings with salary, company, work mode $1.50 / 1,000
Sección Amarilla Mexico Business Scraper seccionamarilla.com.mx Mexican businesses with phone, WhatsApp, website, hours $5.00 / 1,000

Three design rules apply to all of them:

  1. Same field names. id, title or name, url, country, publishedAt, scrapedAt, and typed values (numbers as numbers, dates in ISO 8601, currency as its own field, null instead of empty strings). A tender from TED and an opportunity from SAM.gov land in the same table without mapping.
  2. A hard cost cap. maxResults stops the run at exactly that number, and only items saved to the dataset are charged. Duplicates, invalid rows and failed runs cost nothing.
  3. Incremental mode. onlyNewSinceLastRun: true makes the Actor remember what it delivered (a named key-value store in your account), so a daily schedule returns only new tenders, new solicitations or new companies. That is where the recurring value is.

Under the hood each Actor does the boring part: TED's expert query language and 15,000-result window (the Actor switches to iteration mode), SAM.gov's 200 MB Windows-1252 CSV that has to be streamed and stopped early, NPPES's silent 1,200-record cap (the Actor splits the area by ZIP prefix), Companies House's 10,000-result window and 600-requests-per-5-minutes limit (the Actor splits by incorporation date and waits out 429s).

1. curl: open tenders for software in Germany

The simplest way is the synchronous endpoint, which runs the Actor and returns the dataset in one call. Get a token from Apify Console (Settings → API & Integrations); a free account includes monthly usage credit.

curl -X POST "https://api.apify.com/v2/acts/hexadatalabs~eu-tenders-ted-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"searchQueries":["software"],"countries":["DE"],"noticeTypes":"competition","dateFrom":"2026-10-20","maxResults":50}'

A typical item:

{
  "id": "745163-2026",
  "title": "Germany – Software package and information systems – PolBln 423_26 EU Beschaffung Storagesystem",
  "buyerName": "Polizei Berlin",
  "country": "DE",
  "noticeTypeLabel": "Contract notice",
  "publishedAt": "2026-10-27",
  "deadline": "2026-11-26T07:00:00+01:00",
  "estimatedValue": 1680672.27,
  "currency": "EUR",
  "cpvCodes": ["48000000"],
  "url": "https://ted.europa.eu/en/notice/-/detail/745163-2026"
}

Fifty results cost $0.25.

2. Python: a daily feed of new UK companies with their directors

Install the client (pip install apify-client), create a free Companies House API key (two minutes at developer.company-information.service.gov.uk), and run:

from apify_client import ApifyClient

client = ApifyClient("<APIFY_TOKEN>")
run = client.actor("hexadatalabs/uk-companies-house-scraper").call(run_input={
    "apiKey": "<COMPANIES_HOUSE_KEY>",
    "sicCodes": ["62012", "62020"],        # software development, IT consultancy
    "location": "Manchester",
    "onlyNewSinceLastRun": True,           # first run: everything since 7 days ago; then only new ones
    "includeOfficers": True,
    "maxResults": 500,
})
for company in client.dataset(run["defaultDatasetId"]).iterate_items():
    directors = [o["name"] for o in company.get("officers", []) if o["role"] == "director"]
    print(company["incorporatedAt"], company["name"], company["postalCode"], directors)

Put the same input on an Apify Schedule (every weekday at 08:00) and add a webhook or an integration (Slack, e-mail, Google Sheets, HubSpot) on the run-succeeded event. Each morning you get the companies incorporated the day before, nothing twice. At about 100 companies a day with officers, that is roughly $0.30 per day.

The same pattern works for SAM.gov (naicsCodes + states + onlyNewSinceLastRun) and for TED (cpvCodes + countries).

3. From an AI agent (MCP)

Every Apify Actor is exposed as a tool by the Apify MCP server, so an agent can call these sources directly. Add the server to Claude Desktop, Cursor, VS Code or any MCP client:

{
  "mcpServers": {
    "hexadata": {
      "url": "https://mcp.apify.com?tools=hexadatalabs/eu-tenders-ted-scraper,hexadatalabs/sam-gov-opportunities-scraper,hexadatalabs/us-healthcare-providers-npi-scraper",
      "headers": { "Authorization": "Bearer <APIFY_TOKEN>" }
    }
  }
}

Then ask in plain language:

"Which small-business set-aside solicitations for IT services in Virginia or Maryland were posted this week, and when do they close? At most 100 results."

The agent calls sam-gov-opportunities-scraper with {"naicsCodes":["5415"],"setAsides":["SBA"],"states":["VA","MD"],"noticeTypes":"solicitation","dateFrom":"...","maxResults":100} and answers from the deadline, setAside and url fields. Tool selection works because every Actor description and every input field starts with "Use this when…", which is what the model reads when it picks a tool. Saying "at most N results" in the prompt is the same cost cap as maxResults in code.

In Claude Code the same server is one command:

claude mcp add --transport http hexadata "https://mcp.apify.com?tools=hexadatalabs/uk-companies-house-scraper" --header "Authorization: Bearer <APIFY_TOKEN>"

What about legality and personal data

All seven Actors read official APIs or public pages within their terms, identify themselves, and pace requests. Personal data is opt-in only: Companies House officers (includeOfficers), SAM.gov contracting-officer contacts (includeContacts), NPPES individual practitioners (includeIndividuals), DENUE business contact fields. By default you get organisations, notices and establishments, with the source attribution in every item.

Try it

  • Each Actor's page on Apify has a "Try for free" input with a cheap prefill, the full field list, cost examples and the MCP snippet: apify.com/hexadatalabs.
  • The MCP connection guide and server.json are in the hexadata-mcp repository, and the server is listed in the official MCP registry as io.github.4robot/hexadata.
  • Missing a source (another country's tender portal, another register)? Open an issue on any Actor and say what you need; the next one is usually a clone of an existing one.

來源:DEV Community · dev.to