NSW Planning Applications Monitor (Council DA Tracker JSON)
Pricing
from $1.50 / 1,000 application delivereds
NSW Planning Applications Monitor (Council DA Tracker JSON)
Extract development and planning applications from NSW Planning Portal: applicant, location, description, status and decision date. Monitor mode pushes only new or changed applications. For construction research, site analysis and planning compliance. HTTP only, no browser, pay per delivered row.
Pricing
from $1.50 / 1,000 application delivereds
Rating
0.0
(0)
Developer
Steadfetch
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
9 hours ago
Last modified
Security
Limited permissionsShare
steadfetch/au-planning-application-monitor
Returns development applications and planning proposals from the NSW Planning Portal Application Tracker as clean JSON, with a monitor mode that delivers only new and changed applications.
What it does
- Reads the public Application Tracker API behind https://www.planningportal.nsw.gov.au/map. It is one unified feed for councils across New South Wales: no per-council pages to scrape and no browser.
- Returns one row per application with reference, council, site address, works description, application type, status and lodgement/determination dates.
- Filters by council, address (including partial addresses through the portal address lookup) and lodgement date window.
- Monitor mode keeps a per-user snapshot of the applications already seen and returns only new applications and rows whose status, description or dates changed. An unchanged check returns zero rows.
- Never extracts applicant or owner names: those fields are not requested and not present in the output schema.
Coverage and source
- Source: NSW Planning Portal Application Tracker,
https://api.apps1.nsw.gov.au/eplanning/data/v0/DAApplicationTracker. - Coverage: 131 council display names and about 650,000 applications in the catalogue observed on 2026-10-26. The dataset includes development applications, complying development certificates and modifications; use
querywith a council or address to narrow it. - v1 covers New South Wales only. Other Australian states are out of scope.
- Public access only: no login, no paywall, no CAPTCHA, no proxy. The API returns JSON over HTTP, so there is no JavaScript rendering.
Minimum input
This is the smallest real input and the exact exampleRunInput of the Actor:
{"mode": "extract","query": "Calvert Street Marrickville","councils": ["Inner West Council"],"maxResults": 10,"strictSchema": true}
With defaults plus a query like "Inner West Council" it returns up to 1,000 applications.
How to use
-
Run the Actor from the Apify Console, the API or the CLI:
$apify call steadfetch/au-planning-application-monitor --input='{"mode":"extract","query":"Inner West Council","maxResults":100}' -
Read the default dataset (JSON, CSV or API).
-
For monitoring, schedule the Actor and switch
modetomonitor. AdddateFrom(for example the last 30 days) so each check scans a bounded, recent window.
Input fields
| Field | Type | Required | Default | Description | Example |
|---|---|---|---|---|---|
mode | string | Yes | extract | extract returns every matching application. monitor returns only new or changed applications since the previous run. | "monitor" |
query | string | Yes | - | Council display name or an address / address fragment. Address fragments are resolved through the portal's public address lookup. | "Calvert Street Marrickville" |
councils | array | No | [] | Optional council display names to narrow the search. | ["Inner West Council"] |
dateFrom | string | No | - | Inclusive lodgement date lower bound, YYYY-MM-DD. Recommended in monitor mode. | "2026-07-01" |
dateTo | string | No | - | Inclusive lodgement date upper bound, YYYY-MM-DD. | "2026-09-30" |
maxResults | integer | No | 1000 | Maximum applications returned in this run (1-10000). Each returned row is one billable result. | 100 |
strictSchema | boolean | No | true | Fail the run when a row does not match the output schema. Keep enabled. | true |
Output
Example output
{"url": "https://www.planningportal.nsw.gov.au/map","title": "PAN-652178 - 10 CALVERT STREET MARRICKVILLE 2204","scrapedAt": "2026-10-26T09:00:00.000Z","applicationReference": "PAN-652178","council": "Inner West Council","state": "NSW","address": "10 CALVERT STREET MARRICKVILLE 2204","description": "Demolition,Subdivision,Erection of a new structure,Semi-detached dwelling","applicationType": "Development Application","status": "pending_court_appeal","statusRaw": "Pending Court Appeal","dateLodged": "2026-06-30","dateDetermined": null,"sourceUrl": "https://www.planningportal.nsw.gov.au/map","planningPortalId": "PAN-652178","firstSeenAt": "2026-10-26T09:00:00.000Z","lastCheckedAt": "2026-10-26T09:00:00.000Z","changes": ["new"]}
Output fields
| Field | Type | Description |
|---|---|---|
url | string | Public source URL (common envelope, required). |
title | string or null | reference - address, for readable tables. |
scrapedAt | date-time | Run timestamp in UTC (common envelope, required). |
applicationReference | string | Portal application number (PAN-... or CDC-...). |
council | string | Council display name. |
state | string | Always NSW in v1. |
address | string | Site address as published by the portal. |
description | string or null | Works applied for, comma separated as published. |
applicationType | string or null | Development Application, Complying Development Certificate Application, Modification Application, Review of determination. |
status | string | Normalized snake_case status (under_assessment, approved, determined, ...). |
statusRaw | string or null | Status exactly as published by the source. |
dateLodged | date or null | Lodgement date (YYYY-MM-DD). |
dateDetermined | date or null | Determination date, or null while undecided. |
sourceUrl | string | Public source URL. |
planningPortalId | string | Same as applicationReference. |
firstSeenAt | date-time | First run that delivered the application (preserved in monitor mode). |
lastCheckedAt | date-time | Run that observed the current values. |
changes | array | new, or the changed fields (status, description, determination_date, lodgement_date, address). |
The portal does not publish each council's own DA number (for example DA/2026/0548) in this feed; the stable, state-wide identifier is the portal application number. statusRaw and the portal reference let you join a row back to the council tracker when you need the local number.
Monitor mode
- State is stored per Apify user and per normalized query in the named key-value store
au-planning-application-monitor-state, under a key that includes the user id. One user never sees another user's watches. - A run delivers only
newapplications and rows whose status, description, lodgement date, determination date or address changed. Unchanged rows are not pushed. - New or changed rows beyond
maxResultsstay pending and are delivered by the next run. - The store keeps the most recent 20,000 applications per watched query; older, least recently seen entries are evicted first.
- A
monitor-checkevent is charged once per watched query per run, even when nothing changed. Results are charged separately only when a row is delivered.
Pricing
Pay per event, charged automatically by the Apify platform:
apify-actor-start: 0.00005 USD per run (Apify-recommended default, includes the first 5 seconds of compute).apify-default-dataset-item: 1.50 USD per 1,000 applications (0.0015 USD per row), charged only for validated rows saved to the dataset.monitor-check: 0.20 USD per 1,000 checks (0.0002 USD per check), charged once per watched query in a monitor run, including checks where nothing changed.
Cost per 1,000
Measured locally on 2026-10-26 over the committed 358-row Inner West fixture: mapping plus schema validation took about 9 ms per 1,000 rows against the 343 KB saved API response. At 256 MB and Apify's reference of 0.20 USD per GB-hour, parsing compute is about 0.00000013 USD per 1,000 rows; including HTTP transfer, retries and run overhead the budget is well under 0.01 USD per 1,000 results. At 1.50 USD per 1,000 the gross margin on results is above 99 percent.
A monitor check is one run that fetches up to maxResults rows and diffs them: at 256 MB a typical 5-10 second check costs about 0.07-0.14 USD per 1,000 checks at the same compute reference, so the 0.20 USD per 1,000 check fee covers its compute and the result fee carries the margin.
Works on the Apify free plan: about 3,300 applications for the 5 USD monthly credit at 0.0015 USD per result (plus the run-start fee and any monitor checks).
The price sits below the only comparable Australian actor seen in the Store on 2026-10-26 (100 USD per 1,000 with 2 users) and is in line with the 2-5 USD per 1,000 band of the other actors in the niche, with the monitor delta as the differentiator.
Legal and data protection
- Only public data: no login, no paywall, no CAPTCHA and no account is used or bypassed.
- Only application metadata is extracted. Applicant and owner names are not in the feed and are not requested. The output schema is closed (
additionalProperties: false), so a personal field cannot slip in silently. - Requests are spaced out and retried with backoff; the API is a public NSW Government service.
- If a filter target cannot be reached, it is written to the run key-value store under
skippedwith the reason; the rest of the run continues.
FAQ
Does it need an API key? No. The NSW Planning Portal Application Tracker API is public and keyless.
Why not scrape each council's DA tracker? The portal feed already unifies 131 NSW councils in one schema, which is more coverage with fewer requests and fewer breakages. Council-specific trackers can be added later as an enrichment source if a buyer needs the local DA number.
Does it return personal data? No. It returns the application, the site address, the works and the status. Applicant/owner names are excluded by design.
What is the difference between status and statusRaw? statusRaw is exactly what the portal publishes (Under Assessment); status is the stable snake_case value (under_assessment) for filters and joins.
How do I monitor only new applications? Use mode: "monitor" with a dateFrom covering the window you care about and schedule the Actor. The second run returns only what changed.
Are the dates always present? No. The portal sometimes has no lodgement or determination date; those fields are null rather than guessed.
Support
Report bugs or request features through the Apify Store page (Issues tab) or the Steadfetch actors repository. Include the run ID and the input used.
Maintenance
The Actor is tested daily with the stored example input, and its fixtures, schemas and pricing run in the repository CI on every push. The source API and the council list can change; the daily run and the monitor skipped list surface breakages instead of hiding them.