Security
Almost nothing crosses this line.
Three hosts see a request while you work. Your results and the files you export are not among them.
Your machine
The searches you runthe radius, the categories and the filters — the place you type, and the pin it becomes, are the exception, and they are drawn below
Every result they return
Your proxy credentials
The CSV and the PDF you exportwritten into the folder you picked
The run historySeven days, or the newest 200 runs
Everywhere else
None of the three is ours — there is no scraping queue here, no results store and no proxy — and none of them is sent a result or a file. The only search detail that ever leaves is where you are looking — the place you type, and the pin it becomes — drawn below with the host that receives it.
- No telemetry
- No crash reporting
- No update check
When ordering opens, payment will be handled by Creem as Merchant of Record. There is no LeadCo account, no password and no dashboard here to sign in to.
Google Maps requests
through your proxy
Google Maps — carried by the residential proxy you own and pay for, at its address rather than yours
The place you are searching
unproxied — your real address
nominatim.openstreetmap.org — the text you type into Where, turned into a point; and the pin’s coordinates, turned back into a town name on every scrape you start
Basemap tiles
unproxied
CARTO — the squares of map the application draws, fetched from basemaps.cartocdn.com as you pan
Licence activation
switched off
Nothing — the copy of the application you download carries no activation address, so there is nothing for it to contact
Were activation switched on, it would carry a licence key, a licence id, a non-identifying device id, and the product, version, channel, platform and architecture. Nothing from a run, ever.
The application-side claims describe the shipped 5.0.0 build. What this site does in your own browser was re-checked against the code on 2026-08-24 and in a live browser on 2026-08-17 — the working is in the browser chapter below.
On this page
10 sections
Two systems, and the line between them
The drawing at the top of this page is the whole shape. What follows is why it is a fact about how the product is built rather than a policy that could be changed with an update to this page.
Everything on the left stays on the left, apart from the crossings printed between the columns. That is not a policy we could change with an update to this page: there is no cloud scraping queue to send a search to, no results store to write to, and no route on this server that accepts a business record. A feature that would move any of it would be a feature somebody had to build.
One crossing is not in the drawing, because it happens only when you press the button: Test Proxy makes a single call, through the proxy you configured, to the address-echo service api.ipify.org, so the application can show you which egress address your provider gave you — and the address that service sees is your provider’s, not your machine’s.
What happens on your machine
The design decision behind the whole product: the work is local, and so is everything the work produces.
The searches are yours
LeadCo queries Google Maps from your computer, over an HTTP proxy you supply. This website does not run those searches, has no endpoint that would receive one, and cannot see them.
The proxy is yours
No proxy ships with the application and none is resold. Any rotating residential provider works; DataImpulse is only the one the setup instructions are written for. Credentials are entered in the application’s own settings, written to a file in your user application-data folder with owner-only permissions, and redacted from every log line. We never receive, hold or control them.
The results are yours
Results, filters and run history are stored locally. Exports are CSV and PDF files you create on your own disk, in a folder you choose. Nothing uploads them, and nothing here can read them.
History is short by default
Finished runs are kept for seven days, then the newest 200 of whatever survives that — the age cut is applied first, and a run you have open is never removed. Your exports are ordinary files and are untouched by any of it.
Nothing is cached between runs
Every press of Start makes live requests. That costs you proxy traffic on purpose: a cached listing quietly stops being true, and a dataset that is quietly stale is worse than one that is honestly expensive.
Uninstalling is deleting two things
The application is one; the other is the folder holding your settings, proxy credentials and run history, which lives in your own user application-data directory rather than beside the app — macOS: ~/Library/Application Support/LeadCo; Windows: %APPDATA%\LeadCo. It survives moving or reinstalling the application, which is the point of it, and it also survives deleting the application, which is why it is named here. Delete both and LeadCo is gone from that machine — there is no account left behind, because there was never an account. Settings → Application prints the same path.
The business information you collect — names, addresses, categories and, where a listing publishes them, contact details — is collected by you, on your machine, from publicly visible listings. For that data you are the controller and we are not. What that means in practice is set out in the Privacy Policy and the Acceptable Use Policy.
What actually reaches us
Two payloads, and they are both small enough to describe field by field.
Buying a licence
No order can be placed today, so nothing described here has crossed yet. When ordering opens, your email address will be given to Creem, the Merchant of Record, on its own checkout page; it will take the payment and hold the customer record as the seller, and what it tells this server is a confirmation and a set of references. The route that receives them turns the address into a keyed hash before anything is written.
- Order reference
- Creem’s own identifier for the sale
- Checkout reference
- So the success page can find the purchase
- Subscription reference
- For Monthly and Yearly only, so a renewal extends the right licence
- Plan, amount and currency
- What was bought, and for how much
- Email address
- Passed through fulfilment at the moment of delivery. What is stored is a keyed HMAC-SHA256 of it — what the Privacy Policy calls a one-way salted hash — and never the address
The HMAC key is required on every write path. If it is missing or shorter than 32 characters the application refuses to write the row at all, rather than falling back to a bare digest that could be reversed against any list of addresses.
Activating a licence
This is the only chapter written in the future tense, and it has to be. Version 5.0.0 ships with its licence service switched off: the Licence panel in the application hides itself, there is no screen on which to enter a key, and nothing in the application is locked behind one — so no licence traffic crosses at all today. The setup guide says what that means for a key you have already bought, and the support page says the same. What follows is what the request will carry once activation is switched on, read off the fields the application already implements rather than off an intention.
When the application checks a licence with us, the request will carry the licence key, the licence record’s own id and an identifier for the installation, plus the product name, the version, the release channel, the platform and the processor architecture. That is the complete list. There is no field for a search, a result, an export or a proxy, and the three licence routes accept nothing else.
- Licence key
- Matched against a hash; see the next chapter
- Licence id
- Our own reference for the licence record — a random UUID this server minted at fulfilment, which the application echoes back. An innocuous identifier: it names the licence, not the person or the machine
- Installation id
- The identifier the application derives for itself — dvc_ followed by 32 hexadecimal characters, which identifies nobody. It is hashed again with our key before it is stored
- Product and version
- So an old build can be told it is old
- Platform and architecture
- macOS or Windows, and the chip family
- Not sent
- No IP-derived location, no hardware serial, no MAC address, no user name, no file paths, no telemetry of any kind
A licence check that we cannot answer will be treated as “we do not know” rather than as a refusal: the application keeps working and starts a 14-day offline grace period. Our own error responses are already written so they can never carry a verdict, because a rate-limited request on a busy afternoon must not tell a paying customer that their licence is fake.
What the database holds
Five tables, and a short list of things that are deliberately not in any of them. The schema is written and in place, so what follows describes what the database holds rather than what somebody intends it to hold.
| Record | Stored | Not stored |
|---|---|---|
| Orders | Provider, order / checkout / subscription references, plan, status, amount, currency, a keyed HMAC of the email address, whether it is a test row, and timestamps. | The email address. Any card detail. Any name, address, company or tax identifier — Creem holds those as the seller of record. |
| Licences | A SHA-256 of the normalised key, the first group and the last group for support to read out loud, the plan, the status, the machine allowance, the expiry and the update window. | The licence key itself, beyond a 24-hour disclosure window. After that window there is no plaintext key anywhere in the system. |
| Activations | A keyed HMAC of the installation identifier, when it was first and last seen, whether the seat has been released, the application version and the platform. | The installation identifier itself. Your IP address, user-agent, hostname, hardware serial or any other machine detail — none of it is asked for and none of it is derived. |
| Webhook events | The provider, its event id, the event type, when it was processed, and a hash of the raw body so a replay can be recognised in an investigation. | The event body. The hash is never used to authorise anything; the signature check is what does that. |
| Releases | Version, platform, architecture, storage path, checksum and minimum OS for a published installer. | Anything about a customer. This table holds files, not people. |
The disclosure window, and why it exists
The success page reads your licence key from a URL the payment provider signed. That signature never expires — the same URL replayed next year still verifies — so treating it as permission to disclose a key would make it a permanent bearer token for the one secret a customer paid for.
So the plaintext key lives in one column, for 24 hours from the moment it is minted, and the application clears it on the first read after that instant. A sweep clears the ones nobody reads. After the window the URL discloses nothing, whoever holds it, and the most anyone can learn from the record is the key’s first and last groups. A refund or a chargeback clears it immediately, in the same statement that revokes the licence.
There is no customer account on this site: no login, no password, no session, no password reset. There is nothing to take over, because there is nothing to log into.
How that database is locked
A managed Postgres database is only as private as its access rules. These are the rules, and they are enforced in the database rather than in the application that talks to it.
Row-level security is on, and there is no policy
All five tables have RLS enabled and forced, with no permissive policy defined. With RLS on and no policy present, every role subject to it is denied every row. That absence is the policy.
The public keys are also revoked
Grants are revoked from the anonymous and authenticated roles as well. Either mechanism alone would be enough; both are there because “we thought RLS was on” is a real kind of incident, and a revoked grant fails closed even if somebody later adds a policy by mistake.
The browser has no address for it
Nothing this site sends to your browser carries the database’s address or a key for it, so there is nothing in the page for anyone to point at the database. The only credential that opens it is a server-side key, which bypasses row-level security by design and is read only by code that never runs in a browser. The way to guarantee the browser never talks to this database is to never give it the address.
Test rows and live rows are structurally separate
Every order and every licence carries the mode it was created in, and every lookup filters on it. A test-mode purchase can never be returned to a live-mode query, and a test cohort can be deleted in one statement without touching a real sale.
The three privileged functions are locked too
Fulfilment, seat claiming and status changes are database functions rather than round trips, so each one is a single transaction. All three have their execute permission revoked from the public, anonymous and authenticated roles.
What this website does in your browser
Nothing that outlives the tab. No analytics, no cookies, no browser storage, no trackers — and the claim is checked two ways rather than asserted.
- Analytics provider
- None
- Advertising or retargeting pixels
- None
- Session recording
- None
- Tag manager
- None
- Chat widget
- None
- Cookies set by this site
- None — so there is no consent banner
- Local storage, session storage, IndexedDB
- None written by this site
- Accounts or logins
- None
- Web fonts
- None downloaded. The page is set in the typeface your operating system already has
How that was verified
By reading the code
A search of the whole repository on 2026-08-24 finds zero executable uses of localStorage, sessionStorage, document.cookie or indexedDB — the only matches are this chapter and two comments elsewhere saying the same thing.
By opening a browser
A live check on 2026-08-17, after scrolling the whole homepage and running the demonstration end to end, found all four empty. The only IndexedDB entry present at all belonged to Next.js’s development-mode debug channel, which does not exist in a production build.
The site does keep a short list of interaction events — which page was opened, that a demonstration run was started — in the tab’s own memory, capped at 200 entries, so that a provider could be connected later with one function body and a consent story rather than a hunt through twenty components. Its delivery function’s entire body is a development-only console line. There is no fetch, no beacon, no pixel and no third-party import, and the list is discarded when you close the tab. Pretending to track is worse than not tracking, so the code says which one it is doing.
The two things that do leave your browser
A request to the host
Loading any page means your browser reaches Vercel, which records ordinary request data — IP address, timestamp, page, user-agent — in order to serve and secure the site. That happens beneath the application rather than inside it.
Map tiles
The maps fetch their basemap directly from OpenFreeMap, so that provider sees your IP address and which tiles you looked at. No API key, no account and no cookie is involved, and the request never passes through us. It is named here because “no trackers” is only true if you also say what a page does load.
The demonstration itself downloads static files from this site and filters them inside your browser. The area, the radius and the filters you choose stay in the page and are not sent anywhere — and the dataset it filters carries no telephone numbers at all, only whether a listing has one. The working behind that is on the methodology page.
Payment, and why we never see a card
Ordering opens soon. Creem will be the Merchant of Record: it will take the payment on its own page, handle the tax, and be the seller on your statement. Nothing in this chapter has happened yet, because no order can be placed — what it describes is the route as it is built. This codebase has no card field anywhere in it.
Creem — the far side
- You, and your card — typed on Creem’s own checkout page, never on ours
- The customer record, held by Creem as the seller of record
- The tax, charged and remitted by Creem
- Your statement, which reads CREEM.IO*
What crosses
You → Creem
The payment itself
Card and email, on Creem’s page. The price is decided here and never sent: the call that opens the checkout has no amount parameter.
Creem → this server
One inbound webhook
Signed, and verified before it is parsed. The email address rides in on it and is turned into a keyed HMAC before anything is written.
This server → you
Your licence key
Shown on the success page as the primary delivery, only after the server confirms the payment — never read out of the URL.
This server
- No card field anywhere in the codebase
- A keyed hash of your email address — never the address
- Order, checkout and subscription references, plan, amount and currency
- One licence per paid order, as a database constraint
The price never rides the wire
The checkout call takes a plan identifier and no amount; the provider’s custom-price override is deliberately never sent. A tampered request has no field in which to tamper.
The webhook verifies before it parses
The raw body is read as text, the signature is checked against that exact string, and only then is it turned into an object. Verifying a re-serialised payload is how signature checks quietly stop checking.
Idempotency is a constraint, not an if-statement
One licence per paid order and one processing per delivered event are unique constraints in the database — providers retry precisely when two deliveries are in flight together and “check, then insert” loses.
Money going backwards revokes the licence
A refund or a chargeback sets the order status and revokes the entitlement in one statement. There is no window in which the money has gone and the licence still works.
Your key is shown to you, not only emailed
The success page renders nothing until the server confirms the payment, and never reads a key or a plan out of the query string. What it shows is the delivery, not a copy of one.
The statement descriptor is printed in the drawing above, and it is disclosed again before the button on any checkout that can take a payment, because “I do not recognise this charge” is one of the commonest causes of a chargeback and is entirely preventable by saying in advance what the bank will show.
Every third party involved
The whole list, not a selection. A party appears here in the same change that wires it up and is deleted in the change that removes it, so there is no way to tell a real entry from a planned one — because there are no planned ones.
Creem
independent controller
Armitage Labs OÜ, Rotermanni 14, Tallinn 10111, Estonia
Merchant of Record. Takes the payment, handles tax, holds the customer record and operates the customer portal.
What reaches them: Your email address, your payment details and the record of the sale. Your card details go to Creem and never to us.
Vercel
processor
Hosting for this website, and its request logs.
What reaches them: Your IP address, the time of the request, the page you asked for and your user-agent string — the ordinary record a web server keeps in order to serve and secure a site.
Supabase
processor
The managed Postgres database behind purchases and licensing.
What reaches them: Order, checkout and subscription references, the licence we issued, and a one-way keyed digest (HMAC-SHA-256) of your email address. The address itself is not written to it.
processor
The mailbox behind our support address.
What reaches them: Whatever is in an email you send us and in our reply — your address, your message, and anything you choose to include such as an order reference.
It is used for correspondence only. No marketing list, no newsletter and no contact export exists.
OpenFreeMap
third-party recipient
The basemap under the demonstration map.
What reaches them: Your IP address and which map tiles you looked at. Your browser fetches them itself, so those requests reach the provider directly rather than passing through us.
No API key, no account and no cookie is involved.
openfreemap.org · tiles built from OpenMapTiles and OpenStreetMap data
OpenStreetMap Nominatim
third-party recipient
operated by the OpenStreetMap Foundation
The geocoder inside the desktop application: it answers the Where box, and it names the town under your pin whenever a scrape starts.
What reaches them: The coordinates of your pin, or the place name you typed, and the IP address of the machine you run the application on. Your own computer makes that request — it does not pass through us, and it does not go through your proxy either.
It carries no search terms, no categories, no filters and no results: a coordinate goes out and a town name comes back.
CARTO
third-party recipient
The basemap under the desktop application’s own map.
What reaches them: Your IP address and which map squares the application drew, which is to say roughly where on the map you are working. As with the geocoder, your computer fetches them itself rather than through us or through your proxy.
The tile address in the build carries no key, and there is no account behind it.
CARTO’s privacy notice · tiles built from OpenStreetMap data
ipify
third-party recipient
The address-echo service behind the desktop application’s Test Proxy button: it answers “what address is this request coming from?” so the application can show you the egress address your proxy provider gave you.
What reaches them: One request with no payload, sent through the proxy you configured — so the address ipify sees is your provider’s egress address, not your machine’s own. It also sees the application’s user-agent string. Nothing about the call reaches us.
Called only when you press Test Proxy, and treated as informational by the application: an ipify outage can never fail the proxy check, and no scrape traffic touches it.
What is not on that list, and why
No transactional email provider
A mail sender is not connected in any environment. That is why your licence key is shown to you on screen as the primary delivery, why the disclosure window is 24 hours rather than 30 minutes, and why no email provider is named above. When one is connected it will appear on that list in the same change.
No CDN, font host or script host
Fonts and scripts are served from this site itself, and the typeface is the one your operating system already ships. No third party sees your visit in order to render this page.
Creem is an independent controller rather than our processor, because it is the seller of record and holds the customer record on its own account. That is why a request to erase the email address itself is answered by pointing you at Creem — the full explanation is in the Privacy Policy.
What this page cannot tell you
The limits of this document, stated by the document. A security page that only lists strengths is a marketing page with a padlock on it.
This website cannot verify what the desktop application transmits
No website can. What is above is a description of how the application is built and what our own endpoints will accept — and an endpoint that accepts nothing is a real constraint. But the binary runs on your computer, and the only authority on what it sends is your computer. If it matters to you, watch it: run it behind a proxy you control, or a local network monitor, and look. We would rather you did that than take this page’s word for it.
Nothing here is a certification
There is no SOC 2 report, no ISO 27001, no third-party penetration test and no bug bounty programme. This is a small independent product, and pretending otherwise would be the first dishonest sentence on the site.
No software is unbreakable, and this page does not claim one
What it claims is a small surface: no customer accounts, no passwords, no email addresses in the database, no card data anywhere, no scraped data on our servers at all, and a database a public key cannot read. Less to protect is the only security property that never regresses.
The installers are not signed with a paid certificate
The macOS build is ad-hoc signed and not notarised; the Windows build is unsigned. Both operating systems will warn you on first launch, and the download page explains exactly what each warning says and what it means. Do not extend that habit to software you did not deliberately download.
What you collect is your responsibility
A dataset of local businesses is personal data in many jurisdictions the moment it names a person or reaches one. LeadCo puts the tool in your hands; the obligations that come with using it are yours, and the Acceptable Use Policy is where the line is drawn.
Reporting a problem
If you find something wrong here, we would rather hear it from you than from a customer.
Write to thewebsitelabs@gmail.com. There is no bounty and no disclosure programme to sign up to — just an address that reaches the person who maintains this. We aim to reply within 3 business days.
- Helpful to include
- What you did, what you expected, what happened, and the URL or version
- Please do not send
- Passwords, full card numbers or proxy credentials. We never need them and will never ask for them
- Please do not
- Run automated scans against the live site, or test anything that would affect another customer’s data or availability
- Response target
- We aim to reply within 3 business days.
The binding version of the data questions on this page is the Privacy Policy. Where a figure is quoted rather than a behaviour described, the working is on the methodology page.
Browser-side claims checked by reading the repository on 2026-08-24 and by opening a browser on 2026-08-17. The stored-column list describes the fulfilment schema as it stands, not an intention for it. Questions: thewebsitelabs@gmail.com.