Tempi API API

Scheduling API. Public operations let anyone, including AI assistants, look up open times and book a meeting. Account operations need an API key (`Authorization: Bearer bk_...`) from Settings → API keys in the web app. Times are ISO 8601 and returned in UTC. A `timezone` input sets how dates are rea

Operations 74

GET /api/v1/public/{handle} List a person's or team's event types #
GET /api/v1/public/{handle}/{slug}/slots Find open times #
GET /api/v1/public/{handle}/{slug}/series Check a repeating series before booking it #
GET /api/v1/public/{handle}/{slug}/check Check a time is still open before booking it #
POST /api/v1/public/{handle}/{slug}/bookings Book a meeting #
GET /api/v1/public/bookings/{id} View a booking (invitee) #
POST /api/v1/public/bookings/{id}/reschedule Reschedule a booking (invitee) #
POST /api/v1/public/bookings/{id}/cancel Cancel a booking (invitee) #
GET /api/v1/public/review/{id} View a request from its email link (host) #
POST /api/v1/public/review/{id} Approve or decline a request from its email link (host) #
POST /api/v1/waitlist Join the private beta waitlist #
GET /api/v1/me Get the current account #
PATCH /api/v1/me Update your profile #
POST /api/v1/me/video Set your video call #
POST /api/v1/me/onboarding Finish first-run setup #
GET /api/v1/availability Get working hours #
POST /api/v1/availability Replace weekly hours #
GET /api/v1/availability/preview See your next days as people booking you see them #
GET /api/v1/me/open-times Check that your booking pages have open times #
PATCH /api/v1/availability/limits Cap meetings per day or week #
POST /api/v1/availability/overrides Set hours for a specific date #
DELETE /api/v1/availability/overrides/{date} Remove a date override #
GET /api/v1/teams List your teams #
POST /api/v1/teams Create a team #
GET /api/v1/teams/{team} Get a team #
PATCH /api/v1/teams/{team} Update a team #
DELETE /api/v1/teams/{team} Delete a team #
POST /api/v1/teams/{team}/members Add a team member #
POST /api/v1/teams/{team}/invites/resend Email an invite again #
PATCH /api/v1/teams/{team}/members/{userId} Change a member's role #
DELETE /api/v1/teams/{team}/members/{member} Remove a member or invite #
GET /api/v1/teams/{team}/shared-hours Check when hosts all work #
GET /api/v1/event-types List event types #
POST /api/v1/event-types Create an event type #
PATCH /api/v1/event-types/{id} Update an event type #
POST /api/v1/event-types/{id}/archive Archive an event type #
POST /api/v1/event-types/{id}/restore Restore an archived event type #
GET /api/v1/event-types/{id}/availability Explain why times can or can't be booked #
POST /api/v1/event-types/preview-times Try event type settings before saving #
GET /api/v1/bookings List bookings #
GET /api/v1/bookings/{id} View a booking (host) #
POST /api/v1/bookings/{id}/reschedule Reschedule a booking (host) #
POST /api/v1/bookings/{id}/cancel Cancel a booking (host) #
POST /api/v1/bookings/{id}/approve Approve a booking request #
POST /api/v1/bookings/{id}/decline Decline a booking request #
POST /api/v1/bookings/{id}/calendar Retry a booking’s calendar event #
GET /api/v1/calendars List connected calendars #
POST /api/v1/calendars/apple Connect iCloud Calendar #
POST /api/v1/calendars/{id}/booking Choose the booking calendar #
DELETE /api/v1/calendars/{id} Disconnect a calendar #
GET /api/v1/api-keys List API keys #
POST /api/v1/api-keys Create an API key #
DELETE /api/v1/api-keys/{id} Revoke an API key #
GET /api/v1/teams/{team}/webhooks List webhooks #
POST /api/v1/teams/{team}/webhooks Add a webhook #
POST /api/v1/webhooks/{id}/test Test a webhook #
DELETE /api/v1/webhooks/{id} Remove a webhook #
GET /api/v1/teams/{team}/webhooks/sample Sample webhook events #
GET /api/v1/connected-apps List connected AI assistants #
DELETE /api/v1/connected-apps/{id} Disconnect an AI assistant #
GET /api/v1/teams/{team}/billing Get a team's plan #
POST /api/v1/teams/{team}/billing/seen Count a look at the Team plan card #
POST /api/v1/teams/{team}/billing/interest Say whether you'd pay for the Team plan #
GET /api/v1/admin/waitlist List the waitlist (admin) #
POST /api/v1/admin/waitlist/decide Approve or reject waitlist requests (admin) #
GET /api/v1/insights Get product analytics (admin) #
GET /api/v1/insights/features Get who uses which feature (admin) #
GET /api/v1/covers List painted covers #
GET /api/v1/admin/covers List every cover, for the cover maker (admin) #
GET /api/v1/admin/covers/sources Search the museums for paintings to make a cover from (admin) #
GET /api/v1/admin/covers/gaps What hosts need covers for (admin) #
POST /api/v1/admin/covers/{id}/hidden Hide or show a cover (admin) #
GET /api/v1/addresses Suggest addresses for an in-person event type #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/meettempi-com:tempi-api-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

