[object Object]

App marketplace review used to be a formality. In 2026 it isn’t: scoped permissions, security review, OAuth correctness, and listing copy all get scrutinized. Submissions get rejected for fixable issues. Here are the patterns that get apps approved on the first review.

Request only the scopes you actually use

The reviewer will flag any scope that doesn’t appear in your app’s actual API calls. Audit your codebase before submission and request a minimal scope set. crm.objects.contacts.read is not enough if you also write; explicitly request .write. Conversely, don’t request crm.objects.deals.write if you only read deals.

OAuth flow must round-trip cleanly

The reviewer will install your app, walk the OAuth flow, and check token refresh. Common failure: refresh token logic that breaks at the 6-hour mark because the dev tested only the initial flow. Build refresh handling and exercise it before you submit:

async function getValidToken(portalId) {
  const stored = await getTokenFromDB(portalId);
  if (Date.now() < stored.expires_at - 60_000) return stored.access_token;
  const fresh = await refreshOAuthToken(stored.refresh_token);
  await saveTokenToDB(portalId, fresh);
  return fresh.access_token;
}

Webhook subscription, not polling

Apps that poll the API for changes get rejected. Use webhook subscriptions for change events. If you absolutely need a polled snapshot, document why in the submission notes.

Listing copy: specific, not aspirational

“Sync your data seamlessly” gets rejected. “Two-way contact sync between HubSpot and [Tool], including custom properties, list membership, and engagement events, with conflict resolution” gets approved. Be concrete about what your app does and doesn’t do.

Screenshots from a populated portal

Empty-state screenshots fail review. Populate a demo portal with realistic data and capture screenshots that show the app delivering value. The first screenshot should answer “what does this look like in action.”

Uninstall behavior

Reviewers will install and uninstall. Your app must clean up: delete webhook subscriptions, revoke any portal-side resources, and not leave dangling permissions. A failed uninstall is a near-automatic rejection.

Error handling visible to the user

When the user’s HubSpot API call fails (rate limit, invalid scope, missing property), surface the error. Silent failures in your app’s UI suggest poor production handling and reviewers note it.

Privacy policy and data handling docs

Required. Your privacy policy must specify what HubSpot data you store, where, for how long, and how the user requests deletion. “We take privacy seriously” is not a privacy policy.

Versioning

Use semantic versioning visibly. Reviewers prefer apps that version their API integrations explicitly. Pin to a HubSpot API version (e.g., v3) and document your upgrade plan.

What to do this week

Audit your scope requests against your actual API call list. Eliminate the unused ones. Test your OAuth refresh path with a manually-expired token. These two fixes account for ~60% of first-pass rejections.

[object Object]
Share