# Resolving a prospect to an existing relationship

Before a discovered organisation becomes a prospect, `prospect_identity_resolution` asks whether the workspace already knows it. A match means the record is attached to the existing Person or Company instead of starting a cold life of its own. This is the check that stops a customer receiving an introduction to a company that has been invoicing them for a year.

- **Status:** Available
- **Audience:** both
- **In the app:** #/prospects, #/relationships, #/companies
- **Last verified:** 2026-09-10
- **Canonical:** https://connectbyjbrh.com/docs/prospects/prospect-identity/

## Why this check exists at all

Discovery finds organisations that fit a description. It has no opinion about whether you already know them, and a description of an ideal customer naturally describes your actual customers too — that is what makes it a good description. Without resolution, the better your discovery brief, the more of your own client list it would hand back to you as strangers.

The damage is not a wasted send. It is the message itself: an introduction, a fit reason explaining why this company might benefit, an opening built from public research about a business whose account manager you already are. One of those does more harm than a hundred unanswered cold emails.

## What it matches on

| Signal | Compared against | Strength |
|---|---|---|
| An address on a channel | Existing Identity rows, normalised the way `value_key(kind, value)` normalises them | Strongest — one address resolves to exactly one Person |
| An organisation's web domain | Company records and the domains of known identities | Strong for organisations with their own domain |
| Organisation name plus location | Company records in the same workspace | Weaker; two businesses share a name more often than people expect |
| A named individual | People in your relationships | Depends entirely on how distinctive the name is |

Normalisation is what makes address matching work at all. An address that differs by case, by punctuation the provider ignores, or by the display name wrapped around it is the same identity, and `value_key` is where that decision is made once for the whole product rather than re-implemented per feature.

> **Note** Resolution runs inside one workspace and cannot see another's. That is not a policy setting — the allowlist, the workspace kernel and row-level security each independently prevent it, which is why a customer of yours who is also a customer of another Connect workspace produces no signal in either direction.

## What happens when it fires

1. A strong match resolves. The candidate is not created as a cold prospect.
   - Result: You see the existing relationship instead, with its timeline, so the useful response — a call, a renewal, an upsell — is one click away rather than hidden behind a duplicate record.
2. A weak or ambiguous match is proposed rather than applied.
   - Result: Connect follows the same rule it follows everywhere two records might be one: `merge_people` is a human decision, and so is this. A guessed merge is far harder to undo than a duplicate.
3. No match: the candidate proceeds to research as normal.
   - Result: Nothing is recorded about the check having run, beyond the fact that the prospect exists.

A resolution that fires during an import behaves the same way and is reported in the import summary, so a spreadsheet containing forty of your own clients does not quietly become forty prospects.

## When it is wrong

**A genuine new prospect was matched to a customer** — Two organisations share a name, or one address was attached to the wrong Person earlier. Correct the identity on the Person record; the prospect can then be created.
**A known customer was prospected anyway** — The organisation was reached under an address, domain or name that is not on any record you hold. Adding that identity to the Person prevents a repeat.
**The same company exists twice in relationships** — Resolution matched one of the two. Merge them — the merge preserves identities, stages, follow-ups, deals, demos, cases and onboarding from both sides — and future resolution has one target.
**A supplier or partner was treated as a customer** — Resolution answers 'do you already know them', not 'are they a customer'. Anyone in your relationships counts, which is usually what you want.

## Questions

### Can I turn the check off?

It is not offered as a switch, and the reason is asymmetry: a missed prospect costs you one opportunity you can recover next month, while an introduction sent to a current client costs standing you cannot recover at all. Correcting a wrong match is the supported route.

### Does it match against people I have only emailed once?

Yes — anyone with an Identity in the workspace is known, whatever the depth of the relationship. If you would rather that a one-time enquirer were prospectable, the honest fix is to look at whether they should have a Person record at all.

### Where is a match recorded?

On the decision trail with the reason, alongside every other refusal. A refusal is a decision, and a prospecting run that returned fewer rows than you expected is usually explained there rather than in the list itself.

## Related

- [Prospecting in Connect](https://connectbyjbrh.com/docs/prospects/)
- [Identities](https://connectbyjbrh.com/docs/relationships/identities/)
- [Connect refused to prospect an existing customer](https://connectbyjbrh.com/docs/troubleshooting/prospect-already-customer/)
- [Telling a new prospect from an existing customer](https://connectbyjbrh.com/research/prospect-identity-resolution/)
- [From prospect to opportunity](https://connectbyjbrh.com/docs/prospects/prospect-to-opportunity/)
- [Security and isolation](https://connectbyjbrh.com/docs/security/)

## What this page is based on

- `docs-source/sources/CHANNELS.md` §4 and §5 — identity resolution, Identity and merge
- `docs-source/sources/GENERAL.md` §1 and §2 — the three isolation layers
- `backend/app/prospect_identity_resolution.py`, `backend/app/identity.py`
- Connect capability registry (`docs-source/facts.py`)
