The Toolkit take
16
Webhook event types in SavvyCal's developer docs, each signed with HMAC SHA-256.
2 hours
OAuth access token lifetime
29
API operations, by our count
595
zones in the free Time Zone API

What the SavvyCal API covers, and what it leaves out

SavvyCal gives developers three ways in: a REST API, webhooks and a JavaScript embed library. This guide covers the first two. The REST API speaks JSON, lives at api.savvycal.com and sits at version 1.0.0, with every endpoint under a /v1 path. The developer docs call the product SavvyCal Meetings and its interface the SavvyCal Meetings API, and the reference can be exported as an OpenAPI spec, which saves you from writing a client by hand. The API is additive: SavvyCal says new fields may appear in existing payloads, so your parser should ignore keys it does not know rather than fail on them.

The reference is split into seven groups: Events (7 items), Scheduling Links (10), Current User (1), Time Zones (3), Webhooks (5), Workflows (3) and Schemas (45) [1]. That is 29 operations in all, by our arithmetic. It is a small, tidy surface. There is no group for meeting polls or for contacts, even though both exist in the app. Lists use cursor pagination with after and before cursors and a per-page limit, and validation errors come back keyed by field name, which makes form errors easy to map. If you only need to embed a booking page rather than call the API, start with our SavvyCal embed guide instead.

Authentication: personal tokens or OAuth 2

There are two ways to authenticate. Personal access tokens are for scripts that act on your own account. You create one in the Developer Settings of the SavvyCal app, and it looks like pt_secret_ followed by a long string. You send it as a Bearer token in the Authorization header, and the docs use GET /v1/me as the first test call. One small inconsistency: the raw HTTP example on the same page drops the /v1 prefix, while the cURL example keeps it. Use the /v1 form, which matches the rest of the reference. The authentication page names no plan requirement for creating a token.

OAuth 2 is for integrations that act on behalf of other SavvyCal users. It is the standard authorization code flow, with /oauth/authorize and /oauth/token endpoints. Access tokens are short-lived: the token response sets expires_in to 7200 seconds, which is two hours, and you refresh with a long-lived refresh token posted to savvycal.com/oauth/token [2]. Any user can register an OAuth application under Settings, then Developers, by giving it a name and redirect URIs. You get a client ID and a client secret back. Plan your token storage around that two-hour window. A background job that runs nightly will need to refresh first, every time.

💡
Toolkit tip
Fetch slots before you book

An event created through the API must match an available slot on the link. Call the slots endpoint first, then book one of the times it returns.

Events: reading, booking and canceling meetings

In the API, an event is a meeting scheduled through SavvyCal. GET /v1/events returns a paginated list, GET /v1/events/:event_id returns one event with its attendees, and POST /v1/events/:event_id/cancel cancels it with an optional reason. The event object is rich. It carries one of eight states (confirmed, canceled, awaiting reschedule, awaiting checkout, checkout expired, awaiting approval, declined and tentative), the organizer and the scheduler as separate records, buffers before and after in minutes, location settings, a reschedule reason and conferencing details such as the join URL. Group sessions show a maximum group size, and each attendee record has a marketing opt-in flag and an optional phone number.

Booking a meeting through the API

The most useful call for product builders is POST /v1/links/:link_id/events, which books a meeting on an existing scheduling link. The time must match an available slot on that link, so the normal pattern is to fetch slots first and then book one. The request needs ISO-8601 start and end times and the scheduler's time zone. A phone number is optional unless the link has the always-gather-phone option switched on. You can also pass custom field values and a metadata object.

One warning matters for video calls. With some conferencing providers, Zoom among them, the meeting details are not guaranteed in the create response. If the room cannot be created at once, SavvyCal retries and attaches the details to the event later, so read them from a later fetch or a webhook. The event.changed webhook, covered below, is the natural place to catch that update, since it fires on any change to an event and includes its previous attributes.

Paid events

Paid bookings run through Stripe. The payment sub-object holds the amount in cents and a state of awaiting checkout or paid, and it links to the payment page in the Stripe dashboard only after checkout completes. Keep in mind that paid bookings are a Premium plan feature on the pricing page, so an integration that reads payments needs a Premium account on the other side.

Curious how SavvyCal feels in practice?Try SavvyCal →

