<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Dave Zavin</title>
    <description>The latest articles on DEV Community by Dave Zavin (@truenorthdata).</description>
    <link>https://dev.to/truenorthdata</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4014152%2F6fecd1d6-be70-4cd6-b16b-30de34c218b6.jpg</url>
      <title>DEV Community: Dave Zavin</title>
      <link>https://dev.to/truenorthdata</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/truenorthdata"/>
    <language>en</language>
    <item>
      <title>Two free n8n templates for Canadian B2B lead lists (copy-paste import)</title>
      <dc:creator>Dave Zavin</dc:creator>
      <pubDate>Fri, 24 Jul 2026 17:20:56 +0000</pubDate>
      <link>https://dev.to/truenorthdata/two-free-n8n-templates-for-canadian-b2b-lead-lists-copy-paste-import-1mkd</link>
      <guid>https://dev.to/truenorthdata/two-free-n8n-templates-for-canadian-b2b-lead-lists-copy-paste-import-1mkd</guid>
      <description>&lt;h1&gt;
  
  
  Two free n8n templates for Canadian B2B lead lists (copy-paste import)
&lt;/h1&gt;

&lt;p&gt;If you run outbound, you already know the best lists are &lt;em&gt;trigger-based&lt;/em&gt;: a company that just incorporated, a property that just pulled a building permit. Those are people who just started spending — reach them first and you win the deal.&lt;/p&gt;

&lt;p&gt;Below are two ready-to-run n8n workflows that build those lists for you on a schedule and drop them into a Google Sheet (or your CRM). Both pull from official Canadian open data via Apify actors, and both &lt;strong&gt;deduplicate automatically&lt;/strong&gt; — each run only appends leads you haven't seen.&lt;/p&gt;

&lt;p&gt;No coding. Copy the JSON, import it into n8n, plug in two credentials, done.&lt;/p&gt;




&lt;h2&gt;
  
  
  Template 1 — Daily feed of newly incorporated Canadian companies
&lt;/h2&gt;

