GHL Won't Let You Add Multiple Contacts to an Opportunity. Here's the Fix.

Published on March 20,2026

I was building a sync pipeline that pushed deal records from an external CRM into GoHighLevel. Each deal had multiple people attached: a buyer, a seller, sometimes an agent.

But there was a problem.

When you create an opportunity in GHL via the API, you can pass one contact. That's it. One. The UI lets you see multiple contacts on a deal, so clearly GHL supports it, but the create endpoint doesn't expose it. I went through the docs twice thinking I missed something.

I didn't miss anything. It's just not there.

The Workaround That Isn't Really a Workaround

After digging around, I found an endpoint that GHL doesn't make obvious: /associations/relations.

It's not in the opportunities section of the docs. It lives under a separate associations namespace, and it's how GHL handles relationships between objects internally, including contacts and opportunities.

Once you've created the opportunity, you call this endpoint for each additional contact:

POST https://services.leadconnectorhq.com/associations/relations
{
  "locationId": "your_location_id",
  "associationId": "OPPORTUNITIES_CONTACTS_ASSOCIATION",
  "firstRecordId": "your_opportunity_id",
  "secondRecordId": "your_contact_id",
  "pipelineId": "your_pipeline_id"
}

Headers:

Authorization: Bearer YOUR_ACCESS_TOKEN
Version: 2021-04-15
Content-Type: application/json

The response gives you back a primary boolean. The first contact you attach during opportunity creation is primary. Everyone else you add through this endpoint is not.

A Few Things Worth Knowing

The associationId value OPPORTUNITIES_CONTACTS_ASSOCIATION is a hardcoded string. Not an ID you look up, just use it as-is.

The pipelineId is optional in the schema but pass it anyway. It keeps the relation scoped correctly.

Order matters: create the opportunity first, get the ID back, then loop through your remaining contacts and call this endpoint for each one. You can't batch them.

If you're syncing any multi-party record into GHL (deals, projects, cases), this is the endpoint you need. The standard opportunity creation won't complain about missing contacts. It'll just leave them out.

Check the associations section. Not the opportunities page.



More in this category: Integrating Demio and Go High Level: A Step-by-Step Guide to Adding New Registrants to GHL and Tracking Webinar Attendance ยป