Shared Data — CleanMerge

Reference content for the "Shared Data" section of the HubSpot Marketplace listing — describes exactly how CleanMerge's requested OAuth scopes are currently used. This is written to be accurate as of today's build, not aspirational.

Write scopes are back, and still not installer-facing. CleanMerge now requests write access to Companies and Contacts again (plus schema-write, for creating custom properties) to support two capabilities: the merge executor (finds and merges duplicate records) and a new warehouse-ingest pipeline (creates/updates records from a customer-configured data-lake query). Both remain reachable only via internal admin endpoints, configured per customer by CleanMerge's operator — not self-serve for installers. The scopes are requested because these capabilities are real, deployed, and actively used (just not yet installer-triggered), not held speculatively.

Contacts

Scope requestedcrm.objects.contacts.read, crm.objects.contacts.write, crm.schemas.contacts.write
DirectionBidirectional
Fieldsfirstname, lastname, email, phone, plus any warehouse-mapped custom properties
How it's actually used The CleanMerge: Normalize CRM Data workflow action does not call HubSpot's CRM API at all — HubSpot's own workflow engine passes the selected property's value into the action and writes the returned value back to whichever property the workflow is configured to update. CleanMerge never reads or writes a Contact record directly for this feature.

The read/write scopes support two internal-admin capabilities: the duplicate-detection and merge engine (reads Contacts to find likely duplicates; on a human-approved or high-confidence match, normalizes and merges via HubSpot's Merge API), and the warehouse-ingest pipeline (reads Contacts to match incoming warehouse rows against existing records; creates a new Contact or updates a matched one, and can create a custom property via the schema-write scope if a mapping calls for a field that doesn't exist yet).

Companies

Scope requestedcrm.objects.companies.read, crm.objects.companies.write, crm.schemas.companies.write
DirectionBidirectional
Fieldsname, domain, phone, plus any warehouse-mapped custom properties
How it's actually usedSame as Contacts above — the workflow action doesn't touch Company records directly; read/write is used by the merge engine and the warehouse-ingest pipeline.

Conversations & Owners (optional scopes)

Scope requestedconversations.read, crm.objects.owners.read — requested as optional scopes, not required for every installer
DirectionRead only
FieldsA created Contact's hs_object_source_label (to tell whether it came from Conversations); HubSpot Owner id/email
How it's actually used Supports Contact Gate: a reverse-quarantine tool for Contacts HubSpot auto-creates from unknown Conversations/Help Desk senders. On a contact.creation webhook, CleanMerge checks the new Contact's source label — if it's Conversations and the portal's policy says to quarantine it, the Contact is archived within seconds and held in a review queue for a human to promote or discard, rather than staying in the CRM. Every portal defaults to a dry-run mode (log the decision, never delete) until manually confirmed safe for that account. Owners are only used to bulk-seed an allowlist of staff email addresses, on request.

Kept optional rather than required because most installers only use the free workflow action and never touch Contact Gate — this scope is only requested when walking a specific customer through setup for this feature, not from every installer by default.

If/when this becomes installer-facing

The review queue, merge executor, and warehouse-ingest configuration are all real and deployed, but reachable only by CleanMerge's operator via internal admin endpoints today — not by installers. If/when any of these become self-serve, this page should be updated to reflect installers configuring and triggering them directly, rather than requesting it on their behalf.