- Published
- Byline
- GoHighLevel Partners Editorial
- Filed under
- GoHighLevel Automation
The scope list is the security decision, not the token storage — it is what a compromised credential would be able to do.
OAuth 2.0 scope: asking for exactly what the integration needs
A scope is a named permission an application requests, and which the account holder either grants or refuses. It is the difference between “this app can read your contacts” and “this app can do anything you can do”, and it is decided at the moment somebody clicks approve — after which it is rarely revisited by anyone.
For an agency this is the mechanism that makes client integrations defensible. A scoped grant is something you can describe honestly, a client can understand, and either party can revoke. getting api access and securing the credential is the wider subject; this is the part that decides what the resulting access can actually do.
What the consent screen is really doing
The authorisation flow exists so that a person can grant an application limited access without handing over their password. Three things happen: the application states which scopes it wants, the account holder sees them and decides, and the application receives a token that carries exactly those permissions and no others.
That third point is the useful one. A token is not a password with a different shape — it is a bounded credential. If the integration is compromised, what an attacker can do is the scope list, which is why the scope list is the security decision rather than the token storage.
Ask for less, for three separate reasons
| Reason | Effect of asking for less |
|---|---|
| Blast radius | A compromised token can do less |
| Approval | Reviewers and clients say yes more readily |
| Clarity | The scope list documents what the integration does |
The second reason is the one that surprises developers. A request for broad write access on a first integration is a reasonable thing for a client to hesitate over, and marketplace app approval applies the same judgement more formally: an app asking for more than its described function needs is the kind of thing a review process is designed to catch.
The third is underrated. Six months later, the scope list is the fastest honest answer to “what does this integration actually do”, far faster than reading the code.
Read against write, and the line between them
Most scope families separate reading from writing, and a large share of integrations only need to read. A reporting tool, a dashboard, a sync that pushes data outward: none of these need permission to change anything, and requesting write access “in case we add that later” converts a low-risk integration into a high-risk one for a feature that may never be built.
Where writing is genuinely needed, look for the narrowest write scope available rather than the broadest that includes it. And be careful with scopes that permit deletion, which are the ones with no undo — the same reasoning behind treating protected snapshot assets carefully, where the scope of a change is not obvious from where you are standing.
Scope creep, and how it happens without anyone deciding
Integrations accumulate permissions. A feature is added, a scope is appended, the grant is re-approved, and nobody removes the scope when the feature is retired. After two years the application holds permissions for three things it no longer does.
Review the scope list on a schedule, the same way credentials are rotated. The question is not “is this scope harmful” but “does the integration still use it” — and if nobody can say what uses it, that is the answer. Keep the list of granted scopes with the credential inventory; a log kept outside the platform is enough, provided secrets are not in it.
Tokens expire, and that is a feature
An access token is normally short-lived, with a refresh token used to obtain a new one. That design limits how long a leaked token is useful, and it introduces the failure everyone eventually meets: an integration that stops working with no error anybody sees, because the refresh failed and nothing was watching.
Build for it. Detect a failed refresh, surface it somewhere a person looks, and treat a silent stop as a bug rather than a mystery. This is the same class of problem as a step whose external call fails quietly — the connection to reading a webhook payload is that a confirmed round trip is the only proof an integration is still alive. Note also that a revoked grant looks identical to an expired token from the outside, and only one of them should be retried.
Explaining scopes to a client
A consent screen lists technical scope names, and a client asked to approve them is being asked to consent to something they cannot read. Say in one sentence what the integration will read and what it will change, before they see the screen, in the language they use for their own business.
Then treat their approval as bounded rather than general. If a later feature needs a new scope, ask again and say why. That is the same standard applied to consent wording and records: consent recorded for one thing is not consent for a different thing, and the difference matters most at exactly the moment it is inconvenient.
When not to use OAuth at all
Not every integration needs it. If the requirement is to be told when something happens, reading a webhook payload needs no standing grant. If a non-developer is connecting two tools, building an integration without code holds the credential instead of you, though judging what is worth wiring is worth reading before adding connections that create maintenance. And for a script running against your own account, a simple key is often proportionate.
Reach for the authorisation flow when acting on someone else’s behalf. That is what it is for, and it is the only option that gives the other party a way to withdraw.
A short checklist before you request a grant
- List what the integration reads and what it writes, in plain language.
- Map each to the narrowest scope that covers it — and if none fits, question the feature rather than widening the scope.
- Remove any scope you cannot tie to a specific behaviour.
- Confirm the refresh path works, and that a failure is visible.
- Test the boundary: attempt something outside the scope and confirm it is refused.
- Record what was granted, by whom and when, so access and handover when someone leaves and onboarding a new team member have something to work from.
The last matters more with contractors, where training an assistant on agency work argues for scoped, short-lived access as the default. And design within the published request ceilings while you are there — the ceilings that pace a large job covers the same class of constraint, and mapping fields without corrupting data is what you will be doing with the data once the grant works.
Frequently Asked Questions
What is an OAuth scope?
A named permission an application requests and an account holder grants or refuses. It is the difference between an app that can read your contacts and one that can do anything you can do, and it defines exactly what the resulting token is able to do.
Why does asking for fewer scopes matter?
Three reasons: a compromised token can do less, reviewers and clients approve more readily, and the scope list becomes accurate documentation of what the integration does. That last one is the fastest honest answer to what an integration is for, months later.
Should I request write access in case I need it later?
No. That converts a low-risk integration into a high-risk one for a feature that may never be built. Request read-only where reading is all you do, and come back for a narrower write scope when the feature actually exists.
How do I stop scope creep?
Review the granted scopes on a schedule, the same way credentials are rotated. The question is whether the integration still uses each scope, and if nobody can say what uses it, that is the answer. Keep the list with the credential inventory.
Why did my integration stop working with no error?
Usually a failed token refresh that nothing was watching. Access tokens are short-lived by design, and when the refresh fails the integration simply stops. Detect it, surface it where a person looks, and note that a revoked grant looks identical from the outside.
How should I explain scopes to a client?
In one sentence before they see the consent screen: what the integration will read and what it will change, in the language they use about their own business. A technical scope list is not something a client can meaningfully consent to on its own.
When should I use a simple API key instead?
For scripts running against your own account, where a key is proportionate. Use the authorisation flow whenever you are acting on someone else’s behalf, because it is the only option that gives the other party a bounded grant they can withdraw.
We build your GoHighLevel account for you
CRM, pipelines, funnels, SMS and automation — configured for your business, not left for you to figure out.
- Setup (one-time)$850
- Ongoing (per month)$38.80
No obligation quote · reply within 1 business day
This site is independently operated and is not officially affiliated with, endorsed by, or sponsored by HighLevel LLC. We do not receive referral commissions — this is our own flat-fee implementation service.