The Scheduling Links group is the largest, with ten operations. You can list your links (paginated), fetch one by ID, create a link in your personal scope with POST /v1/links or under a team with POST /v1/scopes/:scope_slug/links, update it with PATCH /v1/links/:link_id, duplicate it, delete it, and switch it between active and disabled with POST /v1/links/:link_id/toggle. A link is either Multi-Use (recurring, the default) or Single-Use, can carry a private name that schedulers never see, can offer several durations, and has a slot increment in minutes. Its state is active, pending or disabled. Custom booking fields support text, email, phone, textarea, select, radio and checkbox types.

Slots come with ranks

GET /v1/links/:link_id/slots returns the bookable times, and for a link with several durations it returns slots for each one. The interesting detail is the rank. Ranked availability is a feature SavvyCal promotes on its own booking pages, and the API exposes it: rank 1 slots are the organizer's most preferred times, and higher ranks are cumulative, so rank 2 includes every rank 1 time plus more. A custom booking interface can therefore show the preferred times first and reveal the rest on request, much as SavvyCal's pages present preferred windows in order. It costs nothing extra. Use it.

Webhooks: 16 event types, signed and retried

Webhooks send an HTTP POST to your endpoint when something changes in a SavvyCal account. You can register one in the app under Settings, then Integrations (the plus icon), or through the API, where creating a webhook needs only the endpoint URL. The Webhooks API lets you list, create, get and delete webhooks. There is no update operation, so changing an endpoint means deleting and recreating it. Each webhook has its own ID, URL, secret and state (active, disabled or deleted), plus a payload version string. The docs show two different example versions, 2020-11-18 and 2024-01-15, and do not describe a version policy, so log the version you receive.

Which events fire

The developer docs list 16 event types [3]. The help center and changelog list fewer, so trust the developer reference. The core set covers the booking life cycle: event.created, event.rescheduled, event.changed (which includes the previous attributes) and event.canceled. Approval flows add event.requested, event.approved and event.declined. Paid links add event.checkout.pending, event.checkout.completed and event.checkout.expired. Group events add event.attendee.added, event.attendee.canceled and event.attendee.rescheduled, where the reschedule payload carries both the original and the new event. Meeting polls fire poll.response.created and poll.response.updated, and workflows fire workflow.action.triggered.

Receiving and verifying them

Deliveries go over HTTPS. Each one is signed with an HMAC SHA-256 signature of the request body, using a secret unique to that webhook, and sent in the x-savvycal-signature header. Verify it before you trust the payload. The only verification example in the docs is written in Elixir, so developers in other languages will translate it themselves. Your endpoint should answer quickly with a 200 OK. On any non-2xx response, SavvyCal retries with exponential backoff, which means a slow handler can receive the same event twice. Make your handler idempotent by keying on the event ID, and do the heavy work in a queue after you reply.

⚠️
Watch out
Retries can repeat deliveries

SavvyCal retries any non-2xx webhook response with exponential backoff. Reply 200 OK quickly and make your handler safe to run twice.

Metadata, UTM tags and Zapier

Metadata is the glue between your site and SavvyCal. You can attach custom properties to an event through the link's query string or through the embed, and read them back from webhooks or the API. The API's create-event call accepts metadata too. SavvyCal also stores UTM parameters appended to a scheduling link in the event metadata, and exposes them through webhooks, the REST API and Zapier. That makes it possible to tie a booked call back to the campaign or the account record it came from, without asking the scheduler an extra question.

For teams that would rather not write code, the native Zapier integration offers three triggers: New Event, Rescheduled Event and Canceled Event. They can fire for every link you can access or only for a chosen set. Group scheduling has its own attendee triggers, and the help center recommends New Event Attendee for group events, because New Event arrives with empty scheduler data there. Workflows can also trigger Zapier automations at points around the meeting. Slack has a native integration that posts to channels on bookings, reschedules and cancellations. For the full list of native connections, see our SavvyCal integrations guide.

Time zones, workflows and the current user

The three smaller groups are quick to describe. The Current User resource represents whoever is making the request, which matters once OAuth is involved, because the same code then runs as many different people. GET /v1/me returns the profile of the authenticated user, and the User object reports the subscription plan as free, basic or premium. That field is handy for an integration that needs to warn users when a feature, such as paid bookings, is out of reach on their plan.

The Workflows group is read-only. It lists workflows for the scopes you manage and lists the rules of one workflow with GET /v1/workflows/:workflow_id/rules. A workflow is active, disabled or draft. Its rules fire on event created, event started or event ended, with an offset before or after in minutes, hours or days, and its actions either send a custom email or trigger an automation. You cannot create or edit workflows through the API. You can only inspect them.

