- What FunnelLedger does — and does not do
- Two ingestion paths
- What FunnelLedger reads
- What FunnelLedger never reads or retains
- The PII firewall (three layers)
- AI: where it is used, and where it is not
- HubSpot writes
- Retention & deletion
- Subprocessors
- Per-scan privacy manifest
- Legal posture
- Contact us
What FunnelLedger does — and does not do
In one screen: FunnelLedger reads the structural evidence behind your HubSpot lifecycle stages and returns a read-only report. It is not an auto-cleanup tool, and it does not change your CRM on its own.
What it does
- Reconstructs lifecycle-stage history and judges whether each advanced-stage label is supported by the evidence in your portal.
- Reads structural evidence only: lifecycle history, timestamps, source / conversion / form labels, categorized activity, deal and ticket timing and counts, selected business-context fields, property schema metadata, and HubSpot Contact IDs.
- Produces a report and, when you ask, a CSV export.
- Records a per-scan privacy manifest of exactly what was used and what was blocked.
What it does not do
- It does not read names, emails, phone numbers, notes, message bodies, call transcripts, or free-text customer content.
- It does not write your lifecycle stages.
- It does not write contact, company, or deal properties.
- It does not auto-clean, remediate, or change records on its own.
- It does not let AI decide lifecycle verdicts — verdicts are deterministic.
The only write FunnelLedger can make to HubSpot is creating a static list from a cohort you explicitly approve (an approved Segment Action), with the required scopes. Everything else is read-only. Each of these statements is explained in detail below.
Two ingestion paths
FunnelLedger has two ways to read your data. The same privacy contract holds for both; the difference is how the data reaches us.
You upload HubSpot exports
No HubSpot connection is required. You export property-history CSVs from HubSpot and upload them. No names, emails, or phone numbers are needed for upload. PII-like values in the files are ignored or suppressed at ingestion and never rendered in the report. You control exactly which columns ever leave your portal.
You connect HubSpot via OAuth
FunnelLedger reads approved HubSpot data through OAuth. Reads are restricted to an enumerated allowlist of evidence properties; directly-identifying fields are never on the request list. The connection is read-only except for the Segment Actions you explicitly approve (see section 7).
The privacy difference. In upload mode, identifying data never has to leave HubSpot at all — the filtering happens at ingestion, and you choose the files. In connected mode, FunnelLedger reads from HubSpot directly but only requests the allowlisted evidence properties, and the same firewall sanitizes and minimizes before anything is stored. Neither path reads or retains raw customer PII.
What FunnelLedger reads
These are the structural and evidence categories the audit uses. They describe the shape of lifecycle movement, not who the contacts are.
- HubSpot Contact ID — the only contact identifier we use, for stable joins inside our process and for handing off approved cohorts to HubSpot static lists.
- Lifecycle-stage history — current value and the sequence of stage transitions. The core audit subject.
- Timestamps — created date and stage entry / exit times, used to judge staleness and sequence.
- Source & conversion / form labels — the categorized source and conversion-event labels around a transition (for example
form_submission), not the free-text answers inside a form. - Activity date / property labels — categorized activity signals (email opened, page seen, meeting booked) as a class plus a timestamp or count — never the subject line, body, or page query string.
- Deal & ticket timing and counts — association counts and timing as support evidence, where available.
- Company / context fields — structured business-context values (country, region, industry, employee band, ICP tier, persona enum, segment enum) when selected by the Evidence Property Catalog for cohort cuts.
- Workflow / source context — attribution for how a stage changed (workflow, import, integration, user), where HubSpot exposes it.
- Property schema metadata — property definitions used to classify which fields are safe evidence and which are identifying.
- Approved static-list cohort IDs — only for a Segment Action you explicitly approve.
Custom properties are not guessed. Known HubSpot-defined fields are interpreted by a deterministic property-semantics registry; ambiguous HubSpot-defined fields may be checked against official HubSpot documentation only where the registry allows it; custom fields stay deterministic, ambiguous, or operator-confirmed. See section 6.
What FunnelLedger never reads or retains
- Names —
firstname,lastname,fullname,name - Emails —
email,work_email, email bodies, email subject lines - Phone numbers —
phone,mobilephone,fax, messaging numbers - Addresses —
address,street,city,state,zip,postalcode - Notes, call transcripts, call notes, meeting notes
- SMS / chat bodies, form free-text answers, attachment contents
- Raw page URLs with query strings or hash fragments (sanitized to a safe category and path)
- HubSpot-flagged sensitive-data properties
- Unknown custom free-text properties, by default
This is not a list of values we receive and then decline to display. PII-like values are ignored or suppressed and never rendered. The firewall prevents them from being fetched or ingested in the first place — they never enter our process, never reach our database, and never reach our AI provider.
The PII firewall (three layers)
The contract above is enforced by a firewall applied in three layers, in series:
- Read-time allowlist (connected) · upload-time filter (upload). In connected mode, the scan only requests enumerated evidence properties from HubSpot's API; directly-identifying fields are never on the request list. In upload mode, PII-like columns in the uploaded files are ignored or suppressed at ingestion and never rendered.
- Persistence-time minimization. The tables that back the audit (lifecycle history, support strength, activity observations) store HubSpot Contact IDs, timestamps, and categorized signal classes — not raw property values and not free-text content. A deep PII strip runs before anything is persisted.
- AI-prompt firewall and value-level PII scan. Every prompt sent to our AI provider passes through a runtime gate that scans for email shape, phone shape, and known HubSpot PII keys. If the gate trips, the prompt is rejected and the block falls back to deterministic output. The AI never receives contact-level data.
The gate is enforced by code, not policy. A future contributor who tries to add a prompt containing a contact's email will see the gate refuse the call — both at runtime and in the test suite.
Verifiable. The firewall is implemented in backend/decay/pii-firewall.js and exercised by hostile-fixture tests in pii-firewall.smoke-test.js. The categorical claims on this page reflect what those tests assert. The full firewall hardening sequence (broader read-allowlist wiring, export-boundary enforcement, AI-boundary tests, and an optional purge-after-report retention mode) is partially shipped and partially planned — see section 8.
AI: where it is used, and where it is not
FunnelLedger's verdicts are produced by a deterministic verdict engine — threshold-based logic over your portal's evidence. AI does not decide whether a lifecycle stage is supported, stale, missing evidence, or conflicting.
- AI does not decide lifecycle verdicts, metrics, or recommendations.
- AI does not receive contact-level data, Contact IDs, names, emails, phones, raw property values, or free-text content.
- AI may paraphrase wording — the intro paragraph and the industry-context summary — grounded only in aggregate, deterministic scan outputs (verdict counts, top findings, top actions, and the industry context you confirmed). It does not change verdicts, findings, or recommendations, and AI-assisted blocks are labelled.
- Property-semantics lookup is conservative: only eligible HubSpot-defined fields may be checked, and only against official HubSpot documentation. Custom properties are never guessed by AI. If a lookup times out, lacks an official HubSpot citation, or sees anything unsafe, FunnelLedger falls back to the deterministic registry result unchanged.
Every AI prompt passes through the PII firewall described in section 5 before it leaves our process.
HubSpot writes
FunnelLedger is read-only on HubSpot by default. To be exact:
- No lifecycle-stage writes. FunnelLedger never writes
lifecyclestage. - No contact, company, or deal property writes.
- No automatic cleanup, remediation, or record changes.
The single exception is an approved Segment Action: creating a HubSpot static list from a cohort you explicitly approve. It requires per-action consent and the verified crm.lists.write and crm.lists.read scopes. Every list creation is audit-logged with the list ID, name, and contact count. You can revoke list-creation consent at any time; lists already in your HubSpot remain under your control.
This is the only write surface. If you never approve a Segment Action, FunnelLedger never writes anything to your HubSpot portal.
Retention & deletion
FunnelLedger retains only what is needed to re-render your audit and to honor the audit log: HubSpot Contact IDs, lifecycle-stage transitions, deal and ticket counts, categorized activity signals, and the deterministic verdicts computed for each scan. We do not retain names, emails, phones, addresses, notes, email bodies, or free-text customer content. An optional purge-after-report retention mode is planned but is not the current default.
Tenant delete · 24-hour SLA
You can delete your tenant from FunnelLedger at any time. The deletion is a single transaction that cascades across every table holding tenant-scoped rows. Operationally it completes in milliseconds; the 24-hour SLA is the legal-side ceiling, not the operational target.
When you trigger a tenant delete, FunnelLedger:
- Writes a single forensic audit row recording the deletion request, the portal identifier, the row counts being cleared, and the timestamp. It carries no tenant linkage, so it survives the cascade as a regulator-grade receipt that the deletion occurred.
- Clears every row in every dependent table within the same transaction — no partial state.
- Runs a residual-rows self-check afterward; the deletion is only acknowledged when every table reports zero rows for the deleted tenant.
- Returns a structured response carrying the row-count summary, the residual check, and a
privacy_boundary: funnelledger_local_only_no_hubspot_writesmarker.
What the deletion does not touch. Your HubSpot portal's contacts, lifecycle stages, deals, tickets, workflows, and OAuth tokens. The tenant delete removes only FunnelLedger-side data; your CRM is unchanged. To remove FunnelLedger's access entirely, revoke the integration from inside HubSpot — that is a separate action you control.
How to request a tenant delete
Email support@funnelledger.com with the HubSpot portal ID and a confirmation. We will reply with the deletion receipt (the forensic audit row contents) within one business day.
Subprocessors
The subprocessor that receives any portion of scan-derived data is listed below.
| Subprocessor | Purpose | Data flow | Region |
|---|---|---|---|
| Anthropic DPA · Privacy Policy |
AI provider. Paraphrases the intro paragraph and industry-context summary from deterministic scan aggregates. | Receives only aggregate scan outputs (verdict counts, top findings, top actions, industry context). Never receives Contact IDs, names, emails, phones, or any free-text customer content. Every prompt passes through the PII firewall before transmission. | United States |
TODO — needs confirmation before commercial launch. FunnelLedger also relies on an infrastructure hosting provider and a payment processor for checkout. These are not yet documented as privacy subprocessors with confirmed data-handling terms in our source materials, so they are intentionally not described here. Privacy counsel should confirm the complete subprocessor list — including hosting and payment — and the data each one touches, before this page is published. We will not claim "no other subprocessors" until that review is complete.
If we add or change a subprocessor, we will update this page and notify pilot customers by email at least 14 days before the change takes effect.
Per-scan privacy manifest
Every scan emits a structured privacy manifest recording what it saw and did not see. The manifest is persisted alongside the scan and rendered in the report itself, so you or any reviewer can confirm the contract was honored on that specific scan — not just as a marketing claim.
An example manifest:
"identity_blind": true,
"pii_minimized": true,
"contact_identifier_policy": "hubspot_contact_id_only",
"llm_contact_level_data_sent": false,
"hubspot_property_writes": false,
"lifecyclestage_writes": false,
"blocked_property_count": 42, // custom + canonical fields refused
"blocked_categories": [
"identity", "contactability", "free_text", "sensitive_data"
],
"allowed_categories": [
"lifecycle_history", "timestamps",
"categorized_touchpoints", "business_context"
]
}
The manifest is the most concrete artifact we can give a security reviewer or DPO. It is generated per scan, persisted, and rendered inside the report.
Legal posture
This section is a technical explanation of the legal framework we believe our processing fits under. It is not legal advice, and the exact wording is pending review by privacy counsel before commercial launch.
GDPR / UK GDPR
The data FunnelLedger processes consists of HubSpot Contact IDs, lifecycle-stage history, timestamps, association counts, and categorized signal classes. We do not receive, and cannot reconstruct, directly-identifying customer information. We do not claim this data is fully anonymous: HubSpot Contact IDs are pseudonymous, and the data remains personal data in your hands as the HubSpot account controller, where you can map IDs back to people.
Whether such data is "personal data" turns on whether the recipient has reasonable means to re-identify the individuals. The CJEU addressed this contextual test in its September 2025 judgment in EDPS v SRB: data may be personal data in one party's hands and not in another's, depending on the means available to each. FunnelLedger receives data pseudonymized at source by the decision not to send directly-identifying fields, and we lack the means to reverse it — no parallel contact database, no cross-customer identity linkage. We believe the architectural separation between identity (which stays in HubSpot) and lifecycle evidence (which we audit) is real and that the legal frame supports the position.
CCPA / CPRA
For California consumers, data meeting the statutory definition of "deidentified" sits outside the personal-information scope, provided the business takes reasonable measures to prevent association, publicly commits to maintain the data in deidentified form and not re-identify it, and contractually requires downstream recipients to comply. This is FunnelLedger's public commitment:
- We do not attempt to re-identify the consumers whose lifecycle-stage history we process, and we do not link HubSpot Contact IDs to any other dataset that would associate the data with a particular consumer or household.
- We maintain the data in its deidentified form. Our architecture forecloses receiving the directly-identifying fields that would make it identifiable in our hands.
- We contractually require downstream recipients to comply. Our AI subprocessor (Anthropic, see section 9) is contracted under terms prohibiting re-identification and use for training. We send only aggregate, deterministic, non-contact-level data.
- We will not derive identifying information from the deidentified data, and we will not contact consumers based on these records.
Counsel review pending. The GDPR / EDPS v SRB and CCPA framings above are the positions we believe are defensible, but their exact wording is pending review by privacy counsel before commercial launch. A DPA and any compliance attestations are TODO and should not be assumed. If your DPO wants the underlying technical inventory and the firewall source, write to support@funnelledger.com.
Contact us
For privacy questions, deletion requests, subprocessor inquiries, or to request the technical inventory behind the claims on this page:
- Privacy, deletion requests, subprocessor & commercial questions: support@funnelledger.com — include your HubSpot portal ID for a deletion request.
For data-protection authority complaints, the relevant authority depends on your jurisdiction: in the EU / EEA, the supervisory authority where your business is established; in the UK, the Information Commissioner's Office; in California, the California Privacy Protection Agency.