← Resources

CRM Hygiene Checklist & Naming Conventions

Dirty CRM data compounds: one duplicate contact double-fires every automation and splits a deal's history in two. The doctrine - one dedupe key per object, one deal-naming pattern, a minimum-viable-record rule - plus a ten-point weekly audit your agent runs read-only.

Who this is for

Anyone whose CRM is written by more than one hand - especially when one of those hands is an AI agent. Agents cut both ways on hygiene: a sloppy one manufactures duplicates at machine speed; a disciplined one makes the audit below nearly free. The difference is whether the conventions exist somewhere the agent can read.

Use it at two moments: install the conventions on day one, when they cost nothing, and run the audit weekly, so each pass surfaces a handful of issues instead of a backlog everyone looks away from.

Dedupe rules: one key per object

The doctrine is one sentence: every object gets exactly one dedupe key. Contacts key on lowercased email. Companies key on domain, never name - names mutate ("Acme", "Acme Inc.", "ACME Corp"); domains stay put. Deals have no natural key - precisely why they need the naming convention below. Activities are append-only and never deduped; a wrong timestamp is fixed with occurred_at backdating, not a second copy.

ObjectDedupe keyOn collision
ContactEmail, lowercasedMerge into the oldest record; keep the newest non-empty field values
CompanyDomainMerge; relink contacts and deals to the survivor
DealCompany + title (by convention)Keep one; close the other as lost with a note pointing at the survivor
ActivityNone - append-onlyNever merge; correct timestamps via occurred_at

Check-then-create is a race: two agents both search, both find nothing, both create. The correct pattern is create-then-catch: attempt the create and treat a conflict as success-with-data. Relm implements this natively - POST /v1/contacts with an existing email returns 409 conflict carrying the full existing record, so the agent's next move is a PATCH, not a second copy. Related but different: an Idempotency-Key header dedupes the same request (a network retry); the email key dedupes the same entity (a re-discovery). You want both - details in the API docs.

Naming conventions

Names are the field every list view, search box and agent prompt touches. The load-bearing convention is deals: Company - What - Quarter, as in Acme - Onboarding Expansion - Q3 2026. The company prefix makes every Acme deal findable with one substring search (q=Acme in Relm). The "what" separates parallel deals on the same account. The quarter is the expected-close quarter, renamed when the deal slips - which is the point: a rename is a cheap, visible re-forecast signal no hidden date field provides.

ObjectConventionExample
DealCompany - What - QuarterAcme - Onboarding Expansion - Q3 2026
CompanyTrading name, no legal suffixAcme, not Acme Holdings Inc.
Contact emailAlways lowercase[email protected]
Activity subjectVerb-first, one lineCalled re: renewal pricing
Custom field keyssnake_case with a family prefixmeddpicc_champion, icp_segment
Pipeline stage keysLowercase snake, stable foreverproposal_sent, never "Proposal Sent!"

The family prefix lets an agent find every field in a kit by convention (meddpicc_*) instead of by memory; start from a prebuilt kit like the SaaS CRM data model rather than inventing keys ad hoc.

The required-fields doctrine

Three rules, in priority order:

1. Define the minimum viable record. The fewest fields that make a record actionable, not a wish list: a contact needs an email or a phone; a company needs a name and a domain; a deal needs a title, a stage, and a link to a company or contact; an activity needs a type and a linked record. Everything else is enrichment.

2. Enforce at moments of change, not at creation. Required-at-create is how CRMs fill up with [email protected] and "n/a" - people (and agents) type garbage to get past the gate. Enforce at stage moves instead, where the information genuinely exists: no proposal_sent without a value, no negotiation without a named contact. Wire the gates as stage-triggered rules - the stage-change playbooks cover the pattern.

3. Empty beats fake. An empty field is a visible to-do; a placeholder defeats the filter that would have found the gap. Ban "n/a", "TBD", "asdf" and noreply@ outright - the audit below hunts them explicitly.

The weekly hygiene audit

Ten checks, read-only, in this order: 1-3 are structural (they corrupt everything else), 4-5 are linkage, 6 is naming, 7-10 are freshness and truth.

  1. Duplicate contacts - group by lowercased email; flag groups larger than one.
  2. Near-duplicate contacts - same first + last name at the same company, different or missing email.
  3. Duplicate companies - group by domain; also flag companies with no domain.
  4. Orphan deals - open deals linked to neither a contact nor a company.
  5. Unlinked contacts - email domain matches an existing company's domain but no link is set.
  6. Naming violations - deal titles that do not parse as Company - What - Quarter.
  7. Stale deals - open deals with no activity in 14+ days; 30+ days is a zombie.
  8. Stage-gate gaps - deals past proposal with no value, past negotiation with no named contact.
  9. Placeholder junk - "n/a", "TBD", "test", "asdf", noreply@ anywhere in live records.
  10. Expired quarters - open deals whose title names a quarter that has already passed.

