Practical automation · 4 min read
Send GoHighLevel leads to the right branch
Keep website requests with the right team. Map your GoHighLevel accounts, check contact matches, and test the handoff before automatic replies start.
Suppose a plumbing company has three branches and one website. A customer asks for an estimate, but the message lands with a team that does not serve their area. The form worked. The handoff failed. Start by deciding which team owns each request, then connect that choice to the correct GoHighLevel account and contact record.
What to take away
- Map your actual sub-accounts before deciding how to route physical branches.
- Keep access tokens on the server and choose accounts from an approved branch map.
- Review conflicting email and phone matches before updating a contact.
- Test unclear locations and repeated submissions as well as the successful path.
Our suggested request flow
Choose the branch
The customer picks a service area they recognize.
Check the account
The server finds the approved account and connection.
Check the contact
Match the request to the right customer record.
Hand off the work
Save the request and start the agreed follow-up.
If the branch is unclear or contact details conflict, hold the request for review before updating records or sending a reply.
Map your accounts before connecting the forms
GoHighLevel uses the terms location and sub-account in its API documentation. That is an account boundary. Do not assume your account setup has one sub-account for every physical branch.
List each branch, the team responsible for it, and the GoHighLevel sub-account that should receive its requests. Record that account's locationId. If several branches share an account, decide how their requests will be assigned within it. If they use separate accounts, keep that split explicit in the integration.
Agree on this map with the people who answer the messages. A developer should not have to guess which branch owns a postcode or which team handles a shared phone number.
Sources: HighLevel: sub-account API
Check which account the connection can access
HighLevel supports private integrations at both agency and sub-account level. For a contact connection, check the token's account and permissions against the endpoint you will use. Copying credentials from another branch can cause a failed request or a write to the wrong account.
For marketplace apps that target sub-accounts, HighLevel documents two OAuth paths. A sub-account user receives a Location token. An agency user receives a Company token, which must be exchanged for a Location token to use sub-account APIs. The exchange identifies the target with companyId and locationId.
Our recommendation is to store each approved account's connection on the server. Check that the app is installed for the intended account and has the permissions it needs. Confirm the endpoint and API version in the current reference before building the request.
Sources: HighLevel: private integrations · HighLevel: sub-account app installations · HighLevel: location access tokens
Let the customer choose a branch, then check it on the server
Use familiar choices such as branch names or service areas. The server should translate that choice through your approved branch map. An arbitrary locationId sent by a browser should never be enough to choose which account gets updated.
HighLevel's create-or-update contact endpoint, called upsert, requires a locationId. Supply the approved destination from your server, with the matching account connection. Keep tokens out of browser code, form fields, and public links.
For our hypothetical plumbing company, an Eastside request maps to the Eastside team's agreed account. A missing or unrecognized branch stays in a review queue. It does not fall back to whichever account was connected first. Keep the original request so the team can resolve it.
Check contact matches before changing records
With the default upsert behavior, HighLevel uses the location's contact matching order. If one existing record matches the email and another matches the phone, the documented behavior is to update the record matching the first configured field and ignore the second field.
Our recommendation is to catch that conflict before calling upsert. Ask a person to resolve it, especially when customers share an office or household phone. Keep confirmed links to a contact together with the account they belong to. Do not treat an email match as permission to merge records across accounts.
Test the handoff before turning on replies
Use test contacts to submit one request for each branch. Check the destination account, contact, assigned team, and next action. Then test a missing branch, an unapproved account ID, conflicting contact details, and a connection that has been removed.
Submit the same request twice and interrupt the connection after a write. Decide how your integration will recognize work it already completed, so a retry does not create another task or repeat the reply. Save a processing record with the request, destination, and result. Keep automatic messages off until these cases behave as agreed.
Keep this handy
Your pre-project checklist
- Have the teams agreed which account and person own each branch's requests?
- Does the server check branch choices against an approved account map?
- Are tokens stored on the server, with the right account and permissions?
- Does each contact lookup and update use the intended sub-account?
- Do conflicting email and phone matches wait for review?
- Can the team recover a failed request without creating duplicate work?
- Have you checked the resulting assignment and reply for every branch?
Prefer to write it down? Tell us about your project. No portal account required.
These examples explain how we would approach the work. They are not client results. How we write our guides or send a correction.