# AusTender Contract Notices Scraper (Australia) (`knotty_mistveil/austender-contract-notices`) Actor

Australian Government contract notices from the official AusTender OCDS API: agency, supplier + ABN, UNSPSC category, value, dates, procurement method.

- **URL**: https://apify.com/knotty\_mistveil/austender-contract-notices.md
- **Developed by:** [Jason](https://apify.com/knotty_mistveil) (community)
- **Categories:** Business, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$3.00 / 1,000 result returneds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

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

## AusTender Contract Notices Scraper (Australia)

Pulls Australian Government contract notices (CNs) straight from the **official AusTender OCDS API** published by the Department of Finance and turns each notice into one flat, analysis-ready record: agency and its procurement contact, supplier name and ABN, UNSPSC category code *and* plain-English description, contract value, signed / start / end dates, procurement method, limited-tender reason and a link to the notice on tenders.gov.au. No API key, no browser scraping, no login. Use it to watch who is winning federal work, build supplier and agency lead lists, or find contracts that are about to expire and will be re-competed.

### What you get

One record per contract notice (or per amendment, id like `CN1234567-A1`):

- `id`, `contractId`, `url` (notice page on tenders.gov.au), `ocid`, `releaseId`, `releaseTag`, `isAmendment`, `amendmentId`, `amendsReleaseId`
- Agency: `agencyName`, `agencyAbn`, `agencyContactName`, `agencyBranch`, `agencyDivision`, `agencyContactEmail`, `agencyContactPhone`
- Supplier: `supplierName`, `supplierAbn`, `supplierStreetAddress`, `supplierLocality`, `supplierRegion`, `supplierPostcode`, `supplierCountry`
- Contract: `title` / `agencyReferenceId` (the agency's own reference, shown on the notice as "Agency Reference ID"), `description`, `unspscCode`, `unspscDescription`, `valueAmount`, `valueCurrency`, `status`
- Dates, ISO 8601 UTC: `dateSigned`, `publishedDate`, `awardDate`, `startDate`, `endDate`
- Dates, Canberra local (`YYYY-MM-DD`, exactly what the notice page prints): `publishedDateLocal`, `startDateLocal`, `endDateLocal`
- Procurement: `procurementMethod` (`open` / `limited` / `selective`), `procurementMethodDetails` (`Open tender` / `Limited tender` / `Prequalified tender`), `limitedTenderExempt`, `limitedTenderReasonCode`, `limitedTenderReason`, `exemptionCode`, `exemption`
- `source` (`austender`), `fetchedAt`

### Input

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `dateType` | select | `contractPublished` | Which date the window applies to: `contractPublished` (new parent notices), `contractLastModified` (new + amended), `contractStart`, `contractEnd` (expiring contracts). |
| `daysBack` | integer | `7` | Look-back window in days ending today (UTC). Ignored when `dateFrom` is set. |
| `dateFrom`, `dateTo` | `YYYY-MM-DD` | - | Explicit window (UTC, inclusive). History reaches back to 2004; use future dates with `contractEnd` to find expiring contracts. |
| `keywords` | string\[] | `[]` | Case-insensitive OR match on title, description, supplier, agency and UNSPSC description. |
| `agencies` | string\[] | `[]` | Agency-name substrings, e.g. `Defence`, `Home Affairs`. |
| `suppliers` | string\[] | `[]` | Supplier-name substrings, e.g. `Accenture`. |
| `unspscPrefixes` | string\[] | `[]` | UNSPSC code prefixes, e.g. `80` (business services), `8010` (management advisory), `43` (IT). |
| `procurementMethods` | string\[] | `[]` | Substring match against **either** `procurementMethod` (`open`, `limited`, `selective`) or `procurementMethodDetails` (`Open tender`, `Limited tender`, `Prequalified tender`), so `prequalified` works as a filter even though it is not a `procurementMethod` value. |
| `minValue`, `maxValue` | integer | - | Contract value bounds in AUD. |
| `includeAmendments` | boolean | `true` | Keep amendment releases (mostly seen with `contractLastModified`, `contractStart`, `contractEnd`). |
| `contractIds` | string\[] | `[]` | Lookup mode: fetch these notices by id (e.g. `CN4273499`), parent plus all amendments; the date window is ignored. |
| `maxItems` | integer | `500` | Stop after this many records (you pay per record). |

All list filters are ORed within the list and ANDed across filters. Filtering happens after download, so a narrow filter over a wide window still pages through every notice in the window (about 1,100 notices per week; see "Limits and freshness" for the cost of multi-year windows).

### Output example

Real record from a live run on 2026-09-07 (`dateType: contractPublished`, `daysBack: 2`, `maxItems: 5`), unmodified:

```json
{
  "id": "CN4274736",
  "contractId": "CN4274736",
  "source": "austender",
  "url": "https://www.tenders.gov.au/cn/show/0a1fd420-8093-4d1c-8b3d-71c95f024c92",
  "ocid": "prod-d13af6bc9ec945189df23390f6c56e00",
  "releaseId": "prod-d13af6bc9ec945189df23390f6c56e00-d8c405f724ba343ebce0b220ac5b9250",
  "releaseTag": "contract",
  "isAmendment": false,
  "amendmentId": null,
  "amendsReleaseId": null,
  "agencyName": "Australian Communications and Media Authority",
  "agencyAbn": "55386169386",
  "agencyContactName": "Procurement Enquiries",
  "agencyBranch": null,
  "agencyDivision": null,
  "agencyContactEmail": "ProcurementEnquiries@acma.gov.au",
  "agencyContactPhone": null,
  "supplierName": "HorizonOne Recruitment Pty Ltd",
  "supplierAbn": "98129885838",
  "supplierStreetAddress": null,
  "supplierLocality": "BRADDON",
  "supplierRegion": "ACT",
  "supplierPostcode": "2612",
  "supplierCountry": "AUSTRALIA",
  "title": "ACMA00000183",
  "agencyReferenceId": "ACMA00000183",
  "description": "27ACMA008 - Procurement services",
  "unspscCode": "80111600",
  "unspscDescription": "Temporary personnel services",
  "valueAmount": 105000,
  "valueCurrency": "AUD",
  "dateSigned": "2026-09-07T05:51:04Z",
  "publishedDate": "2026-09-07T05:51:04Z",
  "publishedDateLocal": "2026-09-07",
  "awardDate": "2026-09-07T05:51:04Z",
  "startDate": "2026-08-09T14:00:00Z",
  "startDateLocal": "2026-08-10",
  "endDate": "2026-11-29T13:00:00Z",
  "endDateLocal": "2026-11-30",
  "procurementMethod": "open",
  "procurementMethodDetails": "Open tender",
  "limitedTenderExempt": null,
  "limitedTenderReasonCode": null,
  "limitedTenderReason": null,
  "exemptionCode": null,
  "exemption": null,
  "status": "active",
  "fetchedAt": "2026-09-07T06:17:21.883Z"
}
```

Every field above matches the published notice at that `url`, which reads: "CN ID: CN4274736 - Publish Date: 7-Sep-2026 - Category: Temporary personnel services - Contract Period: 10-Aug-2026 to 30-Nov-2026 - Contract Value (AUD): $105,000.00 - Agency Reference ID: ACMA00000183".

### Pricing

Pay per result: **US$0.003 per record, US$3 per 1,000 records**. Nothing is charged for a run that returns no records. Platform usage (compute) is billed by Apify on top of the per-result price; runs on the Apify free plan are limited by the plan's monthly credit.

### Data source and licence

- Source: **AusTender Open Contracting Data Standard (OCDS) API**, `https://api.tenders.gov.au/ocds`, operated by the Australian Government Department of Finance. Publisher documentation: <https://github.com/austender/austender-ocds-api>. The Actor only calls the two public, keyless endpoints `findByDates/{dateType}/{from}/{to}` and `findById/{cnId}`, and it reads only public pages otherwise.
- Licence: every API response declares `"license": "https://creativecommons.org/licenses/by/3.0/au/"`, and the AusTender [Terms of Use](https://www.tenders.gov.au/infolinks/termsofuse) clause 5.1 states: "With the exception of the Commonwealth Coat of Arms, Approach to Market (ATM) material and where otherwise noted, all materials on AusTender are licensed under a Creative Commons Attribution 3.0 Australia licence (CC BY 3.0 AU)." CC BY 3.0 AU permits commercial reuse with attribution. Attribute as: "Source: AusTender, Australian Government Department of Finance, licensed under CC BY 3.0 AU."
- Clause 5.4 of those Terms carves out Approach to Market (ATM) material from reuse. This Actor returns **contract notice** data only - awarded contracts published under CC BY 3.0 AU - and never ATM documents.
- UNSPSC category descriptions are resolved offline from the MIT-licensed `unspsc-lookup` npm package (UNSPSC code list); the codes themselves come from AusTender. Roughly 99% of codes seen in live data resolve; the rest leave `unspscDescription` null.
- Personal data: `agencyContactName`, `agencyContactEmail` and `agencyContactPhone` are the named procurement contact the agency itself published on the notice, and supplier records for sole traders can carry an individual's name and trading address. The Commonwealth publishes those details lawfully on tenders.gov.au under the AusTender Terms of Use, but they remain personal information under the Australian Privacy Act 1988 (and the Australian Privacy Principles, including APP 7 on direct marketing).
- If you contact the people in this data, **that use is yours to justify, not the publisher's**: check the Privacy Act, the Spam Act 2003 and the Do Not Call Register Act 2006 before any outreach, and honour opt-outs. The Actor exposes only what the notice page shows and adds no enrichment from other sources.

### Limits and freshness

- Data is read live from the API on every run; AusTender publishes new notices on business days (roughly 200-250 per business day). Use `daysBack` of 3 or more to cover a weekend.
- **Pagination, handled for you**: the API caps every response at 100 releases and chains the rest through `links.next` cursors; there is no `page` or `limit` parameter. The Actor follows those cursors until the API returns an empty page or `maxItems` is reached, so nothing in the window is missed. Measured on 2026-09-07: the 7-day window `2026-08-31` to `2026-09-07` needed 13 requests and returned 1,131 releases with zero duplicates, and a wider re-check over 260 paged requests / 25,380 releases (four windows, including two full months) again found zero duplicate release ids. Results arrive newest release first.
- **Cost of long windows**: filters are applied after download, so a narrow filter still pages through every notice in the window. Budget **1 request per 100 notices** and 5,000-10,000 notices per month (measured 2026-09-07: 4,758 releases in February 2025, 9,162 in June 2025, 10,433 in June 2015 - the June financial-year end is the annual peak), so roughly 80,000-100,000 notices, ~900 requests and 30-40 minutes per year of history at the ~2 seconds per request measured here. A full 2004-onward backfill is therefore tens of thousands of requests and many hours of compute: size `dateFrom` accordingly, and run long backfills year by year rather than in one pass. Memory does not grow with the window - the Actor de-duplicates within each page and caps its cross-page key memory at 200,000 notices (~30 MB) - so the default 1 GB Actor memory is enough even for a full backfill; the cost of a long window is time and compute units, not RAM.
- `contractPublished` is almost entirely parent notices - a handful of amendments do slip in (measured 2026-08-24 to 08-31: 1,021 releases tagged `contract`, 6 tagged `contractAmendment`) - so use `contractLastModified` to reliably receive amendments (value changes, extensions). Amendment records reuse the CN number with an `-A1`, `-A2` suffix as `id` and keep the parent number in `contractId` - for example `CN4252129` was published at A$27,270 and its `CN4252129-A1` amendment doubled it to A$54,540.
- **Dates**: the OCDS feed is UTC, but tenders.gov.au prints Canberra local dates, so a notice stamped `2026-09-01T23:46:49Z` appears on the site as 2-Sep-2026 and a period starting `2026-09-13T14:00:00Z` appears as 14-Sep-2026. Both forms are in every record: the raw UTC timestamps and the `*Local` calendar dates that match the site.
- Each notice carries one UNSPSC category and one supplier. In practice `dateSigned` equals the notice's publication timestamp; the site's separate "execution date" is not in the OCDS feed.
- ATM (approach to market) id, SON id, consultancy flag, SME flags and confidentiality flags are shown on the notice page (`url`) but are **not** part of the OCDS feed, so they cannot be included - the `url` takes you to them.
- Source quirk, handled for you: AusTender publishes the agency's procurement contact under the supplier party; the Actor exposes it as `agencyContact*` fields, matching what the notice page shows under "Agency Details".
- History reaches back to 2004 (verified), though volume is thin before the 2007-08 financial year, which is AusTender's own stated start of coverage.
- Windows with no notices (for example far-future dates) return zero records and no charge.

### Use cases

- **Sales intelligence**: alert on new contracts in your UNSPSC categories or with target agencies, with the agency procurement contact attached.
- **Competitor and incumbent tracking**: filter by `suppliers` to see every federal contract and amendment a competitor wins.
- **Re-compete pipeline**: run with `dateType: contractEnd` and a future window to list contracts about to expire, sorted by value. This input returns December 2026 Defence expiries over A$100k in IT and business services:

```json
{ "dateType": "contractEnd", "dateFrom": "2026-12-01", "dateTo": "2026-12-31",
  "agencies": ["Defence"], "unspscPrefixes": ["80", "43"], "minValue": 100000, "maxItems": 5 }
```

### Support

Found a problem or need another field? Open an issue on the Actor's Issues tab on Apify Store; replies within 14 days.

# Actor input Schema

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

Which contract date the window applies to. 'contractPublished' = notices first published in the window, newest first (almost entirely parent notices; a handful of amendments do appear). 'contractLastModified' = notices published or amended in the window, the reliable choice for amendments. 'contractStart' / 'contractEnd' = contracts whose period starts / ends in the window (useful for expiring-contract leads).

## `daysBack` (type: `integer`):

Look-back window in days ending now (UTC). Ignored when dateFrom is set. AusTender publishes on business days, so use 3 or more to cover a weekend.

## `dateFrom` (type: `string`):

Start of the window as YYYY-MM-DD (UTC, inclusive). Overrides daysBack. History reaches back to 2004; coverage is complete from the 2007-08 financial year.

## `dateTo` (type: `string`):

End of the window as YYYY-MM-DD (UTC, inclusive). Defaults to today.

## `keywords` (type: `array`):

Case-insensitive OR match against title, description, supplier name, agency name and UNSPSC description. Leave empty for everything.

## `agencies` (type: `array`):

Only notices whose agency name contains one of these substrings (case-insensitive), e.g. 'Defence', 'Home Affairs'.

## `suppliers` (type: `array`):

Only notices whose supplier name contains one of these substrings (case-insensitive), e.g. 'Accenture', 'Hays'.

## `unspscPrefixes` (type: `array`):

Only notices whose 8-digit UNSPSC category code starts with one of these prefixes, e.g. '80' (management and business services), '8010' (management advisory), '43' (IT and telecoms).

## `procurementMethods` (type: `array`):

Only notices whose procurement method matches one of these substrings (case-insensitive). Matched against either field: procurementMethod is 'open', 'limited' or 'selective', and procurementMethodDetails is 'Open tender', 'Limited tender' or 'Prequalified tender' - so 'prequalified' works here even though it is not a procurementMethod value.

## `minValue` (type: `integer`):

Skip contracts with a value below this amount in AUD (contracts without a value are also skipped when set).

## `maxValue` (type: `integer`):

Skip contracts with a value above this amount in AUD.

## `includeAmendments` (type: `boolean`):

Keep contract amendment releases (id like CN1234567-A1). They mainly appear with the 'Last modified', 'Contract start' and 'Contract end' date types.

## `contractIds` (type: `array`):

Optional. Fetch these specific contract notices by ID (e.g. CN4273499) instead of a date window; every release of each notice (parent + amendments) is returned. The date filters are ignored when this is set.

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

Stop after this many records. You are charged per record delivered.

## Actor input object example

```json
{
  "dateType": "contractPublished",
  "daysBack": 7,
  "keywords": [],
  "agencies": [],
  "suppliers": [],
  "unspscPrefixes": [],
  "procurementMethods": [],
  "includeAmendments": true,
  "contractIds": [],
  "maxItems": 500
}
```

# Actor output Schema

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

All contracts returned by the run, one JSON object each. Append ?format=csv or ?format=xlsx to download a spreadsheet.

## `summary` (type: `string`):

Counts, the date window used, source freshness and any per-source warnings, written at the end of the run.

# 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 = {
    "dateType": "contractPublished",
    "daysBack": 7,
    "keywords": [],
    "agencies": [],
    "suppliers": [],
    "unspscPrefixes": [],
    "procurementMethods": [],
    "includeAmendments": true,
    "contractIds": [],
    "maxItems": 500
};

// Run the Actor and wait for it to finish
const run = await client.actor("knotty_mistveil/austender-contract-notices").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 = {
    "dateType": "contractPublished",
    "daysBack": 7,
    "keywords": [],
    "agencies": [],
    "suppliers": [],
    "unspscPrefixes": [],
    "procurementMethods": [],
    "includeAmendments": True,
    "contractIds": [],
    "maxItems": 500,
}

# Run the Actor and wait for it to finish
run = client.actor("knotty_mistveil/austender-contract-notices").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 '{
  "dateType": "contractPublished",
  "daysBack": 7,
  "keywords": [],
  "agencies": [],
  "suppliers": [],
  "unspscPrefixes": [],
  "procurementMethods": [],
  "includeAmendments": true,
  "contractIds": [],
  "maxItems": 500
}' |
apify call knotty_mistveil/austender-contract-notices --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,knotty_mistveil/austender-contract-notices"
        }
    }
}

```

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/6uuontDHa00XnjMtf/builds/yXNVE6XxplIiDmcO3/openapi.json