The audit reports; it does not fix. Merges and renames are destructive - they belong in a separate, human-approved write pass. Recurring fixes should graduate into standing rules; see the automation recipes for ready-made ones.

The audit prompt

Paste this into any MCP client pointed at your CRM. It runs all ten checks read-only and ends with a report, never a write:

You are my CRM hygiene auditor. My CRM is Relm
(MCP: https://api.relmcrm.com/mcp - use the relm_* tools).
This is a READ-ONLY audit: list and read anything, but do not
create, update, delete, or merge a single record.

1. Read the schema. Note the objects, custom fields, pipelines
   and stages that exist. Treat won/lost-type terminal stages as
   closed; every other stage is open.
2. DUPLICATES. Page through all contacts; group by lowercased
   email and flag groups >1. Also flag near-dupes: same first +
   last name at the same company with different or missing
   emails. Page through companies; group by domain, flag groups
   >1 and companies with no domain.
3. LINKAGE. Flag open deals with no contact and no company.
   Flag contacts whose email domain matches an existing
   company's domain but that have no company link.
4. NAMING. Deal titles must parse as "Company - What - Quarter"
   (e.g. "Acme - Onboarding Expansion - Q3 2026"). Flag
   violations and propose the corrected title from the linked
   company. Also flag open deals naming a quarter that has
   already passed.
5. FRESHNESS. For every open deal, find its most recent
   activity. No activity in 14+ days = stale; 30+ = zombie.
6. TRUTH. Flag open deals past the proposal-type stage with no
   value, open deals past a negotiation-type stage with no linked
   contact, contacts with neither email nor phone, and placeholder
   junk anywhere: "n/a", "TBD", "test", "asdf", noreply@.
7. REPORT. Start with a scorecard: records checked and issue
   counts per category. Then one table per category with record
   IDs and a one-line fix each. End with the five highest-impact
   fixes overall. Do not apply any of them - if I want fixes,
   I will ask for a separate write pass and approve it.

Apply it with your agent

Point Claude (or any MCP client - see how to give your AI agent a CRM) at https://api.relmcrm.com/mcp with your relm_live_ key and paste the prompt above. The audit is read-only, so it is safe on live data; a relm_test_ key rehearses it against an isolated, free dataset. Over REST, the dedupe pattern is one call - the 409 hands your agent the existing record instead of a dead end:

curl https://api.relmcrm.com/v1/contacts \
  -H "Authorization: Bearer relm_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "email": "[email protected]", "first_name": "Ada" }'

409 Conflict
{
  "type": "https://relmcrm.com/errors/conflict",
  "title": "Conflict",
  "status": 409,
  "detail": "A contact with email '[email protected]' already exists.",
  "code": "conflict",
  "existing": { "id": "con_x8f3k2m9q2", "object": "contact",
                "email": "[email protected]", "first_name": "Ada" }
}

Run it before the pipeline review agent prompt - reviewing an undeduped pipeline produces confident, wrong numbers.

FAQ

What should be the unique key for CRM contacts?

Lowercased email - the only identifier that is both unique to a person and present on most business records. Names collide, phone numbers get reformatted, LinkedIn URLs drift. For companies the key is the domain, not the name: names mutate (Acme, Acme Inc., ACME Corp) while the domain stays put. Deals have no natural key, which is exactly why they need a naming convention.

How do I stop an AI agent from creating duplicate CRM records?

Use create-then-catch instead of check-then-create. Checking first is a race: two agents both search, find nothing, and both create. Attempt the create instead and treat a conflict as success-with-data. In Relm, POST /v1/contacts with an existing email returns 409 with the full existing record in the body, so the agent PATCHes that record instead of duplicating it. Add an Idempotency-Key header for retry safety - it dedupes the request, while the email key dedupes the entity.

What naming convention should I use for deals?

Company - What - Quarter, for example 'Acme - Onboarding Expansion - Q3 2026'. The company makes every deal findable with a substring search, the what separates parallel deals on the same account, and the quarter is the expected-close quarter - renamed when the deal slips, so the rename doubles as an honest re-forecast signal. Any title that needs the record opened to be understood has failed.

How often should I run a CRM hygiene audit?

Weekly, read-only, ideally before your pipeline review. Weekly means each pass finds a handful of issues instead of hundreds, and with an agent running the checklist it takes minutes, not an afternoon. Save the write pass - merges, renames, relinks - for explicit approval after you have seen the report.

Do I need Relm to use this checklist?

No. The dedupe keys, naming conventions, required-fields doctrine and the ten audit checks work in any CRM, or in a spreadsheet. The prompt on this page targets Relm's MCP server because that makes it a paste-and-run job for an agent, and Relm's 409-with-existing-record behavior implements the dedupe pattern natively - but every check translates to HubSpot or Salesforce queries.

Run the audit on a clean API

1,000 requests a month on the Free plan, no card. See pricing.

Start free →