Skip to main content
You run an agency. Each client you serve lives in their own GoHighLevel sub-account. Team Follow Up mirrors that exactly: your agency is your account, and each connected sub-account is a project. Agents, campaigns, contacts, calls and phone numbers all belong to one project. The dashboard says “sub-account”. The API says “project” and “location”. They are the same thing.

The three names for one project

Every project carries three identifiers, and they are not interchangeable. Build on locationId. When an endpoint accepts both locationId and projectName, it applies the id and ignores the name.

What a project holds

A project record from GET /api/v2/projects/{id} carries the settings that apply to every campaign inside it:
  • status and active, described below.
  • installed: whether the GoHighLevel integration is set up. A project can be installed and still disconnected when its credential has stopped working. That needs a reconnect, not a reinstall.
  • timezone: the sub-account’s timezone. Calling windows use it unless a campaign says otherwise.
  • multipleTimezoneCheck: the project-level default for contact timezone. A campaign can override it.
  • callingWindowOverride: a project-wide calling window that campaigns inherit.
  • callbacksHandledByHuman: whether callback requests go to your team rather than back to the agent. See Speed to lead and power dialer.
  • knowledgeBase: plain text about the business that every agent in the project can draw on, such as opening hours or service areas.
  • campaigns[]: every campaign in the project, with its own settings. See What a campaign is.
  • ghl: live location data read from GoHighLevel, such as the business address and phone. null means the connection could not be used. Read status rather than interpreting this yourself.
  • crm: the CRM behind the project. For the software this is ghl. See Built around GoHighLevel.
GET /api/agent-builder/projects is the lightweight list: just the projects that can hold campaigns, for pickers and lookups. Use GET /api/v2/projects when you need the full record.

Project states

Park a project by setting active: false with PUT /api/v2/projects/{id}. Parking frees its plan slot. DELETE /api/v2/projects/{id} goes further: it disconnects the sub-account and hides the project from your workspace, and it needs the separate projects:delete scope.

Agencies

GET /api/v2/projects/agencies lists the agencies you can see, each with its id, name, niche and agencyType. An agency admin is always pinned to their own agency, so the agencyName filter on GET /api/v2/projects narrows within it and never widens beyond it. An API key belongs to an agency. Everything it reads or writes is scoped to that agency’s projects. See Authentication.

Systems and validation

GET /api/v2/projects/systems returns the seven legacy campaign templates, such as appointment_booking and inbound_receptionist. Each one lists the dispositions (outcomes) an agent built on it can produce, the postCallFields it records, and the dynamicVars its prompt can use. GET /api/v2/projects/{id}/campaigns/{campaignId}/validate checks that a campaign’s agent has the fields and variables its system expects. ok: false comes with missing, present and extra, so you can see exactly what to fix before going live.

Boundaries

  • One project is one GoHighLevel sub-account. There is no project without one.
  • A campaign belongs to exactly one project, and its locationId is that project’s.
  • The agentType on a project’s campaigns is the legacy template id, not the three-value type the Agents module uses. See Campaign types and capabilities.
  • Names are labels. Ids are identity.

In the API