Public app: 403 MISSING_SCOPES when creating Custom Object schema — need solution/next steps

Hi all,

We’re building a public app (HeyRuby.ai) that lets customers connect their HubSpot CRM and import structured data. We want to model that data as a Custom Object and associate it to Deals and Companies.

Problem
When we try to create the custom object schema from our public app, the API returns 403 MISSING_SCOPES.

Endpoints tried

  • POST /crm-object-schemas/v3/schemas
  • POST /crm/v3/schemas

Error (example)

Status: 403
{
 "status": "error",
 "message": "The scope needed for this API call isn't available for public use.",
 "category": "MISSING_SCOPES",
 "correlationId": "81c4fd00-c610-49ab-b4b6-6c9491ed0be3"
}

Notes

  • It fails with an OAuth token from the public app installed on a customer portal.
  • We can create records of existing custom objects and use Associations v4 fine—the blocker is creating the schema itself from a public app.

What we need

  1. Is there a way for a public app to get Custom Objects OAuth access so we can request schema write scopes and create the schema programmatically?
  2. If yes, what’s the process to enable it (and any eligibility requirements)?
  3. If not, what’s the official workaround HubSpot recommends for public apps (beyond asking admins to create the schema manually or via a private app)?

Repro (minimal)

curl -i https://api.hubapi.com/crm-object-schemas/v3/schemas \
 -H "Authorization: Bearer <OAUTH_ACCESS_TOKEN_FROM_PUBLIC_APP>" \
 -H "Content-Type: application/json" \
 -d '{
 "name":"ruby_plan",
 "labels":{"singular":"Ruby Plan","plural":"Ruby Plans"},
 "primaryDisplayProperty":"name",
 "requiredProperties":["name"],
 "properties":[
 {"name":"name","label":"Name","type":"string","fieldType":"text","isPrimaryDisplayLabel":true},
 {"name":"status","label":"Status","type":"enumeration","fieldType":"select",
 "options":[{"label":"Draft","value":"draft"},{"label":"Live","value":"live"}]},
 {"name":"start_date","label":"Start Date","type":"date","fieldType":"date"}
 ],
 "associatedObjects":["DEAL","COMPANY"],
 "metaType":"PORTAL_SPECIFIC"
 }'

Goal behavior (once allowed)

  • Idempotent: read schema first; create only if missing.
  • Namespaced: vendor-prefixed names (e.g., ruby_*).
  • Non-destructive: no deletes/renames on customer data.
  • Only attempt on eligible (Enterprise) portals; otherwise fall back.

App details available on request (App ID, volumes, etc.).
Would appreciate guidance on enabling this or the recommended path forward. Thanks!

Hi @sherjeelfpl
Thank you for reaching out to the Community!
I’d like to invite some community members who are subject matter experts to join this conversation.
@zach_threadint @TomM2 @GiantFocal - Would you be able to share any insights on this? Your expertise would be greatly appreciated.
Best,
Victor

Hi @sherjeelfpl :waving_hand:

In order for a public app to gain access to HubSpot’s custom object API scopes, you need to go through an approval process. More info can be found here: Custom Objects OAuth Access

I hope this proves helpful. Please let me know if you have any follow-up questions.