meettempi-com-api-openapi.json Raw ↑
{"openapi":"3.1.0","info":{"title":"Tempi API","version":"1.0.0","description":"Scheduling API. Public operations let anyone, including AI assistants, look up open times and book a meeting. Account operations need an API key (`Authorization: Bearer bk_...`) from Settings → API keys in the web app. Times are ISO 8601 and returned in UTC. A `timezone` input sets how dates are read and how slots are grouped by day."},"servers":[{"url":"https://meettempi.com"}],"paths":{"/api/v1/public/{handle}":{"get":{"operationId":"get_public_profile","summary":"List a person's or team's event types","description":"Takes a handle, the first path segment of a booking link (https://host/acme/demo → \"acme\"), or the link itself. Returns the person or team and their bookable event types, with duration, price, and hosts with their time zones (`hostTimezones`, so you can say what time a slot is for them). A handle from before a rename also works. Next: call get_available_slots with one of the event type slugs.","tags":["public"],"security":[],"parameters":[{"name":"handle","in":"path","required":true,"schema":{"type":"string","description":"a handle, the first part of a booking link (\"acme\" in meettempi.com/acme/demo), or the whole link"}}],"responses":{"200":{"description":"Success","content":{"application/json":{}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/public/{handle}/{slug}/slots":{"get":{"operationId":"get_available_slots","summary":"Find open times","description":"Returns the start times that can be booked, with the hosts' calendars, buffers and limits already applied. Pass the invitee's `timezone` and either `date` (YYYY-MM-DD in `timezone`) or `from` and `to` (ISO, at most 62 days apart). With neither, it covers the next 7 days. `days` groups the slots by date in `timezone`, and `times` gives each slot as a local time to show people. People can book up to `bookableUntil`. When the range has no open times, `next` is the next one. When `timezone` was an abbreviation that names more than one zone (CST, IST, BST), `timezoneNote` says which one was used: check it with the person. For new times for an existing booking, also pass its `bookingId` and `token`. Next: call create_booking (or reschedule_booking_as_invitee) with one of the `slots` values as `start`.","tags":["public"],"security":[],"parameters":[{"name":"handle","in":"path","required":true,"schema":{"type":"string","description":"a handle, the first part of a booking link (\"acme\" in meettempi.com/acme/demo), or the whole link"}},{"name":"slug","in":"path","required":true,"schema":{"type":"string","description":"an event type slug from get_public_profile (\"demo\" in meettempi.com/acme/demo), or the whole link"}},{"name":"timezone","in":"query","required":true,"schema":{"type":"string","description":"the invitee's time zone, an IANA id like America/New_York or an abbreviation like EST: days, dates and times are in it"}},{"name":"date","in":"query","required":false,"schema":{"type":"string","format":"date","description":"one day to look at, as YYYY-MM-DD in `timezone`"}},{"name":"from","in":"query","required":false,"schema":{"type":"string","format":"date-time","description":"start of the range, ISO with an offset"}},{"name":"to","in":"query","required":false,"schema":{"type":"string","format":"date-time","description":"end of the range, ISO with an offset"}},{"name":"bookingId","in":"query","required":false,"schema":{"type":"string","description":"the booking id from create_booking, or its manageUrl"}},{"name":"token","in":"query","required":false,"schema":{"type":"string","description":"the token from create_booking, or the manageUrl"}}],"responses":{"200":{"description":"Success","content":{"application/json":{}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/public/{handle}/{slug}/series":{"get":{"operationId":"check_series","summary":"Check a repeating series before booking it","description":"For event types with `repeatMax` (from get_public_profile): lists each meeting of a series that starts at `start` (one of the slots) and repeats `every` 1, 2 or 4 weeks at the host's clock time, and whether each is free. Pass the invitee's `timezone` to get each meeting's `when` in it: where clocks change on other dates than the host's, some meetings move for the invitee, and `message` says which. Book it with create_booking and `repeat` when `bookable` is true. A series is booked whole or not at all, and round robin gives every meeting to the same host.","tags":["public"],"security":[],"parameters":[{"name":"handle","in":"path","required":true,"schema":{"type":"string","description":"a handle, the first part of a booking link (\"acme\" in meettempi.com/acme/demo), or the whole link"}},{"name":"slug","in":"path","required":true,"schema":{"type":"string","description":"an event type slug from get_public_profile (\"demo\" in meettempi.com/acme/demo), or the whole link"}},{"name":"start","in":"query","required":true,"schema":{"type":"string","format":"date-time","description":"one of the `slots` values from get_available_slots, as given (ISO in UTC)"}},{"name":"every","in":"query","required":true,"schema":{"anyOf":[{"type":"number","enum":[1,2,4],"description":"weeks between meetings: 1, 2 or 4"},{"type":"string","description":"a string to be decoded into a number"}],"description":"weeks between meetings: 1, 2 or 4"}},{"name":"count","in":"query","required":true,"schema":{"anyOf":[{"type":"integer","description":"how many meetings, first included (2 up to the event type's repeatMax)","title":"between(2, 52)","minimum":2,"maximum":52},{"type":"string","description":"a string to be decoded into a number"}],"description":"how many meetings, first included (2 up to the event type's repeatMax)"}},{"name":"timezone","in":"query","required":false,"schema":{"type":"string","description":"the invitee's time zone, an IANA id like America/New_York or an abbreviation like EST: each meeting's `when` is in it"}}],"responses":{"200":{"description":"Success","content":{"application/json":{}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/public/{handle}/{slug}/check":{"get":{"operationId":"check_time","summary":"Check a time is still open before booking it","description":"Whether `start` (one of the slots) is still open. The booking page calls it while the invitee fills in the form: it reads the hosts' calendars again, so the booking itself needn't wait on them. Agents can call create_booking directly.","tags":["public"],"security":[],"parameters":[{"name":"handle","in":"path","required":true,"schema":{"type":"string","description":"a handle, the first part of a booking link (\"acme\" in meettempi.com/acme/demo), or the whole link"}},{"name":"slug","in":"path","required":true,"schema":{"type":"string","description":"an event type slug from get_public_profile (\"demo\" in meettempi.com/acme/demo), or the whole link"}},{"name":"start","in":"query","required":true,"schema":{"type":"string","format":"date-time","description":"one of the `slots` values from get_available_slots, as given (ISO in UTC)"}}],"responses":{"200":{"description":"Success","content":{"application/json":{}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/public/{handle}/{slug}/bookings":{"post":{"operationId":"create_booking","summary":"Book a meeting","description":"Books `start`, which must be one of the `slots` from get_available_slots. Free events are confirmed at once, unless the event type has `requiresApproval`: then it's a request (status=pending_approval) that holds the time until a host approves or declines it, and the invitee hears either way by email. Nobody answering by its start (`holdExpiresAt`) lets it lapse. Tell the human it isn't confirmed yet. Paid events return status=pending_payment and a `paymentUrl`. Give it to the human to pay before `holdExpiresAt`, or the slot is released. Once confirmed, the event is added to the host's calendar if they connected one, and the invitee gets a confirmation email with a calendar file (.ics). Keep `manageUrl` and `token`: they are the only way to view, reschedule or cancel later. 409 slot_unavailable says why the time can't be booked and lists the `nearest` open times. The result's `when` is the start in the invitee's time zone, to tell them.","tags":["public"],"security":[],"parameters":[{"name":"handle","in":"path","required":true,"schema":{"type":"string","description":"a handle, the first part of a booking link (\"acme\" in meettempi.com/acme/demo), or the whole link"}},{"name":"slug","in":"path","required":true,"schema":{"type":"string","description":"an event type slug from get_public_profile (\"demo\" in meettempi.com/acme/demo), or the whole link"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"start":{"type":"string","format":"date-time","description":"one of the `slots` values from get_available_slots, as given (ISO in UTC)"},"name":{"type":"string","description":"the invitee's full name"},"email":{"type":"string","format":"email","description":"the invitee's email address, which gets the confirmation and its calendar file"},"timezone":{"type":"string","description":"the invitee's time zone, an IANA id like America/New_York or an abbreviation like EST: their emails and reminders show times in it"},"notes":{"type":"string","description":"anything the invitee wants the host to know","title":"maxLength(2000)","minLength":0,"maxLength":2000},"phone":{"type":"string","description":"the invitee's phone number with its country code, like +1 415 555 0134: required when the event type is a phone call (whereKind phone on get_public_profile), where the host calls them","title":"maxLength(40)","minLength":0,"maxLength":40},"repeat":{"type":"object","required":["every","count"],"properties":{"every":{"type":"number","enum":[1,2,4],"description":"weeks between meetings: 1, 2 or 4"},"count":{"type":"integer","description":"how many meetings, first included (2 up to the event type's repeatMax)","title":"between(2, 52)","minimum":2,"maximum":52}},"additionalProperties":false,"description":"book a series instead: `count` meetings, `every` 1, 2 or 4 weeks at the host's clock time, when the event type's repeatMax allows. All or nothing: check_series first. The result's `series.meetings` give each start as `when` in the invitee's time zone, and `series.clockNote` says when that moves"},"cover":{"type":"string","description":"leave it out: the id of the painting the booking page showed, when the event type shows a different one each booking (cover \"hand\", \"light\" or \"still\"), so the booking keeps it. Anything else is ignored, and Tempi picks one","title":"maxLength(40)","maxLength":40}},"required":["start","name","email","timezone"]}}}},"responses":{"201":{"description":"Success","content":{"application/json":{}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/public/bookings/{id}":{"get":{"operationId":"get_booking","summary":"View a booking (invitee)","description":"Returns a booking by its id and token (from create_booking), or its manageUrl passed as both, with `changeableUntil`, `refundableUntil` and `canCancel`. For a series, `series` lists every meeting with its own manageUrl.","tags":["public"],"security":[],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","description":"the booking id from create_booking, or its manageUrl"}},{"name":"token","in":"query","required":true,"schema":{"type":"string","description":"the token from create_booking, or the manageUrl"}}],"responses":{"200":{"description":"Success","content":{"application/json":{}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/public/bookings/{id}/reschedule":{"post":{"operationId":"reschedule_booking_as_invitee","summary":"Reschedule a booking (invitee)","description":"Moves a confirmed booking to `start` with the same hosts. Get valid times from get_available_slots with this `bookingId` and `token`. The calendar event is updated and its provider notifies attendees. Payment carries over. Not possible after `changeableUntil` (409 change_too_late). A request (status=pending_approval) can’t be moved: cancel it and request another time.","tags":["public"],"security":[],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","description":"the booking id from create_booking, or its manageUrl"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string","description":"the token from create_booking, or the manageUrl"},"start":{"type":"string","format":"date-time","description":"one of the `slots` values from get_available_slots, as given (ISO in UTC)"}},"required":["token","start"]}}}},"responses":{"201":{"description":"Success","content":{"application/json":{}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/public/bookings/{id}/cancel":{"post":{"operationId":"cancel_booking_as_invitee","summary":"Cancel a booking (invitee)","description":"Cancels a booking by its id and token. The event is removed from the host's calendar. Paid bookings cancelled before `refundableUntil` are refunded in full. Later cancellations get no refund. The event type sets the rules, which get_booking shows: no changes after `changeableUntil` (409 change_too_late), no cancelling when `canCancel` is false (409 cancel_not_allowed, reschedule instead).","tags":["public"],"security":[],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","description":"the booking id from create_booking, or its manageUrl"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string","description":"the token from create_booking, or the manageUrl"},"reason":{"type":"string","description":"why the invitee cancels, sent to the host","title":"maxLength(500)","minLength":0,"maxLength":500},"following":{"type":"boolean","description":"for a series: also cancel every later meeting"}},"required":["token"]}}}},"responses":{"201":{"description":"Success","content":{"application/json":{}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/public/review/{id}":{"get":{"operationId":"get_review","summary":"View a request from its email link (host)","description":"Returns a request for approval as its host sees it, from the signed link in their email.","tags":["public"],"security":[],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","description":"a string at least 1 character(s) long","title":"minLength(1)","minLength":1}},{"name":"host","in":"query","required":true,"schema":{"type":"string","description":"a string at least 1 character(s) long","title":"minLength(1)","minLength":1}},{"name":"token","in":"query","required":true,"schema":{"type":"string","description":"a string at least 10 character(s) long","title":"minLength(10)","minLength":10}}],"responses":{"200":{"description":"Success","content":{"application/json":{}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"answer_review","summary":"Approve or decline a request from its email link (host)","description":"Approves or declines a request with the signed link from the host’s email. The invitee is told either way.","tags":["public"],"security":[],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","description":"a string at least 1 character(s) long","title":"minLength(1)","minLength":1}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"host":{"type":"string","description":"a string at least 1 character(s) long","title":"minLength(1)","minLength":1},"token":{"type":"string","description":"a string at least 10 character(s) long","title":"minLength(10)","minLength":10},"decision":{"type":"string","enum":["approve","decline"]},"reason":{"type":"string","description":"a string at most 500 character(s) long","title":"maxLength(500)","minLength":0,"maxLength":500}},"required":["host","token","decision"]}}}},"responses":{"201":{"description":"Success","content":{"application/json":{}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/waitlist":{"post":{"operationId":"join_waitlist","summary":"Join the private beta waitlist","description":"Requests access to host on Tempi (create event types, share a booking page). Not needed to book meetings, since booking pages are public. Returns the status: pending, approved (sign in to the Tempi web app), rejected, or open (no waitlist, sign in directly). Joining again with the same email returns the current status.","tags":["public"],"security":[],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email","description":"an email address"},"name":{"type":"string","description":"the person’s name (at most 100 characters)","title":"maxLength(100)","minLength":0,"maxLength":100},"note":{"type":"string","description":"anything the admins should know, e.g. what you want to use Tempi for","title":"maxLength(1000)","minLength":0,"maxLength":1000},"ref":{"type":"string","description":"a short source tag of lowercase letters, digits, - or _, like \"embed\"","pattern":"^[a-z0-9_-]{1,32}$"}},"required":["email"]}}}},"responses":{"201":{"description":"Success","content":{"application/json":{}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/me":{"get":{"operationId":"get_me","summary":"Get the current account","description":"Returns your account: email, name, username (your personal team's slug: get_team with it returns your booking page `url`), time zone, booking calendar, and the teams you belong to with your role in each.","tags":["account"],"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"update_me","summary":"Update your profile","description":"Changes your display name, username or time zone. The username is your personal booking handle, and old links keep working and redirect. A new name also renames your personal team.","tags":["account"],"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"parameters":[],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"your name, as invitees see it on your booking page and in their emails (at most 80 characters, no web addresses)"},"username":{"type":"string","description":"1-40 lowercase letters, digits or dashes, starting and ending with a letter or digit","pattern":"^[a-z0-9](?:[a-z0-9-]{0,38}[a-z0-9])?$"},"timezone":{"type":"string","description":"an IANA time zone such as \"America/New_York\" (abbreviations like EST and offsets like UTC+8 work too)"}},"required":[]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/me/video":{"post":{"operationId":"set_my_video_call","summary":"Set your video call","description":"Chooses the video call your bookings get, in every event type whose place is a video call without one link for everyone. meet: a Google Meet link from your Google Calendar (it must be your booking calendar). teams: a Microsoft Teams link from Outlook (a work or school account; on a personal Outlook account, add your own Teams link as `link`). link: your own link, the same for every booking. null: Tempi picks from your booking calendar. Returns your account, whose `video` says how bookings get their link and why not.","tags":["account"],"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"tool":{"anyOf":[{"type":"string","enum":["meet","teams","link"]},{"type":"null"}],"description":"meet | teams | link, or null to let your booking calendar decide"},"link":{"anyOf":[{"type":"string","format":"uri","description":"a Google Meet, Zoom, Microsoft Teams or Webex link (https)"},{"type":"null"}],"description":"a Google Meet, Zoom, Microsoft Teams or Webex link (https)"}},"required":["tool"]}}}},"responses":{"201":{"description":"Success","content":{"application/json":{}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/me/onboarding":{"post":{"operationId":"complete_onboarding","summary":"Finish first-run setup","description":"Marks first-run setup as done or skipped, so the app stops showing it.","tags":["account"],"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"parameters":[],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"skipped":{"type":"boolean","description":"true when the person skipped setup instead of finishing it"},"ref":{"type":"string","description":"a short source tag of lowercase letters, digits, - or _, like \"embed\"","pattern":"^[a-z0-9_-]{1,32}$"}},"required":[]}}}},"responses":{"201":{"description":"Success","content":{"application/json":{}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/availability":{"get":{"operationId":"get_availability","summary":"Get working hours","description":"Returns your weekly hours, upcoming date overrides and meeting caps, in your time zone. They apply to every event type you host, in every team. Busy times in your connected calendars are subtracted automatically.","tags":["account"],"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"set_availability","summary":"Replace weekly hours","description":"Replaces all your weekly hours. Each rule is one window on one weekday, in your time zone. Use several rules for a split day, such as 09:00-12:00 and 13:00-17:00. An empty list means you are never available, except on date overrides. Pass `timezone` to change your time zone too.","tags":["account"],"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"rules":{"type":"array","items":{"type":"object","required":["weekday","start","end"],"properties":{"weekday":{"type":"number","enum":[0,1,2,3,4,5,6],"description":"a weekday number, 0 = Sunday … 6 = Saturday"},"start":{"type":"string","description":"a 24-hour time as HH:MM, or \"24:00\" for the end of the day","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$|^24:00$"},"end":{"type":"string","description":"a 24-hour time as HH:MM, or \"24:00\" for the end of the day","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$|^24:00$"}},"additionalProperties":false},"description":"an array of at most 50 item(s)","title":"maxItems(50)","maxItems":50},"timezone":{"type":"string","description":"an IANA time zone such as \"America/New_York\" (abbreviations like EST and offsets like UTC+8 work too)"}},"required":["rules"]}}}},"responses":{"201":{"description":"Success","content":{"application/json":{}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/availability/preview":{"get":{"operationId":"preview_availability","summary":"See your next days as people booking you see them","description":"Shows your next days (14 by default) as people booking you see them, in your time zone. Each day has a `status` (open: some time can be booked; busy: calendar events or bookings take your hours; full: your daily limit is reached; day_off: you took the day off; not_working: your weekly hours have nothing that day; past: today's hours are over) and a `summary` to show or say. It also gives your working hours, what takes time inside them (`busy`: Tempi bookings with what they are and a link, and busy time in each calendar with the calendar's account and, for Google, a link to that day. Calendar event titles aren't read) and the `open` time left, each with a local `time`. `eventTypes` lists the event types you host and whether each uses these hours or its own (set in that event type: update_event_type `schedule`). Use it to answer \"when can people book me this week?\" Next: to take a date off or work other hours on it, call set_date_override (windows [] takes the day off). To change your usual week, call set_availability. For why one event type can't be booked at a time, call explain_availability.","tags":["account"],"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"parameters":[{"name":"days","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","description":"an integer","title":"int"},{"type":"string","description":"a string to be decoded into a number"}],"description":"how many days to show, today first (1-28)","title":"between(1, 28)","minimum":1,"maximum":28}}],"responses":{"200":{"description":"Success","content":{"application/json":{}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/me/open-times":{"get":{"operationId":"get_open_times","summary":"Check that your booking pages have open times","description":"For each active event type you host, whether invitees can book any time in the next 14 days. One with none shows \"Nothing open\" on its booking page: check working hours, days off, calendars and limits. explain_availability says why a given time is not offered.","tags":["account"],"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/availability/limits":{"patch":{"operationId":"set_meeting_limits","summary":"Cap meetings per day or week","description":"Caps how many meetings you host per day and per calendar week (Monday first, in your time zone), across all event types and teams. Once a cap is reached, that day or week offers no more slots. null removes a cap, and an omitted field stays as it is. Event types have their own limits too (maxPerDay, maxPerWeek, maxPerMonth).","tags":["account"],"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"parameters":[],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"perDay":{"anyOf":[{"type":"integer","description":"a number between 1 and 100","title":"between(1, 100)","minimum":1,"maximum":100},{"type":"null"}],"description":"the most meetings per day (1-100), or null for no cap"},"perWeek":{"anyOf":[{"type":"integer","description":"a number between 1 and 100","title":"between(1, 100)","minimum":1,"maximum":100},{"type":"null"}],"description":"the most meetings per calendar week (1-100), or null for no cap"}},"required":[]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/availability/overrides":{"post":{"operationId":"set_date_override","summary":"Set hours for a specific date","description":"Sets your hours on one date, in your time zone, in place of the weekly hours and any earlier override for that date. Use windows: [] for a day off, or add hours on a day you usually don't work.","tags":["account"],"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"date":{"type":"string","format":"date","description":"a date as YYYY-MM-DD"},"windows":{"type":"array","items":{"type":"object","required":["start","end"],"properties":{"start":{"type":"string","description":"a 24-hour time as HH:MM, or \"24:00\" for the end of the day","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$|^24:00$"},"end":{"type":"string","description":"a 24-hour time as HH:MM, or \"24:00\" for the end of the day","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$|^24:00$"}},"additionalProperties":false},"description":"an array of at most 10 item(s)","title":"maxItems(10)","maxItems":10}},"required":["date","windows"]}}}},"responses":{"201":{"description":"Success","content":{"application/json":{}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/availability/overrides/{date}":{"delete":{"operationId":"delete_date_override","summary":"Remove a date override","description":"Removes the override for a date, so your weekly hours apply again.","tags":["account"],"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"parameters":[{"name":"date","in":"path","required":true,"schema":{"type":"string","format":"date","description":"a date as YYYY-MM-DD"}}],"responses":{"200":{"description":"Success","content":{"application/json":{}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/teams":{"get":{"operationId":"list_teams","summary":"List your teams","description":"Lists the teams you belong to, with your role in each. Every user has a personal team, which is their own booking page. Event types always belong to a team.","tags":["account"],"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"create_team","summary":"Create a team","description":"Creates a team with you as owner. Returns the team with its booking page `url`. `slug` defaults to one made from the name.","tags":["account"],"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"the team’s name, as invitees see it on its booking pages (at most 80 characters, no web addresses)"},"slug":{"type":"string","description":"1-40 lowercase letters, digits or dashes, starting and ending with a letter or digit","pattern":"^[a-z0-9](?:[a-z0-9-]{0,38}[a-z0-9])?$"}},"required":["name"]}}}},"responses":{"201":{"description":"Success","content":{"application/json":{}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/teams/{team}":{"get":{"operationId":"get_team","summary":"Get a team","description":"Returns a team with its members, pending invites, payment status and invitee blocklist. Each member's `setup` says whether they have a calendar connected and working hours set, which the team's open times need. `setup.meet` says whether bookings they organize get a Google Meet link (their booking calendar is a working Google Calendar), `setup.teams` whether they get a Microsoft Teams link (a working Outlook calendar), and `setup.hostsMeet` whether they host one of the team's Google Meet event types. Any member can call it.","tags":["account"],"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"parameters":[{"name":"team","in":"path","required":true,"schema":{"type":"string","description":"the id or slug of a team you belong to","title":"minLength(1)","minLength":1}}],"responses":{"200":{"description":"Success","content":{"application/json":{}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":

# --- truncated at 32 KB (104 KB total) ---
# Full source: https://artifacts.apis.io/meettempi-com/openapi/_original/meettempi-com-api-openapi.json