Canada Opportunity Feed – Tenders, Permits, Leads
Pricing
Pay per event
Canada Opportunity Feed – Tenders, Permits, Leads
Only NEW Canadian opportunities since your last call: NS tender awards, large Halifax and Calgary permits, new federal corporations, Government of Canada recalls. One schema, 0–100 score with reason, top-N digest. Open-licensed, no personal data. $0.05/run + $0.01/item.
Canada Opportunity Feed
Returns only NEW Canadian business signals since your last call — Nova Scotia tender awards, large Halifax/Calgary building permits, new federal corporations, Government of Canada recalls — in one schema, each scored 0–100 with a one-line reason, plus a top-N digest record.
- Per item: id, type, region, postal FSA, sector, value (CAD), date, URL, source, score, reason.
- Repeat calls never return the same item twice (state store).
- Output: structured JSON/CSV.
Why not build it yourself? No four source integrations, de-duplication state or scoring to build.
Price (live, pay per event): $0.05 per run for the digest + $0.01 per item. digestOnly = $0.05; 20 items = $0.25.
Example inputs
{}
All sources, all of Canada, last 7 days on the first run, up to 100 items + digest.
{"regions": ["NS"], "minValueCad": 100000, "maxItems": 20}
Nova Scotia only, awards/permits ≥ $100k.
{"sectors": ["construction", "energy"], "sinceDays": 30, "digestOnly": true, "topN": 10}
Cheap peek: one digest of the top 10 construction/energy items from the last 30 days. State is not changed.
{"sources": ["federal-corporations"], "regions": ["NS", "NB", "PE", "NL"], "stateStore": "atlantic-newco"}
New Atlantic federal corporations, with their own "seen" cursor.
Input fields
| Field | Default | Meaning |
|---|---|---|
sources | all 5 | ns-tenders, halifax-permits, calgary-permits, federal-corporations, recalls |
regions | [] (all) | 2-letter province codes; CA = national items (recalls) |
sectors | [] (all) | construction, health, food, technology, energy, professional_services, transport, manufacturing, retail, real_estate, finance, other |
minValueCad | 0 | Drops awards/permits below this value (or with no value). Does not affect companies or recalls. |
permitMinValueCad | 250000 | Permits below this are never fetched (only "large" permits) |
sinceDays | 7 | First-run lookback (1-90). Later runs cover the time since the last run + 3 days, at least sinceDays, at most 90 |
maxItems | 100 | Max items returned (1–50,000), highest score first. Anything over the cap is held for the next run. |
fetchAll | false | Return every new item, capped at 50,000. $0.01 per item (50,000 ≈ $500); set a max cost per run in Apify. |
topN | 10 | Items listed in the digest |
digestOnly | false | Return only the digest and leave the state unchanged |
markSeen | true | false = don't update the state (repeatable test) |
stateStore | canada-opportunity-feed-state | Named key-value store holding seen IDs (key SEEN_IDS) |
Output
Dataset item 1 is always the digest (type: "digest"), which is also saved as DIGEST in the run's default key-value store. The items follow, sorted by score.
Item schema (every source)
| Field | Type | Notes |
|---|---|---|
id | string | Stable: <source>:<native id>, e.g. calgary-permits:BP2026-13695, federal-corporations:18302308, ns-tenders:<tender id>:<vendor hash> |
type | string | tender_award, building_permit, new_company, market_signal |
title, summary | string | Plain English, no personal data |
region | string | Province code or CA |
postalFsa | string/null | First 3 postal characters only (companies) |
sector | string | See the sector rules below |
valueCad | number/null | Award amount or estimated project value |
date | YYYY-MM-DD | Award, issue, incorporation or last-updated date |
url | string | Record page when one exists, otherwise the dataset page |
source | string | Dataset name |
licence, licenceUrl | string | Required attribution line + licence link |
score | 0-100 | See scoring |
reason | string | One line, with the points breakdown |
Example output (real local run, 2026-10-16, second call, so the top 5 from the first call are excluded)
{"id": "digest:2026-10-16:193847","type": "digest","title": "Canada Opportunity Feed digest: top 3 of 1432 new items since 2026-10-09","summary": "115 building_permit, 27 market_signal, 1172 new_company, 118 tender_award","date": "2026-10-16","windowStart": "2026-10-09","newItems": 1432,"fetchedPerSource": {"ns-tenders": 118,"federal-corporations": 1172,"recalls": 19793,"halifax-permits": 17,"calgary-permits": 103},"top": [{"rank": 1,"score": 86,"reason": "$3.2M construction permit, 2d old, AB (value 33+recency 28+type 20+detail 5)","id": "calgary-permits:BP2026-13695","type": "building_permit","title": "Calgary permit: 3199 - Trade/Retail/Wholesale Misc. – New in Sage Hill","region": "AB","valueCad": 3162810.0,"url": "https://data.calgary.ca/Business-and-Economic-Activity/Building-Permits/c2es-76ed"},{"rank": 2,"score": 86,"reason": "$2.6M construction permit, 1d old, AB (value 32+recency 29+type 20+detail 5)","id": "calgary-permits:BP2026-14747","type": "building_permit","title": "Calgary permit: 5109 - School, Public – Alteration in North Glenmore Park","region": "AB","valueCad": 2600000.0,"url": "https://data.calgary.ca/Business-and-Economic-Activity/Building-Permits/c2es-76ed"},{"rank": 3,"score": 85,"reason": "$2.5M construction permit, 2d old, AB (value 32+recency 28+type 20+detail 5)","id": "calgary-permits:BP2026-17977","type": "building_permit","title": "Calgary permit: 1606 - Ths Townhouse – New in Mahogany","region": "AB","valueCad": 2544548.18,"url": "https://data.calgary.ca/Business-and-Economic-Activity/Building-Permits/c2es-76ed"}],"scoring": "score = value(0-40, log10 $10k..$10M) + recency(0-30, linear over 30 days) + type(permit 20, award 16, new company 12, recall 8) + detail(sector known 5, record URL 5)","licence": "Each top item's licence is on its full record; sources: OGL-Canada, OGL-Nova Scotia, OGL-Halifax, OGL-City of Calgary."}{"id": "calgary-permits:BP2026-13695","type": "building_permit","title": "Calgary permit: 3199 - Trade/Retail/Wholesale Misc. – New in Sage Hill","summary": "Permit BP2026-13695 (Commercial / Multi Family Project) issued 2026-10-14, status Issued Permit. Lead for trades, suppliers and services. Address and contractor removed.","region": "AB","postalFsa": null,"sector": "construction","valueCad": 3162810.0,"date": "2026-10-14","url": "https://data.calgary.ca/Business-and-Economic-Activity/Building-Permits/c2es-76ed","source": "City of Calgary Building Permits (data.calgary.ca c2es-76ed)","licence": "Contains information licensed under the Open Government Licence – City of Calgary. Licence: https://data.calgary.ca/stories/s/Open-Calgary-Terms-of-Use/u45n-7awa","licenceUrl": "https://data.calgary.ca/stories/s/Open-Calgary-Terms-of-Use/u45n-7awa","score": 86,"reason": "$3.2M construction permit, 2d old, AB (value 33+recency 28+type 20+detail 5)"}
Scoring (deterministic, no AI)
score = value + recency + type + detail, capped at 0-100:
- value (0-40):
round(40 × log10(valueCad / 10,000) / 3), so $10k or less (or no value) = 0, $100k ≈ 13, $1M ≈ 27, $10M+ = 40. - recency (0-30):
round(30 × (1 − ageDays/30)), so today = 30 and 30+ days old = 0. - type: building_permit 20 (an active site that needs trades and suppliers), tender_award 16 (shows who buys what), new_company 12 (new buyer of services), market_signal 8 (an indirect signal).
- detail (0-10): +5 when a sector was assigned, +5 when
urlis a record-level page. Ties are broken by value, then date, then id.reasonreads, for example,"$3.2M construction permit, 2d old, AB (value 33+recency 28+type 20+detail 5)".
Sector rules: permits = construction. NS awards flagged construction = construction. Recalls map by agency (TC → transport, CFIA → food, Health Canada drugs/devices → health, Consumer product safety → retail). Everything else takes the first matching keyword group in src/core.py:SECTOR_RULES, checked against the title, description or company name, otherwise other.
Sources and licences
| Source | Licence (quoted) | Access / robots.txt |
|---|---|---|
NS Tender Awards, data.novascotia.ca m6ps-8j6u | Open Government Licence – Nova Scotia: "licence to use the Information, including for commercial purposes"; attribution "Contains information licensed under the Open Government Licence – Nova Scotia" | Socrata API. robots.txt Crawl-delay: 1, so 1 s between pages. The dataset is refreshed roughly monthly, so this source looks back an extra 60 days; seen-ID dedupe stops repeats. |
| Federal Corporations (Corporations Canada), open.canada.ca | OGL – Canada: "including for commercial purposes"; "Contains information licensed under the Open Government Licence – Canada" | One official CSV download per run (active CBCA, ~100 MB, streamed). open.canada.ca robots.txt Crawl-delay: 20. The Actor makes a single request to this source. |
| Recalls and Safety Alerts, recalls-rappels.canada.ca | OGL – Canada (as above) | One JSON file under /sites/default/files/, which robots.txt does not disallow |
| Halifax building permits, data-hrm.hub.arcgis.com | Open Government Licence—Halifax v1.0: "licence to use the Information, including for commercial purposes"; "Contains information licenced under the Open Government Licence—Halifax" | ArcGIS REST. The host serves no robots.txt. 1 s between pages. |
Calgary building permits, data.calgary.ca c2es-76ed | Open Government Licence – City of Calgary v2.1: "including for commercial purposes" | Socrata API. robots.txt Crawl-delay: 1; /resource is allowed. |
Excluded: CanadaBuys tender and award notices. They are OGL-Canada, but canadabuys.canada.ca/robots.txt has User-agent: * / Disallow: / (only Googlebot and Bingbot are allowed), and the CSVs exist only on that host. Tender descriptions also carry named contacts.
This Actor is independent and not endorsed by any government.
Privacy
- No person names, emails, phones or street addresses.
- Companies: street lines dropped, postal code cut to 3 characters (FSA), city cleaned. Any corporation whose name may be a person's (e.g. "Jane Doe Professional Corporation") is dropped entirely.
- NS awards: the vendor is named only if it carries a legal-form suffix (Inc, Ltd, ...) or is a public body and doesn't look like a person. Otherwise the summary says "vendor name withheld".
- Permits: no address, PID, applicant, contractor or description fields are read.
State and dedupe
The named key-value store stateStore holds SEEN_IDS = {version, lastRunDate, seen: {id: firstSeenDate}}. Only returned items are marked seen. IDs older than 400 days are pruned. Delete the store or change stateStore to start over.
Pricing events (.actor/pay_per_event.json)
result $0.01 per returned item (Actor.charge("result", count=n)), digest $0.05 once per run (Actor.charge("digest")). If the caller's spending limit is lower, the item count is cut to fit. This pricing is live on Apify.