Preventing duplicate opportunities in GoHighLevel starts with a business rule, not a toggle. Decide what one opportunity represents, define when the same contact is allowed to have another one, and then configure the workflow to find and update the right record or create a new one only when no valid match exists.

A contact and an opportunity are different records. One contact can legitimately have more than one service job, estimate, property, or renewal. The goal is not “one opportunity per person forever.” The goal is one opportunity per agreed unit of work.

Separate duplicate contacts from duplicate opportunities

A contact represents a person or organization you communicate with. An opportunity represents a specific deal or work item moving through a pipeline. Contact deduplication settings do not by themselves solve opportunity duplication.

Before changing automation, answer these questions:

  • Does one opportunity represent a person, a property, a service request, an estimate, or a job?
  • Can the same contact have two active requests at the same time?
  • Can one request move between pipelines, or should each pipeline hold a different kind of work?
  • Which field or combination of fields identifies the work item?
  • When a repeated form arrives, should it update, reopen, create, or alert a person?

For a home-service business, “same email address” is often too broad. A property manager may submit work for two addresses. A homeowner may request plumbing service now and an estimate later. Those can be legitimate opportunities even though the contact is the same.

Understand the current opportunity actions

HighLevel’s current Create Opportunity action can allow or block a new opportunity based on whether an opportunity already exists for the contact. Its support page says the duplicate check uses contact ID, not the opportunity name. When duplicates are disabled, a repeated action for that contact does not create a new record. See Workflow Action: Create Opportunity.

That simple guard is useful only when the business rule matches it. If a contact can have multiple legitimate jobs, blocking every later opportunity is too strict.

HighLevel now documents separate actions with more precise roles:

Action Use Important limit
Create Opportunity Create a new record in a selected pipeline and stage Duplicate behavior is based on the contact, so confirm it matches the business rule
Find Opportunity Search the triggering contact’s opportunities using AND filters If several match, it returns only the earliest or latest selected match
Update Opportunity Change the opportunity that triggered the workflow or was found earlier It skips when no opportunity is in context
Create/Update Opportunity Older combined behavior HighLevel says it is being phased out for new workflows and does not use Find Opportunity or the triggering opportunity

The Find Opportunity action can branch to Opportunity Found or Opportunity Not Found. On the found branch, use Update Opportunity. On the not-found branch, use Create Opportunity. This pattern is more explicit than asking a combined action to guess what should happen.

We would not replace a working legacy Create/Update action only because a newer action exists. First document its current behavior, identify the risk, and test the smallest safe change. For new workflows, the separate Find, Create, and Update actions make the decision easier to inspect.

Define the identity rule before building the workflow

Write the rule in plain language and make each part observable.

Business case Suggested identity rule Duplicate decision
One active estimate per contact and service type Contact + service type + open status Update the matching open estimate; create when none exists
Separate jobs for separate properties Contact + service address + job status Create another opportunity when the address differs
One request can move between teams Stable request ID across pipelines Find and move or update the same opportunity
Recurring annual service Contact + property + service period Create a new period only after the prior period is closed
Repeated form for the same active request Contact + form-supplied request identifier Update or alert; do not create another card

An opportunity name can help staff read the pipeline, but a name alone is a fragile identifier. Names can be edited, formatted differently, or reused. Prefer a stable opportunity field when the business process provides one, such as a request ID, property ID, or another agreed key.

Use same-pipeline and cross-pipeline rules intentionally

HighLevel has a sub-account setting for allowing multiple opportunities per contact in the same pipeline. That setting enables legitimate multiplicity; it does not decide which record a workflow should update. HighLevel’s multiple-opportunity guide recommends Find Opportunity and clear entry filters when multiple records are possible.

Cross-pipeline behavior needs a separate business decision. If one job advances from intake to production, moving the same opportunity may preserve a clearer history than creating a second card. If two pipelines represent genuinely independent services, separate opportunities may be correct.

Do not delete and recreate an opportunity merely to move it between pipelines. Deletion can discard context, links, and audit value. The current Update Opportunity action can update the pipeline and stage of an existing opportunity when the correct record is in context.

