Here is the moment that makes GoHighLevel operators suspicious, and reasonably so. You install an automation tool, you paste in the Private Integration Token you just created inside your sub-account, and everything works. Contacts, opportunities, calendars, tags. Then you ask it to build a workflow, and it asks you to log into GoHighLevel again in a browser window.
The instinct is that something shady is happening. Why does a tool that already has an API token need your login? Did the vendor cut a corner?
No. That second step exists because of a specific, checkable gap in what HighLevel publishes, and every tool that can genuinely build a GHL workflow deals with the same gap in some form. Once you see the shape of it, you can also judge which vendors are handling it responsibly and which are not, which is the part that actually matters for your client data.
What your Private Integration Token really is
Start with what you already gave the tool. A Private Integration Token, the PIT, is HighLevel's replacement for the old v1 API key. Per HighLevel's Private Integration Token documentation, the tokens are static and fixed, they do not automatically refresh unless you rotate them from the interface, and you pick the scopes the integration is allowed to use when you create it. The documentation is also blunt about the one-time copy: do not forget to copy the token, because you will not be able to do it again later.
HighLevel's support article on private integrations adds that you can create up to five of them at both the agency level and the location level. So one operator can hold an agency-scoped token and a per-sub-account token at the same time, which is exactly how most portfolio tooling ends up configured.
That token is a good, clean credential. It is scoped, it is revocable from your own settings, and it never expires on its own. It is also, for one specific job, completely useless.
The wall: there is no workflow write
Go to HighLevel's developer documentation and look at what exists for workflows. There is one route: Get Workflow. It is a read. The response HighLevel documents is a list of workflow objects carrying id, name, status, version, locationId, and created and updated timestamps.
Read that field list again with a builder's eye. It tells you a workflow named "New Patient Nurture" exists, that it is published, and when it last changed. It does not tell you what is inside it. Not the actions, not the wait durations, not which tag gets applied on step four, not which pipeline the opportunity lands in. And there is no documented route to create a workflow, update one, clone one, or delete one.
This is not a secret. It is one of the most requested items on HighLevel's own public API ideas board, where operators have filed requests titled "API to create Workflows" and "API endpoints: POST/PUT/DEL for workflows," arguing that full workflow management would unlock a new tier of automation. Neither request carries a shipped status on that board as of this writing.
So when someone tells you their integration "builds GHL workflows" using nothing but a PIT, one of three things is true. They mean they can add a contact to an existing workflow, which the API does support and is a completely different thing. They mean they generate a document describing a workflow that a human then builds by hand. Or they are describing something the public API does not do.
The practical consequence for an agency: everything you assemble in the workflow builder, the part of GoHighLevel where the actual business logic lives, sits outside the documented surface. Ticking more scopes on your PIT will never change that. It is not a permissions problem. The capability is not published.
So how does the workflow builder itself save anything?
Through your session. When you are inside GoHighLevel with the builder open and you drag in a wait action and hit Save, that write is authorized as you, the signed-in user, not as an integration holding a scoped token. Your browser is carrying a session credential that the application issued when you logged in, and that credential is what the builder presents.
In GoHighLevel's case, that login layer is Google Firebase Authentication. HighLevel does not document this anywhere I can point you to, so treat it as observed behavior rather than a published contract. It has been stable for as long as we have been building against it, and it could change without notice. That caveat is doing real work: any tool built on it should tell you clearly when the mechanism shifts rather than silently reporting success.
That is the entire origin of the second login. A tool that can genuinely author workflows has to hold the same kind of session credential you hold when you build one by hand, because that is the only credential the builder accepts.
What a Firebase capture actually hands over
The capture step is a browser window, your normal GoHighLevel login, and then the tool keeps the session values that login produced. The one that matters is a refresh token.
Google's documentation on managing Firebase user sessions is precise about the two pieces:
- The ID token is short lived. Google states that Firebase ID tokens are short lived and last for an hour. That is the credential a request actually carries, and it goes stale every sixty minutes.
- The refresh token mints new ones. Google states that the refresh token can be used to retrieve new ID tokens. That is why you log in once instead of once an hour.
- The refresh token has a defined kill switch. Google states that refresh tokens expire only when the user is deleted, the user is disabled, or a major account change is detected for the user, including events like password or email address updates.
That third bullet is the most useful line in this entire post for an operator, because it answers the security question without anyone's marketing copy. You do not have to trust a vendor's promise that they will stop using your credential. Change your GoHighLevel password and it stops working. The revocation is in your hands, in a place you already know how to reach.
It also explains the support ticket every tool in this category eventually gets: the workflow builder stopped working and nothing changed. Something did change. Somebody rotated the GHL password, or the account email moved. That is not a bug, that is the documented behavior working correctly.
The scope question people get wrong
The capture is not per sub-account. GoHighLevel issues it against the agency company the browser session was in, which means one capture covers every sub-account under that company. Ten clients under one agency, one login.
Where it bites is the second agency. If you hold sub-accounts under two separate GHL agency accounts, you need one capture per agency, even when the same email address logs into both. The credential cannot be reused across companies.
And there is a trap inside that. The company identifier visible in your agency web address is not always the same identifier the session itself authenticates as. Bind the credential to the wrong one and you get a failure with a particularly nasty shape: the tool believes it is authenticated, and the write goes somewhere other than where you meant. We found that one the hard way while getting the credential working across client agencies, and it is the same category of problem as the invalid IDs that kill GHL automations without ever showing an error. GoHighLevel is consistently quiet about failure, so anything you cannot verify by reading back, you have not actually verified.
If you run more than a handful of accounts, this is worth confirming deliberately rather than assuming. We wrote about the wider version of that discipline in running 20 sub-accounts from one console, and the short version is the same here: a write that does not name the account it landed in is a write you should not trust.
Five questions to ask any vendor who asks for this
The credential itself is not the risk. Where it lives is. Ask these before you hand it over, and treat vague answers as answers.
- Where are the values stored? On your own machine, or on the vendor's server? A cloud-hosted tool that asks for this is asking to keep a live version of your GoHighLevel session on infrastructure you do not control, alongside every other customer's. A tool running locally is not making that ask, and the difference is the entire security conversation.
- Does it rotate and persist the credential itself? If it does not, you will be re-logging in constantly, and a tool that makes re-authentication tedious trains you to do it carelessly.
- Can it tell you the credential is dead before a client build depends on it? The answer should be a status check you can run on demand, not a failure you discover mid-launch.
- Does it bind writes to a named account and read them back? Given the company identifier trap above, "it saved successfully" is not evidence. Naming the account it wrote to is.
- What breaks if you change your GHL password? The honest answer is "the workflow builder stops until you log in again." A vendor who tells you nothing breaks either is not using this mechanism or is not being straight with you.
Notice what is not on that list: whether the tool gets extra powers. It does not. The capture carries your permissions and nothing beyond them. If your GHL user cannot see a sub-account, no tool holding your session can see it either. The exposure is not elevation, it is duplication, and duplication is a storage question.
How we handle it
GHL Command is what I built to run my own brands and client accounts, and it uses exactly the mechanism described above, because there is no other one. In practice it is one browser login you do once during setup. You say "Unlock the Workflow Builder," a Chrome window opens, you log into GoHighLevel the way you always do, and that is the whole step.
The values land in a file on your own computer next to your PIT. They rotate there. Nothing about your GoHighLevel account is stored on our servers, because the tool runs on your machine rather than ours, which means the storage question above has a short answer. The built-in checkup reports whether the workflow builder login is still good alongside your license and API connection, so you find out on a Monday morning rather than during a client's launch. And because the credential is company-scoped, one login covers every sub-account under that agency. If you operate two agency companies, you capture twice and the tool routes each write to the right one.
What that unlocks is the layer most GoHighLevel integrations cannot reach: building workflows, cloning them between sub-accounts, editing triggers, auditing branch logic before a real lead hits it. The reading side of GHL is well served by a dozen tools. The building side is where the gap is, and the gap has a cause you can now verify yourself in HighLevel's own documentation.
Flat $97 a month, every sub-account you manage included, never billed per account.
Reach the layer your API token cannot. Flat $97/mo.
Build, clone, and audit GoHighLevel workflows from Claude on your own machine, across every sub-account you manage. Your credentials stay on your computer, and the price does not move when your client list grows.
See how it worksFrequently asked questions
Why can a Private Integration Token read my workflows but not build one?
Because HighLevel documents one workflow route, Get Workflow, and its documented response is metadata only: id, name, status, version, locationId, and timestamps. No create, update, clone, or delete route for workflows appears in the public documentation, so there is no permission to grant. Adding scopes to your PIT cannot unlock something that is not published.
What is the Firebase capture in plain terms?
A one-time browser login whose session credentials the tool keeps, so it can act the way the workflow builder acts when you use it by hand. Google documents that Firebase ID tokens last an hour and that a refresh token is used to obtain new ones, which is why it is one login rather than an hourly one.
Does it give a tool more access than I have?
No. It is your session, carrying your permissions. The real question is where the values are stored and whether you can end them, and you can: Google documents that refresh tokens expire when the user is deleted or disabled, or on a major account change such as a password or email update.
Do I need one capture per sub-account?
No. One per agency company, covering every sub-account under it. Two separate agency accounts need two captures, even with the same login email. That is our operating experience across client agencies rather than a documented HighLevel rule.
What should make me walk away from a vendor asking for this?
Storing it on their servers without saying so, having no way to report that the credential has expired, or claiming they build GHL workflows through the public API alone. The last one is checkable in thirty seconds against HighLevel's own documentation, which is the nice thing about a gap this well documented. For the kind of build quality this credential makes possible, see when If/Else branching earns its place in a GHL workflow.