&lt;p&gt;Every morning this appends the previous day's newly registered Canadian federal companies to a Google Sheet — a fresh outbound list of brand-new businesses (great for banks, insurers, SaaS, agencies, and anyone selling to new companies).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to use it&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In n8n: open a new workflow → &lt;strong&gt;⋮ menu → Import from clipboard&lt;/strong&gt; (or &lt;em&gt;Import from File&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;Paste the JSON below.&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;HTTP&lt;/strong&gt; node, replace &lt;code&gt;YOUR_APIFY_API_TOKEN&lt;/code&gt; with your Apify API token (console.apify.com → Settings → Integrations).&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;Google Sheets&lt;/strong&gt; node, connect your Google account and set &lt;code&gt;YOUR_GOOGLE_SHEET_ID&lt;/code&gt; + tab name.&lt;/li&gt;
&lt;li&gt;Activate. Swap the Sheet node for HubSpot / Pipedrive / Salesforce to route leads straight into your CRM.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Daily new Canadian companies → Google Sheet (TrueNorthData)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"nodes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"parameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"interval"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"field"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"days"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"triggerAtHour"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"a1b2c3d4-1111-4aaa-8000-000000000001"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Every day at 8am"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"n8n-nodes-base.scheduleTrigger"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"typeVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;260&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"parameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"POST"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://api.apify.com/v2/acts/truenorthdata~canada-new-incorporations/run-sync-get-dataset-items"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"sendQuery"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"queryParameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"parameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"token"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"YOUR_APIFY_API_TOKEN"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"sendBody"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"specifyBody"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"jsonBody"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"={&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;  &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;incorporatedWithinDays&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: 3,&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;  &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;onlyNewSinceLastRun&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: true&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"options"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"a1b2c3d4-2222-4aaa-8000-000000000002"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Apify: new incorporations (net-new)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"n8n-nodes-base.httpRequest"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"typeVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;4.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;520&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"parameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"operation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"append"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"documentId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"__rl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"YOUR_GOOGLE_SHEET_ID"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"sheetName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"__rl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Sheet1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"columns"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mappingMode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"autoMapInputData"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"matchingColumns"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"options"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"a1b2c3d4-3333-4aaa-8000-000000000003"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Append to Google Sheet"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"n8n-nodes-base.googleSheets"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"typeVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;4.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;780&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"connections"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Every day at 8am"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[[{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Apify: new incorporations (net-new)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"index"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}]]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Apify: new incorporations (net-new)"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[[{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Append to Google Sheet"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"index"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}]]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"active"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"settings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"executionOrder"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"v1"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"pinData"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"meta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"templateCredsSetupCompleted"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why it stays fresh:&lt;/strong&gt; &lt;code&gt;onlyNewSinceLastRun: true&lt;/code&gt; means every run only appends companies you haven't pulled before — no dupes. &lt;code&gt;incorporatedWithinDays: 3&lt;/code&gt; plus the actor's live-registry probe catch companies incorporated in the last few days that the bulk government file hasn't published yet.&lt;/p&gt;

&lt;p&gt;Actor: &lt;a href="https://apify.com/truenorthdata/canada-new-incorporations" rel="noopener noreferrer"&gt;Canada New Incorporations&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Template 2 — Weekly Canadian building-permit leads
&lt;/h2&gt;

&lt;p&gt;Every Monday this pulls fresh building permits from Toronto, Vancouver, Calgary, Edmonton and Montréal, filters to your trade and minimum project value, and appends them to a Sheet — a weekly list of properties actively spending on construction. Ideal for contractors, trades, and building-material suppliers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tune it to your business&lt;/strong&gt; in the HTTP node body: change &lt;code&gt;keywords&lt;/code&gt; (&lt;code&gt;roof&lt;/code&gt;, &lt;code&gt;solar&lt;/code&gt;, &lt;code&gt;pool&lt;/code&gt;, &lt;code&gt;hvac&lt;/code&gt;, &lt;code&gt;deck&lt;/code&gt;, &lt;code&gt;basement&lt;/code&gt;…), set your &lt;code&gt;minProjectValue&lt;/code&gt;, and drop any cities you don't serve.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Weekly Canadian building-permit leads → Google Sheet (TrueNorthData)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"nodes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"parameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"interval"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"field"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"weeks"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"triggerAtDay"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"triggerAtHour"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"b1b2c3d4-1111-4bbb-8000-000000000001"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Every Monday 8am"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"n8n-nodes-base.scheduleTrigger"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"typeVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;260&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"parameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"POST"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://api.apify.com/v2/acts/truenorthdata~canada-building-permits/run-sync-get-dataset-items"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"sendQuery"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"queryParameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"parameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"token"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"YOUR_APIFY_API_TOKEN"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"sendBody"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"specifyBody"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"jsonBody"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"={&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;  &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;cities&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: [&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;toronto&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;vancouver&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;calgary&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;edmonton&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;montreal&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;],&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;  &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;issuedWithinDays&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: 7,&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;  &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;keywords&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: [&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;roof&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;],&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;  &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;minProjectValue&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: 20000,&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;  &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;onlyNewSinceLastRun&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: true&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"options"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"b1b2c3d4-2222-4bbb-8000-000000000002"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Apify: fresh permits (net-new)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"n8n-nodes-base.httpRequest"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"typeVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;4.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;520&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"parameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"operation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"append"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"documentId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"__rl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"YOUR_GOOGLE_SHEET_ID"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"sheetName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"__rl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Sheet1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"columns"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mappingMode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"autoMapInputData"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"matchingColumns"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"options"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"b1b2c3d4-3333-4bbb-8000-000000000003"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Append to Google Sheet"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"n8n-nodes-base.googleSheets"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"typeVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;4.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;780&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"connections"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Every Monday 8am"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[[{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Apify: fresh permits (net-new)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"index"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}]]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Apify: fresh permits (net-new)"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[[{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Append to Google Sheet"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"index"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}]]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"active"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"settings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"executionOrder"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"v1"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"pinData"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"meta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"templateCredsSetupCompleted"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Actor: &lt;a href="https://apify.com/truenorthdata/canada-building-permits" rel="noopener noreferrer"&gt;Canada Building Permits&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Setup notes (both templates)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Apify token:&lt;/strong&gt; free tier is enough to test. Get it at console.apify.com → Settings → Integrations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Route anywhere:&lt;/strong&gt; the Google Sheets node is just an example. Replace it with an HTTP node to your CRM, a Slack alert, or an email digest.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Widen or narrow the window:&lt;/strong&gt; &lt;code&gt;incorporatedWithinDays&lt;/code&gt; / &lt;code&gt;issuedWithinDays&lt;/code&gt; control how far back each run looks; &lt;code&gt;onlyNewSinceLastRun&lt;/code&gt; keeps it deduped.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both actors are built on official Canadian open data (Corporations Canada; municipal open-data programs). More Canadian data actors: &lt;a href="https://apify.com/truenorthdata" rel="noopener noreferrer"&gt;TrueNorthData on Apify&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Questions or a city/dataset you want added? Drop a comment.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>n8n</category>
      <category>automation</category>
      <category>sales</category>
      <category>apify</category>
    </item>
    <item>
      <title>How to verify a Canadian contractor's licence (RBQ &amp; HCRA) — built on open data</title>
      <dc:creator>Dave Zavin</dc:creator>
      <pubDate>Fri, 24 Jul 2026 16:52:58 +0000</pubDate>
      <link>https://dev.to/truenorthdata/how-to-verify-a-canadian-contractors-licence-rbq-hcra-built-on-open-data-16k8</link>
      <guid>https://dev.to/truenorthdata/how-to-verify-a-canadian-contractors-licence-rbq-hcra-built-on-open-data-16k8</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This is a cross-post of a guide from &lt;a href="https://checkcontractors.ca/guides/verify-contractor-licence" rel="noopener noreferrer"&gt;CheckContractors.ca&lt;/a&gt;, a small side project that turns Canada's official contractor-licence registries (Quebec RBQ, Ontario HCRA) into a fast, searchable lookup. The data comes from official open-data sources; the lookup is a Cloudflare + Astro app over a D1 database.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Before you hire a contractor or buy a newly built home in Canada, confirm they're properly licensed. An unlicensed contractor can leave you with no legal recourse, voided warranties, and no protection if the work goes wrong. Here's how licensing works in &lt;strong&gt;Quebec (RBQ)&lt;/strong&gt; and &lt;strong&gt;Ontario (HCRA)&lt;/strong&gt;, and how to check a contractor in a couple of minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a licence matters
&lt;/h2&gt;

&lt;p&gt;A licence means the contractor has met the province's qualifications, carries the required security or bond, and is accountable to a regulator. Hiring an unlicensed contractor for work that requires a licence can expose you to unsafe work, no warranty coverage, and difficulty claiming compensation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quebec — RBQ licences
&lt;/h2&gt;

&lt;p&gt;In Quebec, most construction work must be done by a contractor holding a licence from the &lt;strong&gt;Régie du bâtiment du Québec (RBQ)&lt;/strong&gt;. The licence lists &lt;em&gt;subclasses&lt;/em&gt; — the specific kinds of work the contractor is qualified to do (electrical, plumbing, roofing, etc.).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Ask the contractor for their RBQ licence number.&lt;/li&gt;
&lt;li&gt;Search it on the &lt;a href="https://checkcontractors.ca/qc" rel="noopener noreferrer"&gt;Quebec RBQ licence lookup&lt;/a&gt; by name or licence number, or verify directly on the &lt;a href="https://www.rbq.gouv.qc.ca/" rel="noopener noreferrer"&gt;official RBQ registry&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Check that the licence is &lt;strong&gt;active&lt;/strong&gt; and that its subclasses cover the work you need.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Browse &lt;a href="https://checkcontractors.ca/qc/trades" rel="noopener noreferrer"&gt;Quebec contractors by trade&lt;/a&gt; — e.g. &lt;a href="https://checkcontractors.ca/qc/trade/electrician" rel="noopener noreferrer"&gt;electricians&lt;/a&gt;, &lt;a href="https://checkcontractors.ca/qc/trade/plumber" rel="noopener noreferrer"&gt;plumbers&lt;/a&gt;, &lt;a href="https://checkcontractors.ca/qc/trade/roofer" rel="noopener noreferrer"&gt;roofers&lt;/a&gt; — or &lt;a href="https://checkcontractors.ca/qc/cities" rel="noopener noreferrer"&gt;by city&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ontario — HCRA licensed builders
&lt;/h2&gt;

&lt;p&gt;In Ontario, new-home builders and vendors must be licensed by the &lt;strong&gt;Home Construction Regulatory Authority (HCRA)&lt;/strong&gt;. This is who to check if you're buying a newly built or pre-construction home.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get the builder's name or licence number.&lt;/li&gt;
&lt;li&gt;Search it on the &lt;a href="https://checkcontractors.ca/on" rel="noopener noreferrer"&gt;Ontario HCRA builder lookup&lt;/a&gt;, or on the &lt;a href="https://www.hcraontario.ca/" rel="noopener noreferrer"&gt;official HCRA registry&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Confirm the builder is licensed and review any conditions on the record.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Browse &lt;a href="https://checkcontractors.ca/on/cities" rel="noopener noreferrer"&gt;Ontario builders by city&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Red flags
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Refuses to give a licence number, or the number doesn't match the business name.&lt;/li&gt;
&lt;li&gt;Asks for a large cash deposit up front, or pressures you to skip a written contract.&lt;/li&gt;
&lt;li&gt;The licence is expired, suspended, or restricted on the official registry.&lt;/li&gt;
&lt;li&gt;The licence subclasses don't cover the work you're hiring for.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Verify before you sign
&lt;/h2&gt;

&lt;p&gt;A two-minute check can save a very expensive mistake. Start with the &lt;a href="https://checkcontractors.ca/qc" rel="noopener noreferrer"&gt;Quebec (RBQ)&lt;/a&gt; or &lt;a href="https://checkcontractors.ca/on" rel="noopener noreferrer"&gt;Ontario (HCRA)&lt;/a&gt; lookup, and always confirm the details on the official provincial registry.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Building on Canadian open data too? The licence datasets behind this are also available as an &lt;a href="https://apify.com/truenorthdata/canada-contractor-licenses" rel="noopener noreferrer"&gt;Apify actor&lt;/a&gt; (JSON/CSV/MCP). Not affiliated with the RBQ or HCRA — always confirm on the official registry.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>opendata</category>
      <category>canada</category>
      <category>webdev</category>
      <category>dataengineering</category>
    </item>
    <item>
      <title>Two free n8n templates for Canadian B2B lead lists (copy-paste import)</title>
      <dc:creator>Dave Zavin</dc:creator>
      <pubDate>Sun, 19 Jul 2026 22:00:00 +0000</pubDate>
      <link>https://dev.to/truenorthdata/two-free-n8n-templates-for-canadian-b2b-lead-lists-copy-paste-import-49ie</link>
      <guid>https://dev.to/truenorthdata/two-free-n8n-templates-for-canadian-b2b-lead-lists-copy-paste-import-49ie</guid>
      <description>&lt;h1&gt;
  
  
  Two free n8n templates for Canadian B2B lead lists (copy-paste import)
&lt;/h1&gt;

&lt;p&gt;If you run outbound, you already know the best lists are &lt;em&gt;trigger-based&lt;/em&gt;: a company that just incorporated, a property that just pulled a building permit. Those are people who just started spending — reach them first and you win the deal.&lt;/p&gt;

&lt;p&gt;Below are two ready-to-run n8n workflows that build those lists for you on a schedule and drop them into a Google Sheet (or your CRM). Both pull from official Canadian open data via Apify actors, and both &lt;strong&gt;deduplicate automatically&lt;/strong&gt; — each run only appends leads you haven't seen.&lt;/p&gt;

&lt;p&gt;No coding. Copy the JSON, import it into n8n, plug in two credentials, done.&lt;/p&gt;




&lt;h2&gt;
  
  
  Template 1 — Daily feed of newly incorporated Canadian companies
&lt;/h2&gt;

&lt;p&gt;Every morning this appends the previous day's newly registered Canadian federal companies to a Google Sheet — a fresh outbound list of brand-new businesses (great for banks, insurers, SaaS, agencies, and anyone selling to new companies).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to use it&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In n8n: open a new workflow → &lt;strong&gt;⋮ menu → Import from clipboard&lt;/strong&gt; (or &lt;em&gt;Import from File&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;Paste the JSON below.&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;HTTP&lt;/strong&gt; node, replace &lt;code&gt;YOUR_APIFY_API_TOKEN&lt;/code&gt; with your Apify API token (console.apify.com → Settings → Integrations).&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;Google Sheets&lt;/strong&gt; node, connect your Google account and set &lt;code&gt;YOUR_GOOGLE_SHEET_ID&lt;/code&gt; + tab name.&lt;/li&gt;
&lt;li&gt;Activate. Swap the Sheet node for HubSpot / Pipedrive / Salesforce to route leads straight into your CRM.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Daily new Canadian companies → Google Sheet (TrueNorthData)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"nodes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"parameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"interval"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"field"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"days"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"triggerAtHour"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"a1b2c3d4-1111-4aaa-8000-000000000001"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Every day at 8am"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"n8n-nodes-base.scheduleTrigger"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"typeVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;260&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"parameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"POST"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://api.apify.com/v2/acts/truenorthdata~canada-new-incorporations/run-sync-get-dataset-items"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"sendQuery"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"queryParameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"parameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"token"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"YOUR_APIFY_API_TOKEN"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"sendBody"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"specifyBody"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"jsonBody"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"={&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;  &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;incorporatedWithinDays&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: 3,&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;  &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;onlyNewSinceLastRun&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: true&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"options"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"a1b2c3d4-2222-4aaa-8000-000000000002"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Apify: new incorporations (net-new)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"n8n-nodes-base.httpRequest"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"typeVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;4.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;520&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"parameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"operation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"append"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"documentId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"__rl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"YOUR_GOOGLE_SHEET_ID"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"sheetName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"__rl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Sheet1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"columns"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mappingMode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"autoMapInputData"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"matchingColumns"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"options"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"a1b2c3d4-3333-4aaa-8000-000000000003"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Append to Google Sheet"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"n8n-nodes-base.googleSheets"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"typeVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;4.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;780&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"connections"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Every day at 8am"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[[{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Apify: new incorporations (net-new)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"index"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}]]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Apify: new incorporations (net-new)"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[[{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Append to Google Sheet"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"index"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}]]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"active"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"settings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"executionOrder"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"v1"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"pinData"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"meta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"templateCredsSetupCompleted"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why it stays fresh:&lt;/strong&gt; &lt;code&gt;onlyNewSinceLastRun: true&lt;/code&gt; means every run only appends companies you haven't pulled before — no dupes. &lt;code&gt;incorporatedWithinDays: 3&lt;/code&gt; plus the actor's live-registry probe catch companies incorporated in the last few days that the bulk government file hasn't published yet.&lt;/p&gt;

&lt;p&gt;Actor: &lt;a href="https://apify.com/truenorthdata/canada-new-incorporations" rel="noopener noreferrer"&gt;Canada New Incorporations&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Template 2 — Weekly Canadian building-permit leads
&lt;/h2&gt;

&lt;p&gt;Every Monday this pulls fresh building permits from Toronto, Vancouver, Calgary, Edmonton and Montréal, filters to your trade and minimum project value, and appends them to a Sheet — a weekly list of properties actively spending on construction. Ideal for contractors, trades, and building-material suppliers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tune it to your business&lt;/strong&gt; in the HTTP node body: change &lt;code&gt;keywords&lt;/code&gt; (&lt;code&gt;roof&lt;/code&gt;, &lt;code&gt;solar&lt;/code&gt;, &lt;code&gt;pool&lt;/code&gt;, &lt;code&gt;hvac&lt;/code&gt;, &lt;code&gt;deck&lt;/code&gt;, &lt;code&gt;basement&lt;/code&gt;…), set your &lt;code&gt;minProjectValue&lt;/code&gt;, and drop any cities you don't serve.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Weekly Canadian building-permit leads → Google Sheet (TrueNorthData)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"nodes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"parameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"interval"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"field"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"weeks"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"triggerAtDay"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"triggerAtHour"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"b1b2c3d4-1111-4bbb-8000-000000000001"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Every Monday 8am"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"n8n-nodes-base.scheduleTrigger"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"typeVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;260&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"parameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"POST"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://api.apify.com/v2/acts/truenorthdata~canada-building-permits/run-sync-get-dataset-items"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"sendQuery"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"queryParameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"parameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"token"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"YOUR_APIFY_API_TOKEN"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"sendBody"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"specifyBody"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"jsonBody"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"={&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;  &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;cities&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: [&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;toronto&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;vancouver&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;calgary&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;edmonton&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;montreal&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;],&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;  &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;issuedWithinDays&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: 7,&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;  &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;keywords&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: [&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;roof&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;],&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;  &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;minProjectValue&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: 20000,&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;  &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;onlyNewSinceLastRun&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: true&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"options"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"b1b2c3d4-2222-4bbb-8000-000000000002"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Apify: fresh permits (net-new)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"n8n-nodes-base.httpRequest"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"typeVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;4.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;520&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"parameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"operation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"append"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"documentId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"__rl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"YOUR_GOOGLE_SHEET_ID"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"sheetName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"__rl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Sheet1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"columns"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mappingMode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"autoMapInputData"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"matchingColumns"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"options"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"b1b2c3d4-3333-4bbb-8000-000000000003"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Append to Google Sheet"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"n8n-nodes-base.googleSheets"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"typeVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;4.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;780&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"connections"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Every Monday 8am"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[[{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Apify: fresh permits (net-new)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"index"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}]]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Apify: fresh permits (net-new)"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[[{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Append to Google Sheet"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"index"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}]]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"active"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"settings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"executionOrder"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"v1"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"pinData"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"meta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"templateCredsSetupCompleted"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Actor: &lt;a href="https://apify.com/truenorthdata/canada-building-permits" rel="noopener noreferrer"&gt;Canada Building Permits&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Setup notes (both templates)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Apify token:&lt;/strong&gt; free tier is enough to test. Get it at console.apify.com → Settings → Integrations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Route anywhere:&lt;/strong&gt; the Google Sheets node is just an example. Replace it with an HTTP node to your CRM, a Slack alert, or an email digest.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Widen or narrow the window:&lt;/strong&gt; &lt;code&gt;incorporatedWithinDays&lt;/code&gt; / &lt;code&gt;issuedWithinDays&lt;/code&gt; control how far back each run looks; &lt;code&gt;onlyNewSinceLastRun&lt;/code&gt; keeps it deduped.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both actors are built on official Canadian open data (Corporations Canada; municipal open-data programs). More Canadian data actors: &lt;a href="https://apify.com/truenorthdata" rel="noopener noreferrer"&gt;TrueNorthData on Apify&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Questions or a city/dataset you want added? Drop a comment.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>n8nbrightdatachallenge</category>
      <category>automation</category>
      <category>showdev</category>
      <category>apify</category>
    </item>
    <item>
      <title>How I turned Canada's messy open government data into 3 clean data products</title>
      <dc:creator>Dave Zavin</dc:creator>
      <pubDate>Fri, 17 Jul 2026 18:12:57 +0000</pubDate>
      <link>https://dev.to/truenorthdata/how-i-turned-canadas-messy-open-government-data-into-3-clean-data-products-12kf</link>
      <guid>https://dev.to/truenorthdata/how-i-turned-canadas-messy-open-government-data-into-3-clean-data-products-12kf</guid>
      <description>&lt;p&gt;Canadian government data is &lt;em&gt;public&lt;/em&gt;. That's the good news. The bad news is that&lt;br&gt;
"public" and "usable" are two very different things.&lt;/p&gt;

&lt;p&gt;The same category of data lives in a dozen portals, in three different formats,&lt;br&gt;
half of it only in French, with schemas that change per municipality. If you want&lt;br&gt;
"licensed contractors in Canada" or "open government tenders," you don't get a table —&lt;br&gt;
you get a scavenger hunt.&lt;/p&gt;

&lt;p&gt;So I built the scavenger hunt once, cleaned everything up, and published three free&lt;br&gt;
data products on Snowflake Marketplace (also on Apify as API/no-code actors):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Licensed Contractors&lt;/strong&gt; — Quebec (RBQ) + Ontario (HCRA), ~60,500 records&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Building Permits&lt;/strong&gt; — with contractor names + project values, ~16,500 records&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Government Tenders&lt;/strong&gt; — federal (CanadaBuys) + Québec (SEAO), ~10,000 open bids&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's how it's built, quirks and all.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 1: Sources and licences (do it legally)
&lt;/h2&gt;

&lt;p&gt;Everything is built on official open data with permissive licences. This matters —&lt;br&gt;
you can't resell scraped data you don't have the right to redistribute.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;RBQ&lt;/strong&gt; (Quebec contractor licences) — a bulk CSV shipped in a ~10 MB zip,
refreshed daily, CC-BY. ~924k raw rows collapse to ~54k unique active holders.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HCRA&lt;/strong&gt; (Ontario home builders) — no bulk file, but an internal JSON API:
&lt;code&gt;obd.hcraontario.ca/api/builders?builderName=&amp;lt;term&amp;gt;&lt;/code&gt; (an empty term 500s, so you
iterate). Details come from &lt;code&gt;/api/buildersummary?id=&amp;lt;ACCT&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CanadaBuys&lt;/strong&gt; (federal tenders) — a ~100 MB CSV on CloudFront, refreshed daily
for open tenders, every 2 hours for new ones.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SEAO&lt;/strong&gt; (Québec public sector) — weekly OCDS/CKAN files from the Données Québec
catalogue. You have to resolve the &lt;em&gt;newest&lt;/em&gt; weekly files programmatically.&lt;/li&gt;
&lt;li&gt;Building permits — a different API per city: Toronto (CKAN), Vancouver
(Opendatasoft), Calgary/Edmonton (Socrata), Montréal (CKAN CSV, in French).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lesson one: there is no such thing as "the Canada open-data API." Every source is a&lt;br&gt;
one-off.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 2: The scraping quirks that cost me the most time
&lt;/h2&gt;

&lt;p&gt;A few things that aren't in any tutorial:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SEAO weekly files&lt;/strong&gt; — the catalogue lists many resources; you want the latest N
weekly OCDS files and have to sort/resolve them by date, then handle the OCDS
release structure, not a flat row.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Socrata lag&lt;/strong&gt; — Calgary's permit data can trail reality by ~6 weeks. Don't
promise "real-time" on data that isn't.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;French-first fields&lt;/strong&gt; — SEAO titles are in French. If you filter by keyword you
need French terms ("informatique," "construction") or you silently drop Québec rows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Encoding&lt;/strong&gt; — the classic Windows gotcha. When you shell out to a scraper and
capture its output, Python defaults to cp1252 and dies on the first emoji/UTF-8 byte:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# This blows up on Windows with UnicodeDecodeError: 'charmap' codec...
&lt;/span&gt;&lt;span class="n"&gt;subprocess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;capture_output&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# This doesn't:
&lt;/span&gt;&lt;span class="n"&gt;subprocess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;capture_output&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;utf-8&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;replace&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Step 3: Normalize to one clean schema
&lt;/h2&gt;

&lt;p&gt;Each source gets mapped into a single, boring, predictable schema. For contractors:&lt;br&gt;
&lt;code&gt;legal_name, province, licence_body, licence_number, city, postal, status&lt;/code&gt;. Then a&lt;br&gt;
normalized &lt;code&gt;name_key&lt;/code&gt; for dedupe across RBQ + HCRA:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;unicodedata&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;namekey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;unicodedata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;normalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;NFKD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ascii&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ignore&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[^a-z0-9 ]&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

&lt;span class="c1"&gt;# dedupe on (name_key, province) after concatenating sources
&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name_key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;drop_duplicates&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name_key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;province&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The one rule I never break:&lt;/strong&gt; no personal contact info for private individuals.&lt;br&gt;
The normalizer simply doesn't carry personal emails/phones into the output, and every&lt;br&gt;
product links back to the official registry so anyone can verify the source record.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 4: Load into Snowflake without breaking the listing
&lt;/h2&gt;

&lt;p&gt;This is the part that surprised me. Once a table is published on Snowflake&lt;br&gt;
Marketplace, you can't just &lt;code&gt;DROP&lt;/code&gt; and recreate it — that detaches the share. You want&lt;br&gt;
to &lt;strong&gt;replace the rows but keep the table object&lt;/strong&gt;. So the weekly refresh does&lt;br&gt;
&lt;code&gt;TRUNCATE&lt;/code&gt; + &lt;code&gt;PUT&lt;/code&gt; a Parquet file to the table stage + &lt;code&gt;COPY INTO&lt;/code&gt; with&lt;br&gt;
&lt;code&gt;MATCH_BY_COLUMN_NAME&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PUT &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;file://&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;parquet&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; @%&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; AUTO_COMPRESS=FALSE OVERWRITE=TRUE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TRUNCATE TABLE &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;cur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;COPY INTO &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; FROM @%&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;parquet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;FILE_FORMAT=(TYPE=PARQUET) MATCH_BY_COLUMN_NAME=CASE_INSENSITIVE &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ON_ERROR=ABORT_STATEMENT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two more things that saved me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Key-pair auth&lt;/strong&gt;, so the scheduled job authenticates without MFA prompts. Generate
an RSA key, &lt;code&gt;ALTER USER ... SET RSA_PUBLIC_KEY=...&lt;/code&gt;, and pass the private key to the
connector.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An empty-guard&lt;/strong&gt;: if a rebuild comes back with 0 rows (a scraper failed), abort
the load. Never let a broken run truncate a live product to empty.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product_a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product_b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;SystemExit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;a product came back EMPTY - aborting load&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5: Ship it — free, cross-cloud
&lt;/h2&gt;

&lt;p&gt;All three are free listings on Snowflake Marketplace with &lt;strong&gt;cross-cloud&lt;br&gt;
auto-fulfillment&lt;/strong&gt; enabled, so a consumer in another region gets the data replicated&lt;br&gt;
on demand instead of me pre-copying it everywhere. The whole refresh runs weekly from&lt;br&gt;
a single scheduled task.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;Ontario building permits, BC contractor licences, and a few more provinces are on the&lt;br&gt;
list. If you work with Canadian market data — outbound to contractors, construction&lt;br&gt;
analytics, or bidding on public tenders — I'd love to know which dataset or province&lt;br&gt;
to add next.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Snowflake Marketplace:
&lt;a href="https://app.snowflake.com/marketplace/listing/GZ2FQZ1O9RH0" rel="noopener noreferrer"&gt;Licensed Contractors&lt;/a&gt; ·
&lt;a href="https://app.snowflake.com/marketplace/listing/GZ2FQZ1O9RH4" rel="noopener noreferrer"&gt;Building Permits&lt;/a&gt; ·
&lt;a href="https://app.snowflake.com/marketplace/listing/GZ2FQZ1O9RH8" rel="noopener noreferrer"&gt;Government Tenders&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Apify actors (API + no-code): &lt;a href="https://apify.com/truenorthdata" rel="noopener noreferrer"&gt;https://apify.com/truenorthdata&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Homeowner contractor lookup: &lt;a href="https://checkcontractors.ca" rel="noopener noreferrer"&gt;https://checkcontractors.ca&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;All data built on official open sources (Open Government Licence – Canada,&lt;br&gt;
RBQ/SEAO CC-BY), with a link to the official registry on every record.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>dataengineering</category>
      <category>python</category>
      <category>snowflake</category>
      <category>opendata</category>
    </item>
    <item>
      <title>How to Verify Canadian Contractor Licences at Scale (RBQ and HCRA, 2026)</title>
      <dc:creator>Dave Zavin</dc:creator>
      <pubDate>Sun, 12 Jul 2026 17:32:49 +0000</pubDate>
      <link>https://dev.to/truenorthdata/how-to-verify-canadian-contractor-licences-at-scale-rbq-and-hcra-2026-3gj8</link>
      <guid>https://dev.to/truenorthdata/how-to-verify-canadian-contractor-licences-at-scale-rbq-and-hcra-2026-3gj8</guid>
      <description>&lt;p&gt;Before anyone hires a contractor or lets a builder onto a platform, one question matters: are they actually licensed, and is that licence in good standing? In Canada the answer lives in provincial registries — Quebec's RBQ, Ontario's HCRA — and checking one contractor by hand is easy. Checking hundreds, or wiring the check into your product, is where it gets painful. This is a practical guide to verifying Canadian contractor licences at scale, plus a free tool for one-off lookups.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two ways to use licence data
&lt;/h2&gt;

&lt;p&gt;One-off checks (free). If you just need to confirm a specific contractor before hiring, use a lookup. &lt;a href="https://checkcontractors.ca" rel="noopener noreferrer"&gt;CheckContractors.ca&lt;/a&gt; aggregates Quebec (RBQ) and Ontario (HCRA) licences into one search — type a name or licence number and see the status. Always confirm on the official registry too; the site links back to it.&lt;/p&gt;

&lt;p&gt;At scale (data / API). If you run a marketplace, an insurer, a screening service, or any product that needs to verify contractors programmatically, you don't want to retype names into a government portal. You want the registry as structured data. That's the &lt;a href="https://apify.com/truenorthdata/canada-contractor-licenses" rel="noopener noreferrer"&gt;Canada Contractor Licences actor&lt;/a&gt;: Quebec RBQ and Ontario HCRA records — name, licence number, status, location — as JSON/CSV, updated regularly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why status is the whole point
&lt;/h2&gt;

&lt;p&gt;A licence lookup isn't just "do they exist." The valuable signal is status: Active, Licensed, Licensed with Conditions — and the red flags: Revoked, Suspended, Refused, Cancelled. For anyone doing risk or trust work, those negative statuses are exactly what you're screening for. A marketplace wants to keep revoked builders off the platform; an insurer wants to price around them. The data carries all of it, not just the clean records.&lt;/p&gt;

&lt;h2&gt;
  
  
  The recipe: verification at scale
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Pull the registry. Run the Canada Contractor Licences actor for Quebec, Ontario, or both.&lt;/li&gt;
&lt;li&gt;Match against your list. Join it to your existing contractors/vendors by name or licence number to flag who's licensed, who isn't, and whose status changed.&lt;/li&gt;
&lt;li&gt;Screen for red flags. Filter for Revoked / Suspended / Refused to catch the records that should stop a hire or an approval.&lt;/li&gt;
&lt;li&gt;Wire it into your flow. Via Make or n8n or the Apify API, refresh on a schedule so your platform's licence checks stay current instead of going stale the day after onboarding.&lt;/li&gt;
&lt;li&gt;Keep the official registry as source of truth. Aggregated data is for scale and screening; for a formal decision, confirm the current status on the RBQ/HCRA registry itself.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Who uses this
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Home-services marketplaces and directories — verify and badge contractors, keep revoked ones out.&lt;/li&gt;
&lt;li&gt;Insurers and underwriters — licence status as a risk input.&lt;/li&gt;
&lt;li&gt;Background-check and vendor-screening services — add contractor-licensing to their checks.&lt;/li&gt;
&lt;li&gt;Lead-gen and proptech platforms — filter their contractor lists to licensed-only.&lt;/li&gt;
&lt;li&gt;Homeowners — the free &lt;a href="https://checkcontractors.ca" rel="noopener noreferrer"&gt;CheckContractors.ca&lt;/a&gt; lookup for a single check before hiring.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The honest part
&lt;/h2&gt;

&lt;p&gt;Licensing is provincial, so coverage is by province — this is Quebec (RBQ) and Ontario (HCRA) today, the two biggest, with more provinces the natural next step. And aggregated data is for scale and screening, not the final word: registries update on their own cadence, so for a formal, high-stakes decision, always re-check the current status on the official provincial registry. Use the dataset to work fast across thousands; use the official source to close the loop on the one that matters.&lt;/p&gt;




&lt;p&gt;Free single lookup: &lt;a href="https://checkcontractors.ca" rel="noopener noreferrer"&gt;CheckContractors.ca&lt;/a&gt;. Bulk / API data for Quebec and Ontario: the &lt;a href="https://apify.com/truenorthdata/canada-contractor-licenses" rel="noopener noreferrer"&gt;Canada Contractor Licences actor&lt;/a&gt;. Questions about verifying licences at scale? Happy to help in the comments.&lt;/p&gt;

</description>
      <category>api</category>
      <category>data</category>
      <category>saas</category>
      <category>opendata</category>
    </item>
    <item>
      <title>How to Get Clean Data on Every Registered Canadian Charity (CRA List, 2026)</title>
      <dc:creator>Dave Zavin</dc:creator>
      <pubDate>Sun, 12 Jul 2026 17:28:01 +0000</pubDate>
      <link>https://dev.to/truenorthdata/how-to-get-clean-data-on-every-registered-canadian-charity-cra-list-2026-ig</link>
      <guid>https://dev.to/truenorthdata/how-to-get-clean-data-on-every-registered-canadian-charity-cra-list-2026-ig</guid>
      <description>&lt;p&gt;Canada has tens of thousands of registered charities, and every one of them is public record — the CRA maintains the official list. If you sell to the nonprofit sector, research it, or serve it, that list is the foundation you want. The catch is that the raw source is built for lookups, not for bulk analysis: it's awkward to pull, split across files, and not exactly friendly to drop into a CRM or a notebook. This is a practical recipe for turning the CRA charity registry into a clean dataset you can actually work with.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the charity registry is worth having as data
&lt;/h2&gt;

&lt;p&gt;Two very different groups want this list, for opposite reasons.&lt;/p&gt;

&lt;p&gt;If you sell to charities — accounting, fundraising software, event services, insurance, consulting — the registry is your total addressable market, by name, category, and location. Instead of guessing who your prospects are, you start from the actual list of every registered organization and filter to the ones you serve.&lt;/p&gt;

&lt;p&gt;If you study or serve the sector — researchers, journalists, foundations, sector associations — the registry is the backbone of any analysis: how many charities operate in a category, where they're concentrated, how the sector is changing over time.&lt;/p&gt;

&lt;p&gt;Either way, you want it as structured data, not a search box.&lt;/p&gt;

&lt;h2&gt;
  
  
  The data source
&lt;/h2&gt;

&lt;p&gt;The registry comes from the CRA List of Charities. Rather than wrangle the official files yourself (they arrive split across multiple CSVs that need to be joined on the business number, with their own quirks), you can pull a cleaned, joined dataset through an Apify actor: &lt;a href="https://apify.com/truenorthdata/canada-charities" rel="noopener noreferrer"&gt;Canada Charities Scraper&lt;/a&gt;. It outputs the registered charities with their identifiers, category, and location as JSON/CSV.&lt;/p&gt;

&lt;p&gt;A note on freshness so you use it correctly: the CRA publishes this list on a slow cadence (roughly annually), so this is reference data, not a live feed. That's exactly right for its use cases — you're mapping and analyzing a sector, not chasing same-day events.&lt;/p&gt;

&lt;h2&gt;
  
  
  The recipe: registry to a working list
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Pull the dataset. Run the Canada Charities Scraper to get the registered charities in one clean file.&lt;/li&gt;
&lt;li&gt;Filter to your segment. Narrow by category (religion, education, health, social services, arts, etc.), province/city, or status. A fundraising-software vendor might want mid-sized charities in specific categories; a researcher might want everything in one province.&lt;/li&gt;
&lt;li&gt;Enrich if you're prospecting. From the charity name, use a tool like Clay to find the website and a contact for outreach. The registry gives you the universe; enrichment makes it contactable.&lt;/li&gt;
&lt;li&gt;Load it where you work. Drop the file into a CRM, a Google Sheet, Airtable, or a data notebook via Make or n8n or a direct import. Now it's queryable.&lt;/li&gt;
&lt;li&gt;Refresh on the source's cadence. Because the CRA list updates slowly, you don't need a daily job — refresh when a new version is published.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Who uses this
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Vendors selling to nonprofits — software, accounting, events, insurance, consulting: the full prospect universe, filterable.&lt;/li&gt;
&lt;li&gt;Researchers, journalists and academics — sector-wide analysis by category, geography, and time.&lt;/li&gt;
&lt;li&gt;Foundations and grantmakers — mapping the organizations in a field before funding decisions.&lt;/li&gt;
&lt;li&gt;Sector associations and data teams — a clean base table to build reporting on.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The honest part
&lt;/h2&gt;

&lt;p&gt;This is a foundation, not a finished contact list. The CRA registry tells you who the charities are and where — it isn't a bundle of email addresses, and (because the official list refreshes slowly) it's reference data rather than a real-time feed. For prospecting you'll layer enrichment on top; for research it's exactly what you need as-is. Detailed financials from charities' annual T3010 filings are a natural next layer on top of the base registry.&lt;/p&gt;




&lt;p&gt;The dataset used here is the &lt;a href="https://apify.com/truenorthdata/canada-charities" rel="noopener noreferrer"&gt;Canada Charities Scraper&lt;/a&gt; — the CRA List of Charities, cleaned and joined, as JSON/CSV. Questions about filtering it by category or province? Happy to help in the comments.&lt;/p&gt;

</description>
      <category>data</category>
      <category>api</category>
      <category>nonprofit</category>
      <category>opendata</category>
    </item>
    <item>
      <title>How to Find Canadian Government Tenders You Can Actually Win (Daily Feed, 2026)</title>
      <dc:creator>Dave Zavin</dc:creator>
      <pubDate>Sun, 12 Jul 2026 17:24:54 +0000</pubDate>
      <link>https://dev.to/truenorthdata/how-to-find-canadian-government-tenders-you-can-actually-win-daily-feed-2026-28i2</link>
      <guid>https://dev.to/truenorthdata/how-to-find-canadian-government-tenders-you-can-actually-win-daily-feed-2026-28i2</guid>
      <description>&lt;p&gt;Governments in Canada spend hundreds of billions a year, and almost all of it is announced in public before a single dollar is awarded. The problem was never a lack of opportunities — it's that they're scattered across a federal portal, separate provincial systems, and dozens of formats, and the good ones close fast. This is a practical recipe for pulling Canadian government tenders into one searchable, filterable feed so you actually see the contracts you can bid on while there's still time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a tender feed beats "checking the portal"
&lt;/h2&gt;

&lt;p&gt;If your plan is to log into CanadaBuys now and then and scroll, you will miss things. Tenders open and close on their own schedule, relevance is buried under thousands of unrelated notices, and by the time you stumble onto a good one, half the response window is gone. The teams that win government work treat tender discovery as a pipeline: pull everything, filter to what fits, and get alerted early enough to actually prepare a bid.&lt;/p&gt;

&lt;h2&gt;
  
  
  The data source
&lt;/h2&gt;

&lt;p&gt;Canadian public tenders live in several systems: CanadaBuys (federal), SEAO (Québec), and provincial portals like Nova Scotia's. Each has its own format and quirks. Instead of monitoring them separately, you can pull them through one Apify actor that normalizes them into a single dataset: &lt;a href="https://apify.com/truenorthdata/canada-tenders-scraper" rel="noopener noreferrer"&gt;Canada Tenders Scraper&lt;/a&gt;. It covers federal (CanadaBuys), Québec (SEAO), and Nova Scotia, refreshes on a short cycle, and outputs JSON/CSV.&lt;/p&gt;

&lt;h2&gt;
  
  
  The recipe: tenders to a bid pipeline
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Pull the feed. Run the Canada Tenders Scraper for the jurisdictions you can serve (you can bid federally and in specific provinces).&lt;/li&gt;
&lt;li&gt;Filter to your categories. Tenders carry classification and keyword fields. Filter to the categories, keywords, and NAICS/UNSPSC-style codes that match what you actually deliver — IT services, construction, cleaning, staffing, whatever your lane is. Cut the noise to a shortlist you can act on.&lt;/li&gt;
&lt;li&gt;Filter by closing date. Drop anything closing too soon to respond to properly. What's left is your real, workable pipeline.&lt;/li&gt;
&lt;li&gt;Route it to where you work. Send the filtered list to a Google Sheet, Airtable, or CRM via Make or n8n, or schedule the Apify run and export weekly. Each new matching tender becomes a row your team triages.&lt;/li&gt;
&lt;li&gt;Act early. The whole point is time. A tender you see the day it opens gives you room to team up, ask questions, and write a real proposal instead of a rushed one.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Who uses this
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Companies that sell to government — IT, construction, professional services, facilities, staffing: an early, filtered view of relevant contracts.&lt;/li&gt;
&lt;li&gt;Bid-writing and capture consultants — monitor opportunities across multiple clients and jurisdictions from one feed.&lt;/li&gt;
&lt;li&gt;SMBs breaking into govcon — public tenders are the most level playing field there is; the barrier is discovery, and this removes it.&lt;/li&gt;
&lt;li&gt;Market and competitive analysts — tender volume and categories reveal where public spending is heading.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The honest part
&lt;/h2&gt;

&lt;p&gt;Public tender systems are messy — inconsistent categories, uneven data quality, the occasional flaky source. A normalized feed saves you the scraping and the format-wrangling, but you still have to do the human work: judge fit, decide what's worth pursuing, and write a bid that wins. The data gets you to the starting line early. It doesn't run the race for you.&lt;/p&gt;




&lt;p&gt;The dataset used here is the &lt;a href="https://apify.com/truenorthdata/canada-tenders-scraper" rel="noopener noreferrer"&gt;Canada Tenders Scraper&lt;/a&gt; — federal (CanadaBuys), Québec (SEAO), and Nova Scotia tenders in one JSON/CSV feed. Questions about filtering it for a specific category or province? Happy to help in the comments.&lt;/p&gt;

</description>
      <category>government</category>
      <category>api</category>
      <category>sales</category>
      <category>opendata</category>
    </item>
    <item>
      <title>How to Turn Canadian Building Permits Into a Steady Stream of Contractor Leads (2026)</title>
      <dc:creator>Dave Zavin</dc:creator>
      <pubDate>Sun, 12 Jul 2026 02:41:44 +0000</pubDate>
      <link>https://dev.to/truenorthdata/how-to-turn-canadian-building-permits-into-a-steady-stream-of-contractor-leads-2026-4d8e</link>
      <guid>https://dev.to/truenorthdata/how-to-turn-canadian-building-permits-into-a-steady-stream-of-contractor-leads-2026-4d8e</guid>
      <description>&lt;p&gt;Every building permit is a public announcement that someone is about to spend money on construction. A new roof, an addition, a pool, a basement, a full teardown — before any of it happens, a permit gets filed with the city. If you sell to homeowners or property owners who are building, that permit is the earliest, highest-intent signal you can get. This is a practical recipe for pulling fresh Canadian building-permit data and turning it into a lead list for outreach.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why permits are the best trigger for the trades
&lt;/h2&gt;

&lt;p&gt;Most contractor lead-gen is either expensive (pay-per-lead marketplaces taking a cut of every job) or a guessing game (blanket ads to people who aren't building anything). Permit data flips that. A filed permit tells you: this specific address, in this specific city, is doing this specific type of work, right now. You're not hoping someone needs a roofer — you're looking at a list of properties that just pulled a roofing permit.&lt;/p&gt;

&lt;p&gt;The trades this works for: roofing, HVAC, solar, windows/doors, landscaping, pools, foundations, remodelers, and every supplier who sells into those jobs (materials, equipment, financing).&lt;/p&gt;

&lt;h2&gt;
  
  
  The data source
&lt;/h2&gt;

&lt;p&gt;Canadian cities publish building permits as open data, but each city does it differently — different portals, different formats, different fields. Instead of wrangling five municipal APIs yourself, you can pull them through one Apify actor that normalizes them into a single clean dataset: &lt;a href="https://apify.com/truenorthdata/canada-building-permits" rel="noopener noreferrer"&gt;Building Permits Canada&lt;/a&gt;. It currently covers Toronto, Vancouver, Calgary, Edmonton, and Montréal. Output is JSON/CSV.&lt;/p&gt;

&lt;p&gt;Honesty first, because it affects how you use it: this is municipal open data, and freshness varies by city. Some cities publish within days; others lag (Calgary, for example, runs several weeks behind). So treat it as a steady prospecting feed, not a real-time race — filter to recent permits and work the list.&lt;/p&gt;

&lt;h2&gt;
  
  
  The recipe: permits to a working lead list
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Pull the data. Run the Building Permits Canada actor, scoped to the city or cities you serve.&lt;/li&gt;
&lt;li&gt;Filter to your job type. Building permits carry a work type / description field (new construction, alteration, demolition, roofing, plumbing, etc.). Filter to the ones that match what you sell — a roofer wants re-roof and new-build permits, not plumbing alterations.&lt;/li&gt;
&lt;li&gt;Filter to recent + your service area. Keep permits from the last few weeks in the postal codes / neighbourhoods you actually cover. A tight, local list beats a huge one.&lt;/li&gt;
&lt;li&gt;Turn addresses into outreach. You now have property addresses with a known, dated intent. Direct mail still works extremely well for the trades (a postcard to "the owner of [address] who just pulled a permit" converts). For B2B (suppliers selling to the GC or developer named on the permit), enrich the company name in a tool like Clay to find contacts.&lt;/li&gt;
&lt;li&gt;Automate it. Wire the actor into Make or n8n, or a scheduled Apify run, drop new permits into a Google Sheet or CRM each week, and work the fresh rows. Set it once, get a weekly list.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Who buys this kind of data
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Contractors and trades — roofing, HVAC, solar, windows, pools, landscaping, remodeling: permit lists = local, dated, high-intent leads.&lt;/li&gt;
&lt;li&gt;Building-material and equipment suppliers — sell to the builders named on new-construction permits.&lt;/li&gt;
&lt;li&gt;Proptech and real-estate investors — permit activity signals renovations, flips, and development before it's visible on the market.&lt;/li&gt;
&lt;li&gt;Market analysts and lenders — permit volume is a leading indicator of local construction demand.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The mistake to avoid
&lt;/h2&gt;

&lt;p&gt;Don't buy "all permits, all cities" and blast everyone. The power of permit data is precision: right city, right work type, right recency, right service area. A roofer working three suburbs wants this week's re-roof permits in those three suburbs — nothing else. Narrow the list hard, personalize the outreach to the actual job, and the response rate takes care of itself.&lt;/p&gt;




&lt;p&gt;The dataset used here is the &lt;a href="https://apify.com/truenorthdata/canada-building-permits" rel="noopener noreferrer"&gt;Building Permits Canada actor&lt;/a&gt; — Toronto, Vancouver, Calgary, Edmonton, and Montréal permits normalized into one JSON/CSV feed. Questions about filtering it for a specific trade or city? Happy to help in the comments.&lt;/p&gt;

</description>
      <category>sales</category>
      <category>leads</category>
      <category>api</category>
      <category>automation</category>
    </item>
    <item>
      <title>How to Build a Daily List of Newly Incorporated Canadian Companies for Cold Outreach (Clay Recipe, 2026)</title>
      <dc:creator>Dave Zavin</dc:creator>
      <pubDate>Sun, 12 Jul 2026 02:31:11 +0000</pubDate>
      <link>https://dev.to/truenorthdata/how-to-build-a-daily-list-of-newly-incorporated-canadian-companies-for-cold-outreach-clay-recipe-46lg</link>
      <guid>https://dev.to/truenorthdata/how-to-build-a-daily-list-of-newly-incorporated-canadian-companies-for-cold-outreach-clay-recipe-46lg</guid>
      <description>&lt;p&gt;A company that registered yesterday is one of the best outbound triggers there is. It has no accountant yet, no bank relationship locked in, no website, no payroll provider, no insurance — and nobody has pitched it eleven times already. The catch is timing: that window is open for days, not months. This is a practical recipe for pulling a fresh daily list of newly incorporated Canadian companies and turning it into an outreach-ready table in Clay (with Make/n8n alternatives).&lt;/p&gt;

&lt;h2&gt;
  
  
  Why "fresh" beats "big"
&lt;/h2&gt;

&lt;p&gt;Most Canadian business lists you can buy are huge and stale — a million-row database that was assembled once and slowly rots. For prospecting a brand-new company, size is the wrong metric. You don't want every company in Canada; you want the ones that came into existence this week, before your competitors know they exist. Freshness is the whole edge. A 500-row list of companies registered in the last 7 days beats a 1,000,000-row list from last year for this use case, every time.&lt;/p&gt;

&lt;h2&gt;
  
  
  The data source
&lt;/h2&gt;

&lt;p&gt;New federal Canadian companies are published by Corporations Canada. Instead of scraping it yourself, you can pull it through an Apify actor that outputs a clean, filterable dataset: &lt;a href="https://apify.com/truenorthdata/canada-new-incorporations" rel="noopener noreferrer"&gt;Canada New Incorporations&lt;/a&gt;. The important input is a freshness filter — incorporatedWithinDays — so you only get companies registered in the last N days. Output is JSON/CSV, which is what makes the rest of this recipe trivial.&lt;/p&gt;

&lt;p&gt;A note on honesty before you build a business on it: this is federal-level data, and the bulk source lags real time by roughly a week or two. That's fine for most outbound (you're not paging anyone at 3am), but don't promise your prospects or your boss "real-time." Know what you're working with.&lt;/p&gt;

&lt;h2&gt;
  
  
  The recipe: Apify to Clay
&lt;/h2&gt;

&lt;p&gt;Clay is where a lot of outbound teams already assemble and enrich lead lists, so it's the shortest path from raw registrations to a running campaign.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add the source. In a Clay table: Add, Import data, choose the Apify integration, select the Canada New Incorporations actor.&lt;/li&gt;
&lt;li&gt;Set the freshness filter. In the actor input, set incorporatedWithinDays to 7 (or 1 if you want to run it daily and only see yesterday's additions).&lt;/li&gt;
&lt;li&gt;Map the columns. Clay will pull the actor's fields — company name, incorporation date, corporation number, jurisdiction, status. Map those to table columns. (Field names depend on the actor's current output — check the example dataset and map accordingly.)&lt;/li&gt;
&lt;li&gt;Enrich. This is where Clay earns its keep: from the company name, run Clay's enrichments to find the website, LinkedIn company page, and decision-maker email. Now a bare registration record becomes a contactable lead.&lt;/li&gt;
&lt;li&gt;Push to your sequence. Send the enriched rows to your email tool or CRM (Instantly, Smartlead, HubSpot, etc.) with a first line that references the trigger: "Congrats on incorporating [Company] — figured you might not have [your thing] sorted yet."&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Schedule the table to refresh daily and you have a self-updating pipeline of net-new companies.&lt;/p&gt;

&lt;h2&gt;
  
  
  No Clay? Use Make or n8n
&lt;/h2&gt;

&lt;p&gt;Same idea, different plumbing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make or n8n: use the Apify "Run actor and get dataset" module, take the JSON output, drop it into a Google Sheet, Airtable, or straight into your CRM via its API. Add an enrichment step (Clearbit, Apollo, etc.) if you want contacts.&lt;/li&gt;
&lt;li&gt;Plain CSV: run the actor, export CSV, import to your tool of choice. Least automated, zero setup.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Who actually uses this
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Outbound, agencies, B2B SaaS — new companies as a daily trigger list.&lt;/li&gt;
&lt;li&gt;Accountants and bookkeepers — a company needs books from day one.&lt;/li&gt;
&lt;li&gt;Fintech, banks, business services (websites, logos, payroll, insurance) — reach the business before everyone else does.&lt;/li&gt;
&lt;li&gt;Market researchers — track company-formation velocity across the country.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The one thing that makes or breaks it
&lt;/h2&gt;

&lt;p&gt;Speed of follow-up. The value of a new-incorporation lead decays fast — the same reason it's a great trigger is the reason it's a short window. Wire the pipeline so a new registration goes from "appeared in the data" to "first touch sent" in under a day, not next week. Automate the boring parts (pull and enrich) so the only thing you're spending time on is the message.&lt;/p&gt;




&lt;p&gt;The dataset used here is the &lt;a href="https://apify.com/truenorthdata/canada-new-incorporations" rel="noopener noreferrer"&gt;Canada New Incorporations actor&lt;/a&gt; — daily new federal registrations, filterable by freshness, JSON/CSV out. Questions about wiring it into Clay, Make, or n8n? Happy to help in the comments.&lt;/p&gt;

</description>
      <category>sales</category>
      <category>api</category>
      <category>automation</category>
      <category>startup</category>
    </item>
    <item>
      <title>How I Turned Canadian Open Government Data Into a Live Licence-Verification Site + API (Build Log, 2026)</title>
      <dc:creator>Dave Zavin</dc:creator>
      <pubDate>Sat, 11 Jul 2026 17:45:06 +0000</pubDate>
      <link>https://dev.to/truenorthdata/how-i-turned-canadian-open-government-data-into-a-live-licence-verification-site-api-build-log-1a8l</link>
      <guid>https://dev.to/truenorthdata/how-i-turned-canadian-open-government-data-into-a-live-licence-verification-site-api-build-log-1a8l</guid>
      <description>&lt;p&gt;Six weeks ago "verify a contractor licence in Canada" meant opening a different clunky government portal for every province. I wanted one search box. So I built one — a live site backed by 65,177 official contractor and home-builder licences, plus an API for the same data. This is the build log: the stack, the data pipeline, and the one bug that quietly cost me 98% of my Ontario records.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;Canada has no single national registry of licensed contractors. Quebec has the RBQ. Ontario licenses new-home builders through the HCRA. Every province publishes its own data in its own format, on its own portal, with its own quirks. For a homeowner trying to check "is this person actually licensed before I pay them a deposit," that's a dead end. For a developer who wants the data programmatically, it's worse.&lt;/p&gt;

&lt;p&gt;The goal: aggregate the official registries into one place, keep it free to search, and expose the same data as a clean API for people who want to build on top of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Data collection:&lt;/strong&gt; &lt;a href="https://apify.com" rel="noopener noreferrer"&gt;Apify&lt;/a&gt; actors, one per source, that scrape the open-data endpoints and normalize them. Quebec RBQ ships a daily bulk CSV (inside a 10.8 MB zip, ~924k rows that dedupe to ~54k active licences). Ontario HCRA has no bulk file — it's an internal JSON API behind the public registry.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Site:&lt;/strong&gt; Astro 5 in SSR mode.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hosting + data:&lt;/strong&gt; Cloudflare Workers with a D1 database (SQLite at the edge). The free tier gives 100k reads/day, which is plenty for launch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Output:&lt;/strong&gt; server-rendered profile pages with &lt;code&gt;schema.org&lt;/code&gt; &lt;code&gt;HomeAndConstructionBusiness&lt;/code&gt; markup, a chunked sitemap, and a JSON/CSV API.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The whole thing runs on free tiers. The interesting engineering wasn't the framework — it was getting clean, &lt;em&gt;complete&lt;/em&gt; data out of registries that don't want to hand it to you in bulk.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bug that ate my data: "755"
&lt;/h2&gt;

&lt;p&gt;Ontario was supposed to be the strong half of the launch. Instead, for two days, my site showed exactly &lt;strong&gt;755&lt;/strong&gt; Ontario builders. The real HCRA registry has tens of thousands. Something was silently dropping ~98% of the records.&lt;/p&gt;

&lt;p&gt;Here's what was happening.&lt;/p&gt;

&lt;p&gt;The HCRA registry exposes an internal search endpoint that takes a name term: &lt;code&gt;/api/builders?builderName=&amp;lt;term&amp;gt;&lt;/code&gt;. There's no "give me everything" call, so to sweep the full registry you iterate the search across the alphabet (&lt;code&gt;a&lt;/code&gt;, &lt;code&gt;b&lt;/code&gt;, &lt;code&gt;c&lt;/code&gt;, …) and union the results, deduping by account number.&lt;/p&gt;

&lt;p&gt;My first version did two things wrong:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The sweep was &lt;code&gt;a&lt;/code&gt;–&lt;code&gt;z&lt;/code&gt; only.&lt;/strong&gt; Company names starting with a digit — and in Ontario a &lt;em&gt;huge&lt;/em&gt; number of numbered corporations are named things like &lt;code&gt;1000014268 Ontario Inc.&lt;/code&gt; — were never queried.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It enriched every single record with a detail call.&lt;/strong&gt; For each builder found in the list, the scraper fired a second request to &lt;code&gt;/api/buildersummary?id=&amp;lt;account&amp;gt;&lt;/code&gt; to pull full details. On a full sweep that's &lt;em&gt;tens of thousands&lt;/em&gt; of sequential requests.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;On Apify's free plan, a run that balloons into tens of thousands of sequential requests eventually hits the account's usage ceiling and gets &lt;strong&gt;Aborted&lt;/strong&gt; mid-run. When a run aborts, whatever made it into the dataset so far is what you keep. In my case: 755 records. No error on the site. No crash. Just a quietly truncated dataset that &lt;em&gt;looked&lt;/em&gt; fine.&lt;/p&gt;

&lt;p&gt;That's the dangerous class of bug — not the one that throws, but the one that silently returns less.&lt;/p&gt;

&lt;h3&gt;
  
  
  The fix
&lt;/h3&gt;

&lt;p&gt;Three changes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Sweep &lt;code&gt;a&lt;/code&gt;–&lt;code&gt;z&lt;/code&gt; &lt;em&gt;and&lt;/em&gt; &lt;code&gt;0&lt;/code&gt;–&lt;code&gt;9&lt;/code&gt;.&lt;/strong&gt; 36 prefixes instead of 26. This alone recovered the entire universe of numbered corporations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make detail enrichment optional.&lt;/strong&gt; I added an &lt;code&gt;enrich&lt;/code&gt; input flag: &lt;code&gt;on&lt;/code&gt; for small keyword lookups (where the extra detail is cheap and useful), &lt;code&gt;off&lt;/code&gt; for the full sweep. A full sweep is now &lt;strong&gt;36 fast list requests&lt;/strong&gt; — no per-record fan-out, no abort.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Filter deliberately, not accidentally.&lt;/strong&gt; The full registry turned out to be &lt;strong&gt;48,175&lt;/strong&gt; records once I could actually read all of it — but most of that is &lt;code&gt;Expired&lt;/code&gt; (~34k). Instead of dumping everything, I publish an allowlist of &lt;em&gt;meaningful&lt;/em&gt; statuses (Licensed, Licensed with Conditions, Revoked, Refused, Suspended, Cancelled, Unlicensed, and a few notice-of-proposal states). That's the &lt;strong&gt;11,104&lt;/strong&gt; builders now live — the ones a homeowner would actually care about, including the scary ones.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Ontario went from 755 → 11,104. Lesson burned in permanently: &lt;strong&gt;on metered infrastructure, a job that grows unboundedly doesn't fail loudly — it fails by giving you less and calling it success.&lt;/strong&gt; Now the full sweep is a fixed, predictable number of requests, and I sanity-check row counts against the registry's own totals before publishing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The edge-cache red herring
&lt;/h2&gt;

&lt;p&gt;One more debugging story, because it cost me an hour and the lesson is useful.&lt;/p&gt;

&lt;p&gt;After updating D1, the bare URLs (&lt;code&gt;/&lt;/code&gt;, &lt;code&gt;/on&lt;/code&gt;) still showed old numbers, while URLs with a query string (&lt;code&gt;/on?page=40&lt;/code&gt;) showed fresh data. Obvious conclusion: Cloudflare is edge-caching my SSR HTML. I almost ran a full cache purge.&lt;/p&gt;

&lt;p&gt;It wasn't Cloudflare. HTML wasn't being cached at all (caching level Standard doesn't cache HTML by default). The stale numbers were coming from &lt;strong&gt;my own fetch tool's per-URL cache&lt;/strong&gt; — I'd requested the bare URLs &lt;em&gt;before&lt;/em&gt; the data update, and was reading those cached responses back. Real users, in a real browser, saw the correct numbers the entire time.&lt;/p&gt;

&lt;p&gt;Lesson: when you're verifying a deploy, check the &lt;em&gt;actual live site in a real browser&lt;/em&gt; (or bust the cache with &lt;code&gt;?v=&lt;/code&gt;), not through a tool that might be serving you a cached copy. "It's stale for me" is not the same as "it's stale for users."&lt;/p&gt;

&lt;h2&gt;
  
  
  What it looks like now
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;65,177 licences&lt;/strong&gt; live in D1: 54,073 Quebec (RBQ) + 11,104 Ontario (HCRA).&lt;/li&gt;
&lt;li&gt;Search by business name or licence number, per-province listing pages, individual profile pages with structured data.&lt;/li&gt;
&lt;li&gt;A chunked sitemap (static routes + seven 10k chunks) so search engines can actually crawl 65k profile URLs.&lt;/li&gt;
&lt;li&gt;The same data available as &lt;strong&gt;JSON, CSV, or via an MCP endpoint&lt;/strong&gt; for AI agents, through the underlying Apify actors.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can try the site here: &lt;strong&gt;&lt;a href="https://checkcontractors.ca" rel="noopener noreferrer"&gt;CheckContractors.ca&lt;/a&gt;&lt;/strong&gt;. If you want the raw datasets for Quebec and Ontario, the &lt;a href="https://apify.com/truenorthdata/contractor-license-scraper-canada" rel="noopener noreferrer"&gt;contractor-licence actor on Apify&lt;/a&gt; gives you the same records programmatically, updated daily.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaways for anyone building on open gov data
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;"No bulk export" doesn't mean "no data."&lt;/strong&gt; An internal search API you can sweep is a bulk export in disguise — you just have to enumerate the key space (including digits).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Watch for silent truncation on metered platforms.&lt;/strong&gt; Always compare your row count to the source's published total. A number that looks plausible is the easiest bug to miss.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Separate "collect everything" from "publish a subset."&lt;/strong&gt; Pull the full registry once, then filter to what your users need with an explicit allowlist — don't let the collection step do your filtering by crashing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify deploys in a real browser.&lt;/strong&gt; Your tooling has caches too.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Building on open data is mostly a data-quality problem wearing an engineering costume. The framework is the easy part.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If this was useful, the live tool is &lt;a href="https://checkcontractors.ca" rel="noopener noreferrer"&gt;CheckContractors.ca&lt;/a&gt; and the datasets are on &lt;a href="https://apify.com/truenorthdata" rel="noopener noreferrer"&gt;Apify&lt;/a&gt;. Happy to answer questions about the pipeline in the comments.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>webdev</category>
      <category>api</category>
      <category>opendata</category>
    </item>
    <item>
      <title>How to Check if a Quebec Contractor Is Licensed (RBQ, 2026)</title>
      <dc:creator>Dave Zavin</dc:creator>
      <pubDate>Thu, 09 Jul 2026 23:38:26 +0000</pubDate>
      <link>https://dev.to/truenorthdata/-how-to-check-if-a-quebec-contractor-is-licensed-rbq-2026-3f8p</link>
      <guid>https://dev.to/truenorthdata/-how-to-check-if-a-quebec-contractor-is-licensed-rbq-2026-3f8p</guid>
      <description>&lt;p&gt;Planning a renovation, a new build, or any construction work in Quebec? Before you hand over a deposit, spend five minutes confirming your contractor holds a valid RBQ licence. In Quebec that check isn't a nicety — it's the law, and it's what stands between you and a job with no recourse if it goes wrong.&lt;/p&gt;

&lt;p&gt;Here's exactly how to verify a Quebec contractor, what the licence number and class mean, and where to look it up fast.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the RBQ licence matters
&lt;/h2&gt;

&lt;p&gt;Almost anyone who carries out construction work for the public in Quebec — general contractors, specialized trades, even owner-builders in some cases — must hold a licence from the &lt;strong&gt;Régie du bâtiment du Québec (RBQ)&lt;/strong&gt;. The licence confirms the contractor met competency, financial, and probity requirements.&lt;/p&gt;

&lt;p&gt;Hiring someone without a valid RBQ licence is a real risk:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You have far less recourse if the work is defective or unfinished.&lt;/li&gt;
&lt;li&gt;Unlicensed work can void warranties and complicate insurance claims.&lt;/li&gt;
&lt;li&gt;Contractors working without a licence are breaking the law — and can be fined.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So "does this contractor have an RBQ licence?" is really shorthand for "is this job protected?"&lt;/p&gt;

&lt;h2&gt;
  
  
  What to check before you sign
&lt;/h2&gt;

&lt;p&gt;Don't stop at "yes, I'm licensed." Read the actual record:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The licence number&lt;/strong&gt; — an RBQ licence is 10 digits, shown as &lt;code&gt;RBQ licence: XXXX-XXXX-XX&lt;/code&gt;. It's a public document; you're entitled to ask the contractor to show it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Status&lt;/strong&gt; — the licence must be currently valid (in good standing), not expired, suspended, or restricted.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The licence class&lt;/strong&gt; — it has to cover the work you're hiring for.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The name&lt;/strong&gt; — the licensed company name should match the business you're actually contracting with, not a look-alike.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Understanding the licence class
&lt;/h2&gt;

&lt;p&gt;RBQ licences are issued by class, so the class tells you what a contractor is actually allowed to do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;1.x&lt;/strong&gt; — general contractor classes (building construction, civil engineering, etc.).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Higher subcategories&lt;/strong&gt; — specialized trades (for example structural work, foundations, roofing, and other trades).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The practical rule for a homeowner: make sure the class on the licence matches your project. A licence that's valid but for the wrong type of work doesn't protect you for the job you're hiring.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to look it up
&lt;/h2&gt;

&lt;p&gt;The official source is the RBQ's &lt;strong&gt;Licence Holders' Repertory&lt;/strong&gt; on rbq.gouv.qc.ca, where you can search by company name or licence number and confirm status directly with the regulator. Always treat this as the final word.&lt;/p&gt;

&lt;p&gt;If you want a &lt;strong&gt;faster, plain-English lookup&lt;/strong&gt; — or you're comparing contractors across provinces — you can also search the free directory at &lt;strong&gt;&lt;a href="https://checkcontractors.ca/qc" rel="noopener noreferrer"&gt;CheckContractors.ca&lt;/a&gt;&lt;/strong&gt;. It puts official licence data for Quebec (RBQ) and Ontario (HCRA) in one place: search by business name or licence number, see status and city, and jump to the official registry to confirm. No account, no paywall.&lt;/p&gt;

&lt;p&gt;Whichever tool you use, the rule is the same: &lt;strong&gt;confirm the current status on the official RBQ repertory before you sign a contract or pay a deposit.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Red flags
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The contractor can't or won't show a licence number.&lt;/li&gt;
&lt;li&gt;The number doesn't return a valid, in-good-standing record.&lt;/li&gt;
&lt;li&gt;The licence class doesn't cover your type of work.&lt;/li&gt;
&lt;li&gt;They pressure you to pay large sums in cash up front.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Any one of these is a reason to slow down and verify independently.&lt;/p&gt;

&lt;h2&gt;
  
  
  The five-minute checklist
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Get the 10-digit RBQ licence number (&lt;code&gt;XXXX-XXXX-XX&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;[ ] Confirm the licence is &lt;strong&gt;valid and in good standing&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Check the &lt;strong&gt;class&lt;/strong&gt; covers your project&lt;/li&gt;
&lt;li&gt;[ ] Match the licensed name to the company on your contract&lt;/li&gt;
&lt;li&gt;[ ] Confirm on the official RBQ Licence Holders' Repertory before paying&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Five minutes now can save you months of grief later.&lt;/p&gt;

&lt;h2&gt;
  
  
  For developers and agencies
&lt;/h2&gt;

&lt;p&gt;If you're building a proptech tool, a lead-gen product, or an AI agent that needs Canadian contractor-licence data, you don't want to re-scrape registries by hand. The same Quebec (RBQ) and Ontario (HCRA) licence data behind CheckContractors.ca is available as a structured feed — JSON or CSV, or over MCP for AI agents — via the &lt;a href="https://apify.com/truenorthdata/canada-contractor-licenses" rel="noopener noreferrer"&gt;Canada Contractor Licence Scraper on Apify&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This article is for general information and is not affiliated with the RBQ or any government body. Licence data comes from official open sources; always confirm final status on the official registry before hiring or signing a contract.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>datascience</category>
      <category>api</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Check if Your Ontario Home Builder Is Licensed (HCRA, 2026)</title>
      <dc:creator>Dave Zavin</dc:creator>
      <pubDate>Wed, 08 Jul 2026 23:57:24 +0000</pubDate>
      <link>https://dev.to/truenorthdata/how-to-check-if-your-ontario-home-builder-is-licensed-hcra-2026-3840</link>
      <guid>https://dev.to/truenorthdata/how-to-check-if-your-ontario-home-builder-is-licensed-hcra-2026-3840</guid>
      <description>&lt;h1&gt;
  
  
  How to Check if Your Ontario Home Builder Is Licensed (HCRA, 2026)
&lt;/h1&gt;

&lt;p&gt;Buying or building a new home in Ontario is probably the biggest purchase you'll ever make. Before you sign anything, spend five minutes confirming your builder is actually licensed. In Ontario that check is not optional trivia — it's the law, and it's the difference between a protected purchase and a very expensive problem.&lt;/p&gt;

&lt;p&gt;Here's exactly how to verify a builder, what each licence status means, and where to look it up fast.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why licensing matters in Ontario
&lt;/h2&gt;

&lt;p&gt;Since 2021, every new home builder and vendor in Ontario is required by law to be licensed by the &lt;strong&gt;Home Construction Regulatory Authority (HCRA)&lt;/strong&gt;. The HCRA took over builder licensing from Tarion, and the two now do different jobs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HCRA&lt;/strong&gt; licenses builders and vendors, sets competency requirements, and handles complaints, conduct, and enforcement.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tarion&lt;/strong&gt; administers the new-home warranty and helps resolve disputes between buyers and builders.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If a builder isn't HCRA-licensed, they legally cannot build or sell you a new home in Ontario. An unlicensed build can also jeopardize your warranty coverage — which is the protection you'll lean on if something goes wrong after closing.&lt;/p&gt;

&lt;p&gt;So "is this builder licensed?" is really shorthand for "is this purchase protected?"&lt;/p&gt;

&lt;h2&gt;
  
  
  What to check before you sign
&lt;/h2&gt;

&lt;p&gt;When you look a builder up, don't stop at a green checkmark. Read the whole record:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Licence status&lt;/strong&gt; — is it active, and are there conditions attached?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Licence number&lt;/strong&gt; — confirm it matches the company on your contract, not a similarly named one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;History&lt;/strong&gt; — years active, homes built, and any regulatory action taken against them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The exact legal name&lt;/strong&gt; — many Ontario builders operate under numbered companies (e.g. "1000110155 Ontario Inc."). Match the number on the licence to the number on the paperwork.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How to read the licence statuses
&lt;/h2&gt;

&lt;p&gt;The status label tells you most of what you need to know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Licensed&lt;/strong&gt; — active and in good standing. This is what you want to see.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Licensed with Conditions&lt;/strong&gt; — still valid, but the HCRA has attached requirements (for example, further education) that the builder must satisfy within a set time. Worth asking about.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Suspended&lt;/strong&gt; — the licence has been paused. Do not proceed until it's resolved.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Revoked / Refused&lt;/strong&gt; — the HCRA removed or denied the licence. A serious red flag.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Expired&lt;/strong&gt; — no longer current. The builder would need to renew before legally building or selling.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you see anything other than a clean "Licensed," ask the builder to explain it in writing — and confirm independently.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to look it up
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The official source&lt;/strong&gt; is the Ontario Builder Directory run by the HCRA, which carries detailed records on 7,000+ builders and sellers, including status, history, and Tarion warranty data. Always treat this as the final word.&lt;/p&gt;

&lt;p&gt;If you want a &lt;strong&gt;faster, plain-English lookup&lt;/strong&gt; — or you're comparing builders across provinces — you can also search our free directory at &lt;strong&gt;&lt;a href="https://checkcontractors.ca/on" rel="noopener noreferrer"&gt;CheckContractors.ca&lt;/a&gt;&lt;/strong&gt;. It aggregates official licence data for Ontario (HCRA) and Quebec (RBQ) into one place: search by business name or licence number, see status and city, and jump to the official registry to confirm. No account, no paywall.&lt;/p&gt;

&lt;p&gt;Whichever tool you use, the rule is the same: &lt;strong&gt;confirm the current status on the official HCRA registry before you sign a contract.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  For developers and agencies: get the data by API
&lt;/h2&gt;

&lt;p&gt;If you're building a proptech tool, a lead-gen product, a brokerage dashboard, or an AI agent that needs Canadian contractor-licence data, you don't want to scrape registries by hand.&lt;/p&gt;

&lt;p&gt;The same dataset behind CheckContractors.ca is available as a structured feed — Quebec RBQ and Ontario HCRA licences, updated regularly — via the &lt;strong&gt;&lt;a href="https://apify.com/truenorthdata/canada-contractor-licenses" rel="noopener noreferrer"&gt;Canada Contractor Licence Scraper on Apify&lt;/a&gt;&lt;/strong&gt;. Output as JSON or CSV, or plug it straight into an AI agent over MCP. You pay per result, so a quick test costs almost nothing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The five-minute checklist
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Find the builder by exact legal name &lt;strong&gt;and&lt;/strong&gt; licence number&lt;/li&gt;
&lt;li&gt;[ ] Confirm the status reads &lt;strong&gt;Licensed&lt;/strong&gt; (not Suspended, Revoked, Refused, or Expired)&lt;/li&gt;
&lt;li&gt;[ ] Read any conditions and their history&lt;/li&gt;
&lt;li&gt;[ ] Cross-check the licence number against your contract&lt;/li&gt;
&lt;li&gt;[ ] Confirm on the official HCRA Ontario Builder Directory before signing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Five minutes now can save you years of grief later.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This article is for general information and is not affiliated with the HCRA, Tarion, or any government body. Licence data comes from official open sources; always confirm final status on the official registry before hiring or signing a contract.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>api</category>
      <category>webdev</category>
      <category>datascience</category>
    </item>
  </channel>
</rss>
