Public scheduling API
The public scheduling API lets external requesters list visible meeting types and submit booking proposals through a public scheduling link.
Use it when you are building a requester-side integration, MCP tool, or partner workflow. If you are configuring links for calendar owners, the admin dashboard is the recommended control surface.
Overview
There are two API surfaces:
| Surface | Base path | Who uses it |
|---|---|---|
| Public requester API | /public/... | Anonymous or verified external requesters. |
| Admin public scheduling API | /v1/public-scheduling/... | Authenticated admin dashboard and admin clients. |
Requester APIs never return private calendar details, hidden meeting types, internal proposal IDs, audit rows, or raw availability.
Authentication
Anonymous public scheduling does not require credentials.
Verified requester flows may include an optional requester credential:
Authorization: Bearer rc_1234abcd_...
Requester credentials prove external requester identity. They do not grant calendar access and do not replace owner policy.
Admin public scheduling APIs require an authenticated dashboard admin session. In personal accounts, the calendar owner is also the admin. In workspace accounts, non-admin members cannot list or mutate these configuration records in beta.
Public endpoints
| Endpoint | Purpose |
|---|---|
| GET /public/schedules/{id}/meeting-types | List meeting types visible to the requester. |
| POST /public/schedules/{id}/booking-proposals | Submit a public booking proposal. |
| GET /public/booking-proposals/{token} | Poll the safe public status for a request. |
| POST /public/contact-verifications/{token}/confirm | Confirm the requester contact email. |
| POST /public/booking-proposals/{token}/withdraw | Withdraw a pending request. |
{id} can be the public scheduling ID or the readable alias path used by the public URL.
Admin endpoints
The admin API backs the dashboard:
| Endpoint | Purpose |
|---|---|
GET /v1/public-scheduling/boundaries | List public links. |
POST /v1/public-scheduling/boundaries | Create a public link for one calendar owner. |
PATCH /v1/public-scheduling/boundaries/{boundary_id} | Update link path, free-text policy, or status. |
GET /v1/public-scheduling/boundaries/{boundary_id}/meeting-types | List meeting types on a link. |
POST /v1/public-scheduling/boundaries/{boundary_id}/meeting-types | Create or publish a public meeting type. |
PATCH /v1/public-scheduling/meeting-types/{meeting_type_id} | Update meeting type policy or status. |
GET /v1/public-scheduling/verified-domains | List DNS verification challenges. |
POST /v1/public-scheduling/verified-domains | Create a DNS verification challenge. |
POST /v1/public-scheduling/verified-domains/{id}/check | Re-check DNS verification. |
DELETE /v1/public-scheduling/verified-domains/{id} | Remove an unused domain. |
GET /v1/public-scheduling/requester-identities | List requester identities. |
POST /v1/public-scheduling/requester-identities | Create a requester identity. |
GET /v1/public-scheduling/requester-identities/{id}/credentials | List credential metadata. |
POST /v1/public-scheduling/requester-identities/{id}/credentials | Issue a one-time requester credential secret. |
POST /v1/public-scheduling/requester-credentials/{id}/revoke | Revoke a requester credential. |
GET /v1/public-scheduling/requester-audiences | List audiences. |
POST /v1/public-scheduling/requester-audiences | Create an audience. |
POST /v1/public-scheduling/requester-audiences/{id}/members | Add a domain, identity, or pending domain to an audience. |
GET /v1/public-scheduling/meeting-types/{meeting_type_id}/allocations | List allocations for a meeting type. |
POST /v1/public-scheduling/meeting-types/{meeting_type_id}/allocations | Create an allocation. |
PATCH /v1/public-scheduling/allocations/{allocation_id} | Update or disable an allocation. |
GET /v1/public-scheduling/security-events | List public scheduling security and abuse events. |
These endpoints use internal resource names like boundary because they mirror the API and database model. The dashboard translates that to public link for admins configuring owner-facing links.
Security events
Admins can inspect public scheduling abuse and policy events with:
GET /v1/public-scheduling/security-events
Optional filters:
| Query | Meaning |
|---|---|
boundary_id | Limit to one public link. |
event_type | Limit to one event type. |
reason | Limit to one reason. |
from / to | ISO 8601 time range. |
cursor | Continue pagination. |
page_size | Number of rows to return. |
Rows include the event type, reason, related public link, meeting type, requester identity, verified domain, IP hash, user agent, and metadata. They are admin-visible operational signals, not requester-facing status.
Suggested times
GET /public/schedules/{id}/meeting-types can return suggested_times on visible meeting types:
{
"public_meeting_type": "intro-call",
"name": "Intro call",
"duration_minutes": 30,
"suggested_times": [
{
"start": "2026-07-08T14:00:00.000Z",
"end": "2026-07-08T14:30:00.000Z",
"rank": 1,
"source": "allocation"
}
]
}
Suggested times are not holds. Submit the chosen start/end inside requested_window; Openavail rechecks availability before accepting the request.
Status and withdrawal
A successful public proposal response includes a status_url. Anonymous proposals may also include a contact_verification_url.
Safe public statuses include:
| Status | Meaning |
|---|---|
pending_review | Waiting for owner review. |
pending_requester_verification | Waiting for contact confirmation. |
booked | The request became a booking. |
rejected | The owner or policy rejected it. |
expired | The request expired. |
withdrawn | The requester withdrew it. |
countered | The owner asked for a different path forward. |
needs_more_information | The owner needs more requester context. |
Requesters can withdraw while the request is still pending review or pending requester verification.
Errors
Public scheduling errors use the normal Openavail error envelope:
{
"error": {
"code": "attendee_limit_exceeded",
"message": "Attendee limit is 1"
},
"pending_notifications": []
}
See Error codes for public scheduling-specific error codes.