Protect against repeated and simultaneous triggers

Duplicate opportunities can also originate upstream of the opportunity action. The same real-world event may reach more than one workflow through:

  • a form submission and a contact-created trigger;
  • a form and an integration webhook;
  • a booking and an opportunity-stage change;
  • two nearly simultaneous form submissions;
  • workflow re-entry while a previous execution is still active;
  • a manual action running beside automation.

Create a trigger inventory. For each workflow that can create an opportunity, record the triggering event, filters, re-entry setting, pipeline, identity rule, and whether another path can observe the same event.

A pre-create lookup reduces duplicates, but two simultaneous executions can both look before either creates. Where simultaneous events are plausible, test them. Consider a single authoritative creation workflow, an intake-state marker set before downstream work, or a human exception queue. The right safeguard depends on whether the platform guarantees atomic behavior for that specific path. Do not claim it does without documented evidence.

Build the explicit find-or-create path

A maintainable workflow can follow this order:

  1. Normalize and validate the fields needed to identify the work item.
  2. Use Find Opportunity with the narrowest stable filters available.
  3. On Opportunity Found, update only fields that the new event is allowed to change.
  4. On Opportunity Not Found, create the opportunity once.
  5. Record source and ownership.
  6. Route ambiguous matches to review instead of guessing.

Find Opportunity returns only one record when several match. Choosing “earliest” or “latest” is not a substitute for a unique rule. If multiple matches are possible and either could be correct, narrow the filters or stop for human review.

This design connects naturally to GoHighLevel pipeline stages for home services. A stage should describe what is currently true about the opportunity, while the identity rule describes which work item the card belongs to. Mixing those concepts leads to workflows that create a new card whenever the state changes.

Repair existing duplicates without destroying evidence

Pause before deleting anything. First export or record the relevant opportunities and determine whether the records are truly duplicates or separate jobs for the same contact.

Use a review table:

Check Keep or repair decision
Same contact only Not enough evidence of duplication
Same stable request or property identifier Stronger duplicate signal
Different appointments, estimates, or service periods May be legitimate separate work
Notes, files, tasks, invoices, or ownership differ Preserve before any consolidation decision
One card is referenced by an active workflow Do not remove until workflow impact is understood
One card has the authoritative history Update and retain that record; document disposition of the other

Repair the creation cause before cleaning the pipeline, or the duplicates will return. Prefer non-destructive actions: close or mark a reviewed record, copy needed context, and keep an audit note. Remove a record only when the business owner confirms it is safe and the required history has been preserved.

The Edex funnel, pipeline, and QA case study documents a coordinated implementation with duplicate-prevention rules. It does not document a specific production duplicate incident or a universal configuration. The evidence supports the architecture decision, not an invented cleanup story.

Test both prevention and legitimate multiplicity

Do not stop after one successful form submission. Use fresh contacts and controlled identifiers.

Scenario Expected result
First valid request One contact and one opportunity are created in the intended stage
Same form submitted again with the same request ID Existing opportunity follows the approved update or alert rule
Same contact, different property A second opportunity is created only if the business rule allows it
Same contact, different service type Result matches the documented service rule
Two submissions within seconds No unintended duplicate; any ambiguity reaches review
Existing open opportunity in same pipeline Correct record is found and updated
Existing opportunity in another pipeline Move, update, or create exactly as the cross-pipeline rule specifies
Multiple records satisfy the lookup Workflow does not silently update an arbitrary record
Closed prior job and new request New opportunity is created if the lifecycle rule calls for it
Missing identity field No guess-based creation; staff sees an exception

Capture contact ID, opportunity ID, pipeline, stage, stable identifier, workflow enrollment, action result, and timestamps. How to connect a website form to GoHighLevel covers the upstream field-mapping contract, while the workflow testing guide provides the expected-versus-actual evidence format.

Release rule

The system is ready when a staff member can answer why two opportunities exist for the same contact and point to the rule that allowed them. It is not ready when the only explanation is that a duplicate toggle was on or off.