Which scope authorizes POST /scheduler/v3/meetings/meeting-links/book for a public app?

I’m building a public OAuth app, and I can’t work out how to authorize the scheduler booking endpoint.

What works:

GET /scheduler/v3/meetings/meeting-links → 200

with scheduler.meetings.meeting-link.read granted. So the token is valid and the scheduler scope is live.

What doesn’t:

POST /scheduler/v3/meetings/meeting-links/book → 403
{
“status”: “error”,
“message”: “The scope needed for this API call isn’t available for public use. If you have questions, contact support or post in our developer forum.”,
“category”: “MISSING_SCOPES”
}
correlationId: 019ff6cb-99c7-73fd-93de-fb2dd217507e

The thing I’m stuck on is that the category is MISSING_SCOPES but no scope is named. When I was missing the read scope, the same category came back with context.requiredGranularScopes: [“scheduler.meetings.meeting-link.read”], which told me exactly what to add. The booking endpoint names nothing.

So my questions:

  1. Which scope authorizes POST /scheduler/v3/meetings/meeting-links/book?
  2. Can a marketplace app be granted it, and if so what’s the process?
  3. If it isn’t grantable to public apps, is there any supported way for an
    app to book against a customer’s scheduling page on their behalf?

Hi there @letsbuildmyapp,

Thank you for posting to the Community!

I’d like to tag in some of our Top Contributors to see if they have experienced this before – Hi @Mike_Eastwood @ChristinaKay and @Gonzalo do any of you all have any ideas?

Cassie, Community Manager

Hello @letsbuildmyapp

Typically, POST is used for writing data to the API but your scopes say that you’ve got a read scope not a write scope.

If you are trying to read from the API, I would use a GET rather than a POST.

What are you trying to achieve with your app?
Curiously
Mike

You’re right that POST is a write and that I only hold the read scope. That’s exactly what I’m stuck on. I’d happily add the write scope, I justcan’t find one that exists.

There’s no scheduler write scope in the scopes reference. The only one listed is scheduler.meetings.meeting-link.read. And when I put candidate names in my app config, the project build rejects every one of them as unrecognized:

scheduler.meetings.meeting-link.write
scheduler.meetings.meeting-link.book
scheduler.meetings.write
scheduler.meetings.book
scheduler

So my question is really just: what is the write scope called? Give me the exact string and I’ll add it and be on my way.

The reason I suspect it isn’t grantable at all is the error itself. When I was missing the read scope, HubSpot told me precisely what to add:

“category”: “MISSING_SCOPES”,
“context”: { “requiredGranularScopes”: [“scheduler.meetings.meeting-link.read”] }

The booking endpoint returns that same MISSING_SCOPES category but names nothing, and the message says the scope “isn’t available for public use”. That reads like an internal scope rather than one I’ve failed to request.

You’re right that POST is a write and that I only hold the read scope. That’s exactly what I’m stuck on. I’d happily add the write scope, I just can’t find one that exists.

There’s no scheduler write scope in the scopes reference. The only one listed is scheduler.meetings.meeting-link.read. And when I put candidate names in my app config, the project build rejects every one of them as unrecognized:

scheduler.meetings.meeting-link.write
scheduler.meetings.meeting-link.book
scheduler.meetings.write
scheduler.meetings.book
scheduler

So my question is really just: what is the write scope called? Give me the exact string and I’ll add it and be on my way.

The reason I suspect it isn’t grantable at all is the error itself. When I was missing the read scope, HubSpot told me precisely what to add:

“category”: “MISSING_SCOPES”,
“context”: { “requiredGranularScopes”: [“scheduler.meetings.meeting-link.read”] }

The booking endpoint returns that same MISSING_SCOPES category but names nothing, and the message says the scope “isn’t available for public use”. That reads like an internal scope rather than one I’ve failed to request.

The meeting link is a read-only endpoint. Which is why there’s only scopes to read, not write.

What’s your actual goal with this project?

If you want to add a meeting to a contact record, then you could use the engagements API documented here:

Have fun
Mike

Thanks Mike, that’s helpful, and it matches what I’m seeing.

The goal is narrower than logging a meeting. When a prospect replies to one of our emails and says “Tuesday at 2 works,” we want to reserve that time on our customer’s real calendar and send the prospect an invite, same as hitting a slot on their public booking page. Calendly has a book endpoint that does exactly this, so the flow already works there and I was hoping to offer HubSpot customers the same thing.

The engagements API is where I landed first too, but as far as I can tell it creates the activity record on the contact without creating an actual calendar event or inviting the prospect. So the meeting shows up in the CRM and nobody’s calendar knows about it, and the prospect never gets anything. Happy to be wrong about that if there’s a flag I missed.

Is there any path for an ISV to get write access to bookings, through the partner program or a support request, or is it permanently off the table for public apps?

Best,
Alex

Hi @letsbuildmyapp I ran into the same thing. What’s happening here is that the “scope needed for this API call isn’t available for public use” message is different from a normal MISSING_SCOPES error — when you’re actually missing a scope, HubSpot names it in requiredGranularScopes. When it comes back with no scope named, it means that capability is gated off from public/OAuth apps entirely, not that you forgot to add something to your scope list.

This same pattern has shown up for custom object schema creation too — public apps get blocked the same way, and the only way through is a separate approval process with HubSpot (similar to the custom-objects-schema-pilot), not something you can self-serve from the app settings.

So for booking meetings specifically:

  • There’s no publicly documented scope you can just add for POST /scheduler/v3/meetings/meeting-links/book on a public app.
  • To get it enabled, you’d need to go through HubSpot Developer Support directly and request access for that endpoint, referencing your correlationId.
  • As a workaround in the meantime, instead of calling the booking endpoint server-side, redirect the end user to the actual meeting link/scheduling page URL and let them book through HubSpot’s own page — that doesn’t require the restricted scope at all since it’s just a page visit, not an API call.

This is perfect. Thank you for the clarification. I figured I’d have to get a special approval but no one was telling me that. Thank you!