“distribution”: “private”
to
“distribution”:marketplace in app-hsmeta.json.
Then after adding the scopes, I can access the API. But I’m not sure if this is the way to do it. I don’t want to distribute this publicly.
Hi @ANiazov and thanks for getting back to us!
Based on the documentation, changing “distribution”: “marketplace” in your app-hsmeta.json is the correct approach for OAuth apps.
Here’s what you need to know, for OAuth apps:
- “distribution”: “marketplace” allows installation in multiple accounts (up to 25 before listing, unlimited after marketplace approval)
- “distribution”: “private” limits installation to up to 10 allowlisted accounts
You don’t need to distribute publicly. Setting “distribution”: “marketplace” doesn’t automatically list your app on the marketplace.
According to the docs, you can sign the Acceptable Use Policy (AUP) and use the install URL without creating a marketplace listing.
This gives you OAuth functionality while keeping the app unlisted.
It sounds like you’ve set up everything correctly and generated the installation URL, but the install isn’t completing. This usually happens if you don’t have all the permissions the app requires. Ask a super admin to install it, or try with a test account. If the issue persists, please share a screenshot.
I hope this will help you out. Please mark it as Solution Accepted and upvote to help another Community member.
Good call catching that, the confusion comes from HubSpot’s newer Developer Projects flow.
When “distribution”: “private” is set, OAuth installs are limited to allowlisted portals, so any non-listed account will throw the “validating authorization” error you saw. Changing it to “marketplace” simply enables OAuth installs beyond that list, without forcing a public listing. It’s the right move for internal or partner use cases that need OAuth but aren’t meant for marketplace exposure (Working with OAuth | OAuth Quickstart Guide - HubSpot docs )
Also make sure your scopes include conversations.read or conversations.write depending on which endpoints you’re calling; the Conversations API is separate from the CRM scopes. After updating scopes, run hs project upload and regenerate your install URL to refresh tokens. If this project later needs to sync conversation data back to CRMs or data warehouses, Stacksync can handle the two-way mapping automatically so you don’t juggle tokens or endpoints yourself.