The Time Zones group lists zones with localized names and daylight saving data, and fetches a single zone. Each zone reports whether its ID is canonical in IANA, whether daylight saving time is active, its current offset from UTC in seconds, and whether it is the CLDR golden zone of its metazone. Where no CLDR name exists, SavvyCal falls back to Microsoft Windows names. SavvyCal also publishes a free Time Zone API covering 595 zones built from IANA and Unicode CLDR data, with human-friendly names, UTC offsets and exemplar cities. It is useful well beyond scheduling.

Ready to put SavvyCal to the test?Try SavvyCal →

The gaps to plan around

The API is clean, but a few things are missing or unstated. Polls and contacts have no endpoints. The schema list includes Poll and PollResponse objects and the poll webhooks work, but you cannot list or create polls through the reference, and the contact records added in February 2026 are not exposed at all. Workflows are read-only, and webhooks cannot be updated. The docs publish no rate limits, so build in backoff from the start. They also state no plan requirement. The pricing page shows API and webhooks on both paid plans, Basic and Premium [4]. Basic is $12 per user a month billed monthly, or $10 billed annually.

That plan note matters because there is no free scheduling plan. Anyone can create a free account and use meeting polls, but booking links only go live on a paid plan, so a real integration needs at least Basic. The rivals are more explicit. Calendly publishes its rate limit, 50 requests per user per minute on its free plan, and keeps its Scheduling API for paid plans. Cal.com lists more than 20 webhook triggers, an API v2 and OAuth with scopes. TidyCal has no webhooks at all.

💡
Toolkit tip
Carry context in metadata

Attach custom metadata or UTM parameters to a booking and read them back from webhooks, the API or Zapier to tie each meeting to its source.

SavvyCal Appointments is a different product

On its site SavvyCal also shows SavvyCal Appointments, which is easy to confuse with this API. It is a separate scheduling-infrastructure product for in-house teams and agencies, sold through a demo and rolling out only to select agency partners and SaaS businesses. Its API covers appointments, service slots, providers, reschedules, cancellations and blocks, alongside webhooks, a REST API, an embeddable booking widget and an admin dashboard. It also claims HIPAA compliance, which conflicts with the main SavvyCal Terms, which forbid protected health information. Treat that claim as applying to Appointments only, and confirm it in writing before relying on it. Nothing in this guide applies to Appointments.

Frequently asked questions

Does SavvyCal have an API?+

Yes. A REST API v1 at api.savvycal.com covers events, scheduling links, the current user, time zones, webhooks and read-only workflows, and the reference can be exported as an OpenAPI spec.

How do I authenticate with the SavvyCal API?+

Use a personal access token from Developer Settings as a Bearer token for your own account, or OAuth 2 for integrations acting for other users. OAuth access tokens last two hours and are renewed with a refresh token.

Which webhooks does SavvyCal send?+

The developer docs list 16 event types, covering bookings, reschedules, changes, cancellations, approvals, paid checkouts, group attendees, poll responses and workflow actions.

Can I book a meeting through the SavvyCal API?+

Yes, with POST /v1/links/:link_id/events. The time must match an available slot on that link, so list the slots first.

Does the SavvyCal API have rate limits?+

The docs do not publish any. Build in backoff and retries from the start.

Do I need a paid plan to use the SavvyCal API?+

The docs state no plan requirement, but the pricing page lists API and webhooks on the paid Basic and Premium plans, and booking links only go live on a paid plan.

The bottom line

The SavvyCal API is small, consistent and well suited to its main jobs: booking on a link from your own interface, reading events into a CRM or warehouse, and reacting to 16 signed webhook events in near real time. Ranked slots and event metadata are the standout details. The limits are real, though. Polls and contacts have no endpoints, workflows are read-only, rate limits are unpublished and every live link needs a paid plan. For a sales or product team that wants scheduling data flowing into its own systems, it is enough. For a deep, two-way automation, check the gaps first.

Sources
  1. [1] SavvyCal Developers: category / rest api (2026-10) https://developers.savvycal.com/category/rest-api
  2. [2] SavvyCal Developers: authentication (2026-10) https://developers.savvycal.com/authentication
  3. [3] SavvyCal webhooks docs (2026-10) https://developers.savvycal.com/webhooks
  4. [4] SavvyCal pricing page (2026-10) https://savvycal.com/pricing