{
  "name": "Florida new LLCs to Google Sheet (NexGen Signal)",
  "nodes": [
    {
      "parameters": {
        "jsCode": "\nconst unknownMessage = (at) => `START OUTCOME UNKNOWN: a request to start a paid run was sent at ${at} but no answer `\n  + `came back, so it is not known whether Apify started it. This workflow will not start another run until you decide. `\n  + `Check Apify Console > Runs for nexgensignal/florida-new-business-filing-records around that time. If a run is there, paste its run ID into `\n  + `resumeRunId in Settings (its results are collected without paying again). If no run started, paste ${at} into `\n  + `startNewAfterUnknown.`;\n// Edit these, then save. Every record delivered is charged (no start fee for this Actor).\nconst settings = {\n  zipPrefixes: ['33401', '33480'],   // West Palm Beach + Palm Beach. Use [] for all of Florida (about 2,000 a day).\n  filingTypes: ['FLAL'],             // FLAL = Florida LLC, DOMP = Florida corporation. [] = all types.\n  maxRecords: 25,                    // most records (and charges) per run\n  maxTotalChargeUsd: 1.50,           // hard spending cap for one run\n};\n\n// ---- Recovery (normally leave empty) -------------------------------------------------------------------------\nconst recovery = {\n  resumeRunId: '',            // collect an existing run's results without starting a new paid run\n  startNewAfterUnknown: '',   // after \"START OUTCOME UNKNOWN\": paste the time it shows, if you checked no run started\n};\nconst memory = $getWorkflowStaticData('global');   // kept between executions (n8n stores it with the workflow)\nmemory.usedResumeIds = memory.usedResumeIds || [];\nif (recovery.resumeRunId && !memory.usedResumeIds.includes(recovery.resumeRunId)) {\n  memory.usedResumeIds.push(recovery.resumeRunId);\n  memory.pendingRun = recovery.resumeRunId; memory.startAttempt = null;\n}\nif (memory.startAttempt && !memory.pendingRun) {\n  if (recovery.startNewAfterUnknown !== memory.startAttempt.at) throw new Error(unknownMessage(memory.startAttempt.at));\n  memory.startAttempt = null;\n}\n\nif (memory.pendingRun) return [{ json: { mode: 'resume', runId: memory.pendingRun, maxRecords: settings.maxRecords } }];\n// The newest State daily file already read in full is remembered so later runs ask only for newer files.\nconst actorInput = { newFormationsOnly: true, filingTypes: settings.filingTypes,\n                     zipPrefixes: settings.zipPrefixes, maxRecords: settings.maxRecords };\nconst today = new Date().toISOString().slice(0, 10);\nif (memory.lastPostedDate) {\n  const next = new Date(memory.lastPostedDate + 'T00:00:00Z'); next.setUTCDate(next.getUTCDate() + 1);\n  const from = next.toISOString().slice(0, 10);\n  if (from > today) return [];                       // already up to date: nothing to run, nothing charged\n  Object.assign(actorInput, { dateFrom: from, dateTo: today });\n} else {\n  actorInput.days = 1;                               // first run: the newest daily file\n}\nreturn [{ json: { mode: 'start', actorInput, maxTotalChargeUsd: settings.maxTotalChargeUsd, maxRecords: settings.maxRecords } }];\n"
      },
      "id": "daca11ba-f74f-49a4-89ae-5bfdb14729ce",
      "name": "Settings (edit me)",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        0,
        220
      ]
    },
    {
      "parameters": {},
      "id": "713f8727-ebad-4278-bda2-85f5eaccfe09",
      "name": "Run now (manual)",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        -220,
        120
      ]
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 11 * * 1-5"
            }
          ]
        }
      },
      "id": "614a9316-27ed-4aa3-b8ec-8d207bdd112c",
      "name": "Weekdays 11:00",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        -220,
        320
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 2
          },
          "conditions": [
            {
              "id": "8b8f3925-5282-45a2-90fc-fd2365f9e94f",
              "leftValue": "={{ $json.mode === 'resume' }}",
              "rightValue": "",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "6e9fecf5-5d24-437b-b8e1-73ba29c20e4f",
      "name": "Resume a saved run?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        220,
        220
      ]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "=https://api.apify.com/v2/actor-runs/{{ $json.runId }}",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {
          "timeout": 120000
        }
      },
      "id": "3d6a80d7-4054-4b01-807b-5c31ad2022dc",
      "name": "Get saved run",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        440,
        80
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "REPLACE_WITH_YOUR_CREDENTIAL",
          "name": "Apify API token"
        }
      },
      "retryOnFail": true,
      "maxTries": 3,
      "waitBetweenTries": 5000
    },
    {
      "parameters": {
        "jsCode": "const memory = $getWorkflowStaticData('global');\nmemory.startAttempt = { at: new Date().toISOString(), input: $input.first().json.actorInput };\nreturn $input.all();"
      },
      "id": "a50aee38-999f-49a7-b586-b8ff9b1b9774",
      "name": "Record start attempt",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        440,
        280
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.apify.com/v2/acts/nexgensignal~florida-new-business-filing-records/runs",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {
          "timeout": 120000
        },
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "waitForFinish",
              "value": "60"
            },
            {
              "name": "maxTotalChargeUsd",
              "value": "={{ $json.maxTotalChargeUsd }}"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify($json.actorInput) }}"
      },
      "id": "61c724ec-89af-497c-81ae-87e9f5e2360c",
      "name": "Start Apify run",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        660,
        280
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "REPLACE_WITH_YOUR_CREDENTIAL",
          "name": "Apify API token"
        }
      },
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "jsCode": "const memory = $getWorkflowStaticData('global');\nmemory.pendingRun = $json.data.id;\nmemory.startAttempt = null;\nreturn $input.all();"
      },
      "id": "bd911903-df40-4336-bb74-fc50a64ded82",
      "name": "Remember run ID",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        880,
        220
      ]
    },
    {
      "parameters": {
        "jsCode": "\nconst unknownMessage = (at) => `START OUTCOME UNKNOWN: a request to start a paid run was sent at ${at} but no answer `\n  + `came back, so it is not known whether Apify started it. This workflow will not start another run until you decide. `\n  + `Check Apify Console > Runs for nexgensignal~florida-new-business-filing-records around that time. If a run is there, paste its run ID into `\n  + `resumeRunId in Settings (its results are collected without paying again). If no run started, paste ${at} into `\n  + `startNewAfterUnknown.`;\n\nconst memory = $getWorkflowStaticData('global');\nconst e = $json.error || {};\nconst status = Number(e.httpCode || e.status || (String(e.message || '').match(/\\b([45]\\d\\d)\\b/) || [])[1] || 0);\nif (status >= 400 && status < 500) {          // Apify answered with a refusal: no run was started\n  if (memory.startAttempt && memory.startAttempt.plan) {\n    let kind = null; try { kind = $('Record start attempt').itemMatching(0).json.kind; } catch (err) {}\n    memory.startAttempt.plan = memory.startAttempt.plan.filter(p => p.kind !== kind);\n    if (!memory.startAttempt.plan.length) memory.startAttempt = null;\n  } else { memory.startAttempt = null; }\n  return [{ json: { message: `Apify refused to start the run (HTTP ${status}): ${e.message || ''} Nothing was started.` } }];\n}\n// (no throw here: n8n keeps changes to saved memory only when the node itself succeeds; the next node stops)\nreturn [{ json: { message: unknownMessage(memory.startAttempt ? memory.startAttempt.at : 'unknown time') } }];\n"
      },
      "id": "12dca44c-65fa-4e6f-aa2e-e3300fe70184",
      "name": "Start outcome unknown",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        880,
        420
      ]
    },
    {
      "parameters": {
        "errorMessage": "={{ $json.message }}"
      },
      "id": "88b5907f-ff7b-4a78-a056-e3da588bece6",
      "name": "Stop: start problem",
      "type": "n8n-nodes-base.stopAndError",
      "typeVersion": 1,
      "position": [
        1100,
        420
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 2
          },
          "conditions": [
            {
              "id": "0d31d8a9-d274-4b8c-a610-a5f2360e844a",
              "leftValue": "={{ $input.all().some(i => ['READY','RUNNING','TIMING-OUT','ABORTING'].includes(i.json.data.status)) }}",
              "rightValue": "",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "068c5703-3baf-4433-89de-dab4a19cf690",
      "name": "Still running?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        1100,
        220
      ]
    },
    {
      "parameters": {
        "amount": 5,
        "unit": "seconds"
      },
      "id": "6510cb69-1140-4ece-bcc7-a4e8e07bb8e6",
      "name": "Wait 5 s",
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1.1,
      "position": [
        1320,
        60
      ],
      "webhookId": "eddbeb24-e7c2-4e47-a674-e33aa5565415"
    },
    {
      "parameters": {
        "method": "GET",
        "url": "=https://api.apify.com/v2/actor-runs/{{ $json.data.id }}",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {
          "timeout": 120000
        },
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "waitForFinish",
              "value": "60"
            }
          ]
        }
      },
      "id": "5f0fa697-64c0-49cb-9ba5-be7dc34d634d",
      "name": "Check run",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1540,
        60
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "REPLACE_WITH_YOUR_CREDENTIAL",
          "name": "Apify API token"
        }
      },
      "retryOnFail": true,
      "maxTries": 3,
      "waitBetweenTries": 5000
    },
    {
      "parameters": {},
      "id": "6fd75817-3663-4c84-91a1-46961ad1b2d8",
      "name": "Run finished",
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [
        1320,
        280
      ]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "https://api.apify.com/v2/acts/nexgensignal~florida-new-business-filing-records/runs",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {
          "timeout": 120000
        },
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "desc",
              "value": "1"
            },
            {
              "name": "limit",
              "value": "25"
            }
          ]
        }
      },
      "id": "10c1e310-751a-4518-8e1e-6a661c4e1a2e",
      "name": "List runs of this Actor",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        330,
        520
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "REPLACE_WITH_YOUR_CREDENTIAL",
          "name": "Apify API token"
        }
      },
      "executeOnce": true,
      "retryOnFail": true,
      "maxTries": 3,
      "waitBetweenTries": 5000
    },
    {
      "parameters": {
        "jsCode": "\n// Runs of this Actor that are still going (READY / RUNNING / TIMING-OUT), newest first.\nconst going = ['READY', 'RUNNING', 'TIMING-OUT'];\nconst items = (($json.data || {}).items || []).filter(r => going.includes(r.status));\nif (!items.length) return [{ json: { none: true } }];\nreturn items.map(r => ({ json: { runId: r.id, kv: r.defaultKeyValueStoreId, startedAt: r.startedAt } }));\n"
      },
      "id": "2feff3dd-107c-4c3b-b053-5f5b4b72e8a9",
      "name": "Runs still going",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        550,
        520
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 2
          },
          "conditions": [
            {
              "id": "d1ea7feb-d1bd-4e28-9040-078af29e6801",
              "leftValue": "={{ !$json.none }}",
              "rightValue": "",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "0383d383-e55b-4f4a-be7b-221acf0710cb",
      "name": "Another run going?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        770,
        520
      ]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "=https://api.apify.com/v2/key-value-stores/{{ $json.kv }}/records/INPUT",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {
          "timeout": 120000
        }
      },
      "id": "619cd9f2-6a97-48a1-b8d1-1d6e448cf7bf",
      "name": "Read input of running runs",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        990,
        460
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "REPLACE_WITH_YOUR_CREDENTIAL",
          "name": "Apify API token"
        }
      },
      "alwaysOutputData": true,
      "onError": "continueRegularOutput",
      "retryOnFail": true,
      "maxTries": 3,
      "waitBetweenTries": 5000
    },
    {
      "parameters": {
        "jsCode": "\n// The run this execution would start: the 'start' items planned in 'Settings (edit me)'.\nconst planned = $('Settings (edit me)').all().map(it => ({ json: it.json })).filter(x => x.json.mode === 'start');\nlet running = [];\ntry { running = $('Read input of running runs').all().map(i => i.json || {}); } catch (e) { running = []; }\nlet ids = [];\ntry { ids = $('Runs still going').all().map(i => i.json); } catch (e) { ids = []; }\n// Same settings = every setting this execution would send has the same value in the running run's input\n// (Apify may add the Actor's defaults to a run's stored input, so extra fields there do not matter).\nconst same = (mine, theirs) => Object.keys(mine).every(k => JSON.stringify(mine[k]) === JSON.stringify(theirs[k]));\nfor (const p of planned) {\n  const i = running.findIndex(inp => inp && typeof inp === 'object' && same(p.json.actorInput || {}, inp));\n  if (i >= 0) {\n    const r = ids[i] || {};\n    return [{ json: { __overlap: `ALREADY RUNNING: run ${r.runId || ''} of this Actor, started ${r.startedAt || ''} with `\n      + `the same settings, is still going (most likely started by an earlier execution of this workflow that is `\n      + `still waiting for it). This execution stopped without starting or paying for anything; the earlier `\n      + `execution writes those results. If that earlier execution was stopped, its run is not collected `\n      + `automatically: paste its run ID into resumeRunId in Settings.` } }];\n  }\n}\nreturn planned;\n"
      },
      "id": "fb3c562c-d310-4ed7-8119-283de1bc169f",
      "name": "Same settings already running?",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1210,
        520
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 2
          },
          "conditions": [
            {
              "id": "b14fdaf5-281b-4164-855e-187c8c78a61f",
              "leftValue": "={{ !!$json.__overlap }}",
              "rightValue": "",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "62bfa4c3-61ea-4b52-905b-1249812fbc51",
      "name": "Overlap?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        1430,
        520
      ]
    },
    {
      "parameters": {
        "errorMessage": "={{ $json.__overlap }}"
      },
      "id": "1ddb70d5-c65c-49aa-b8b2-f9945164f0c2",
      "name": "Stop: already running",
      "type": "n8n-nodes-base.stopAndError",
      "typeVersion": 1,
      "position": [
        1650,
        460
      ]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "=https://api.apify.com/v2/key-value-stores/{{ $json.data.defaultKeyValueStoreId }}/records/RUN_RECEIPT",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {
          "timeout": 120000
        }
      },
      "id": "b6c1b381-b6fa-4657-b7c2-c387d8cbcad3",
      "name": "Get run receipt",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1540,
        280
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "REPLACE_WITH_YOUR_CREDENTIAL",
          "name": "Apify API token"
        }
      },
      "alwaysOutputData": true,
      "onError": "continueRegularOutput",
      "retryOnFail": true,
      "maxTries": 3,
      "waitBetweenTries": 5000
    },
    {
      "parameters": {
        "method": "GET",
        "url": "=https://api.apify.com/v2/datasets/{{ $('Run finished').item.json.data.defaultDatasetId }}/items",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {
          "timeout": 120000
        },
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "clean",
              "value": "true"
            },
            {
              "name": "format",
              "value": "json"
            }
          ]
        }
      },
      "id": "a39ebabf-8130-4819-9303-63bb0c5ea96c",
      "name": "Get records",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1760,
        280
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "REPLACE_WITH_YOUR_CREDENTIAL",
          "name": "Apify API token"
        }
      },
      "alwaysOutputData": true,
      "retryOnFail": true,
      "maxTries": 3,
      "waitBetweenTries": 5000
    },
    {
      "parameters": {
        "jsCode": "\nfunction outcome(run, n) {\n  const msg = run.statusMessage || '';\n  if (run.status !== 'SUCCEEDED') return 'failed';\n  if (msg.startsWith('SOURCE UNAVAILABLE')) return 'source_unavailable';\n  if (/^(PARTIAL|CAPPED|INCOMPLETE SEARCH)/.test(msg) || msg.includes('PARTIAL SEARCH')\n      || msg.startsWith('The sources that answered')) return 'partial';\n  return n === 0 ? 'no_match' : 'complete';\n}\n\nconst run = $('Run finished').first().json.data;\nconst receipt = $('Get run receipt').first().json || {};\nconst n = $('Get records').all().filter(i => i.json && i.json.document_number).length;\nlet result = outcome(run, n);\nif (result === 'no_match' && !Object.keys(receipt.files || {}).length) result = 'no_new_daily_file_yet';\nconst resumed = $('Settings (edit me)').first().json.mode === 'resume';\nreturn [{ json: { run_at: new Date().toISOString(), run_id: run.id, outcome: result, records_received: n,\n                  charged_records: receipt.charged ?? '', status_message: run.statusMessage || '',\n                  note: resumed ? 'results of a run started earlier (no new charge)' : '' } }];\n"
      },
      "id": "8c430d04-1040-461e-aaeb-24115c304af2",
      "name": "Run log entry",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1980,
        280
      ]
    },
    {
      "parameters": {
        "jsCode": "\nconst now = new Date().toISOString();\nconst cols = [\"document_number\", \"entity_name\", \"filing_type_label\", \"status\", \"file_date\", \"posted_date\", \"state_or_country_of_formation\", \"principal_address_1\", \"principal_address_2\", \"principal_city\", \"principal_state\", \"principal_zip\", \"mailing_city\", \"mailing_state\", \"registered_agent_company_name\", \"fei_number\", \"officers_listed\", \"source_file\"];\nreturn $('Get records').all().map(i => i.json).filter(r => r && r.document_number).map(r => {\n  const row = {}; for (const c of cols) row[c] = r[c] === null || r[c] === undefined ? '' : String(r[c]);\n  row.last_seen = now; return { json: row }; });\n"
      },
      "id": "f21d9b32-8e59-4a23-ae91-b104ca0973c6",
      "name": "Map records to sheet rows",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2420,
        280
      ],
      "alwaysOutputData": true
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 2
          },
          "conditions": [
            {
              "id": "f5f3c587-d4db-4077-8521-c47094d9acd7",
              "leftValue": "={{ !!$json.document_number }}",
              "rightValue": "",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "8ee4d9ce-1d4a-43ed-8395-3709cf8c6633",
      "name": "Any rows?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        2640,
        280
      ]
    },
    {
      "parameters": {
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": "PASTE_YOUR_GOOGLE_SHEET_URL_HERE"
        },
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Run log"
        },
        "operation": "append",
        "columns": {
          "mappingMode": "autoMapInputData",
          "value": {},
          "matchingColumns": [],
          "schema": [
            {
              "id": "run_at",
              "displayName": "run_at",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "run_id",
              "displayName": "run_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "outcome",
              "displayName": "outcome",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "records_received",
              "displayName": "records_received",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "charged_records",
              "displayName": "charged_records",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "status_message",
              "displayName": "status_message",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "note",
              "displayName": "note",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            }
          ]
        },
        "options": {
          "cellFormat": "RAW"
        }
      },
      "id": "d4178301-ee66-4d9b-b2c6-3f473fb8922e",
      "name": "Run log (sheet)",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.7,
      "position": [
        2200,
        280
      ],
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "REPLACE_WITH_YOUR_CREDENTIAL",
          "name": "Google Sheets account"
        }
      }
    },
    {
      "parameters": {
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": "PASTE_YOUR_GOOGLE_SHEET_URL_HERE"
        },
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "New Florida LLCs"
        },
        "operation": "appendOrUpdate",
        "columns": {
          "mappingMode": "autoMapInputData",
          "value": {},
          "matchingColumns": [
            "document_number"
          ],
          "schema": [
            {
              "id": "document_number",
              "displayName": "document_number",
              "required": false,
              "defaultMatch": true,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "entity_name",
              "displayName": "entity_name",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "filing_type_label",
              "displayName": "filing_type_label",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "displayName": "status",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "file_date",
              "displayName": "file_date",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "posted_date",
              "displayName": "posted_date",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "state_or_country_of_formation",
              "displayName": "state_or_country_of_formation",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "principal_address_1",
              "displayName": "principal_address_1",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "principal_address_2",
              "displayName": "principal_address_2",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "principal_city",
              "displayName": "principal_city",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "principal_state",
              "displayName": "principal_state",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "principal_zip",
              "displayName": "principal_zip",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "mailing_city",
              "displayName": "mailing_city",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "mailing_state",
              "displayName": "mailing_state",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "registered_agent_company_name",
              "displayName": "registered_agent_company_name",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "fei_number",
              "displayName": "fei_number",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "officers_listed",
              "displayName": "officers_listed",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "source_file",
              "displayName": "source_file",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "last_seen",
              "displayName": "last_seen",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            }
          ]
        },
        "options": {
          "cellFormat": "RAW"
        }
      },
      "id": "c9a05a8a-4d40-49d2-933f-d4a6c31407eb",
      "name": "New Florida LLCs (sheet)",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.7,
      "position": [
        2860,
        160
      ],
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "REPLACE_WITH_YOUR_CREDENTIAL",
          "name": "Google Sheets account"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "\n// Runs only after the rows were written (or there were none): forget the run and move the date mark on.\nconst memory = $getWorkflowStaticData('global');\nconst log = $('Run log entry').first().json;\nconst receipt = $('Get run receipt').first().json || {};\nconst limit = (receipt.filters && receipt.filters.maxRecords) || $('Settings (edit me)').first().json.maxRecords;\nif (['complete', 'no_match', 'no_new_daily_file_yet'].includes(log.outcome) && log.records_received < limit) {\n  const days = Object.keys(receipt.files || {}).filter(f => /^\\d{8}/.test(f))\n    .map(f => `${f.slice(0, 4)}-${f.slice(4, 6)}-${f.slice(6, 8)}`).sort();\n  if (days.length && (!memory.lastPostedDate || days[days.length - 1] > memory.lastPostedDate))\n    memory.lastPostedDate = days[days.length - 1];\n}   // a run that stopped at its maximum or cap is read again next time (rows updated, but charged again)\nmemory.pendingRun = null;\nreturn [{ json: log }];\n"
      },
      "id": "8e5b51d9-752a-4832-9a95-9bc119f4d8ec",
      "name": "Save progress",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        3080,
        280
      ],
      "executeOnce": true
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 2
          },
          "conditions": [
            {
              "id": "d0a6445c-c8de-42b1-bbc7-b2bb13624670",
              "leftValue": "={{ ['failed','source_unavailable'].includes($json.outcome) }}",
              "rightValue": "",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "67e39ded-788a-4e9d-9849-7908a164a573",
      "name": "Run failed?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        3300,
        280
      ]
    },
    {
      "parameters": {
        "errorMessage": "={{ 'Apify run ' + $json.run_id + ' ended as ' + $json.outcome + ': ' + $json.status_message }}"
      },
      "id": "9acb1d92-3c58-4400-801f-f06df585e129",
      "name": "Stop: run failed",
      "type": "n8n-nodes-base.stopAndError",
      "typeVersion": 1,
      "position": [
        3520,
        280
      ]
    },
    {
      "parameters": {
        "content": "## New Florida LLCs \u2192 Google Sheet\nOfficial Florida Division of Corporations daily filings via the Apify Actor **nexgensignal/florida-new-business-filing-records**.\n\n1. Create an **Apify API token** credential: *Header Auth*, name `Authorization`, value `Bearer <your token>`; select it in the seven HTTP Request nodes.\n2. Make a Google Sheet with tabs **New Florida LLCs** and **Run log**; paste the header rows from the tutorial.\n3. Paste the sheet URL into both sheet nodes and pick your Google credential.\n4. Edit **Settings (edit me)**, run once, then activate the schedule.\n\nRows are matched on `document_number`, so a company is never listed twice \u2014 but a company delivered again is charged again. Progress is saved only after the rows are written; a run whose rows were not written is reused next time instead of paying for a new one. Cost: $0.05 per record on the Free plan ($0.045 Bronze, $0.04 Silver, $0.0335 Gold+), no start fee.",
        "height": 380,
        "width": 600,
        "color": 4
      },
      "id": "674d4199-86d4-45ae-bd48-11745d7a7618",
      "name": "Note c8dca4",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -260,
        -300
      ]
    }
  ],
  "connections": {
    "Run now (manual)": {
      "main": [
        [
          {
            "node": "Settings (edit me)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Weekdays 11:00": {
      "main": [
        [
          {
            "node": "Settings (edit me)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Start outcome unknown": {
      "main": [
        [
          {
            "node": "Stop: start problem",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Settings (edit me)": {
      "main": [
        [
          {
            "node": "Resume a saved run?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Resume a saved run?": {
      "main": [
        [
          {
            "node": "Get saved run",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "List runs of this Actor",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "List runs of this Actor": {
      "main": [
        [
          {
            "node": "Runs still going",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Runs still going": {
      "main": [
        [
          {
            "node": "Another run going?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Another run going?": {
      "main": [
        [
          {
            "node": "Read input of running runs",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Same settings already running?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read input of running runs": {
      "main": [
        [
          {
            "node": "Same settings already running?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Same settings already running?": {
      "main": [
        [
          {
            "node": "Overlap?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Overlap?": {
      "main": [
        [
          {
            "node": "Stop: already running",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Record start attempt",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Record start attempt": {
      "main": [
        [
          {
            "node": "Start Apify run",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Start Apify run": {
      "main": [
        [
          {
            "node": "Remember run ID",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Start outcome unknown",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get saved run": {
      "main": [
        [
          {
            "node": "Still running?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Remember run ID": {
      "main": [
        [
          {
            "node": "Still running?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Still running?": {
      "main": [
        [
          {
            "node": "Wait 5 s",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Run finished",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait 5 s": {
      "main": [
        [
          {
            "node": "Check run",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check run": {
      "main": [
        [
          {
            "node": "Still running?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Run finished": {
      "main": [
        [
          {
            "node": "Get run receipt",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get run receipt": {
      "main": [
        [
          {
            "node": "Get records",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get records": {
      "main": [
        [
          {
            "node": "Run log entry",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Run log entry": {
      "main": [
        [
          {
            "node": "Run log (sheet)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Run log (sheet)": {
      "main": [
        [
          {
            "node": "Map records to sheet rows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Map records to sheet rows": {
      "main": [
        [
          {
            "node": "Any rows?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Any rows?": {
      "main": [
        [
          {
            "node": "New Florida LLCs (sheet)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Save progress",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "New Florida LLCs (sheet)": {
      "main": [
        [
          {
            "node": "Save progress",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save progress": {
      "main": [
        [
          {
            "node": "Run failed?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Run failed?": {
      "main": [
        [
          {
            "node": "Stop: run failed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1",
    "timezone": "America/New_York"
  },
  "pinData": {},
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "tags": []
}