curl --request POST \
--url https://api.cal.com/v2/events \
--header 'Authorization: <authorization>' \
--header 'Content-Type: application/json' \
--data '
{
"title": "Team offsite",
"startTime": "2030-01-01T10:00:00.000Z",
"endTime": "2030-01-01T11:00:00.000Z",
"timeZone": "Europe/Berlin",
"slug": "team-offsite-2030",
"description": "<string>",
"visibility": "PUBLIC",
"capacity": 50000.5,
"waitlistEnabled": false,
"requiresApproval": false,
"showOrganizerEmail": true,
"guestList": "names",
"showPresentedBy": true,
"locations": [
{
"type": "address",
"address": "1 Example Street, Berlin",
"label": "<string>",
"price": 1500,
"currency": "usd",
"capacity": 50000.5
}
]
}
'import requests
url = "https://api.cal.com/v2/events"
payload = {
"title": "Team offsite",
"startTime": "2030-01-01T10:00:00.000Z",
"endTime": "2030-01-01T11:00:00.000Z",
"timeZone": "Europe/Berlin",
"slug": "team-offsite-2030",
"description": "<string>",
"visibility": "PUBLIC",
"capacity": 50000.5,
"waitlistEnabled": False,
"requiresApproval": False,
"showOrganizerEmail": True,
"guestList": "names",
"showPresentedBy": True,
"locations": [
{
"type": "address",
"address": "1 Example Street, Berlin",
"label": "<string>",
"price": 1500,
"currency": "usd",
"capacity": 50000.5
}
]
}
headers = {
"Authorization": "<authorization>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<authorization>', 'Content-Type': 'application/json'},
body: JSON.stringify({
title: 'Team offsite',
startTime: '2030-01-01T10:00:00.000Z',
endTime: '2030-01-01T11:00:00.000Z',
timeZone: 'Europe/Berlin',
slug: 'team-offsite-2030',
description: '<string>',
visibility: 'PUBLIC',
capacity: 50000.5,
waitlistEnabled: false,
requiresApproval: false,
showOrganizerEmail: true,
guestList: 'names',
showPresentedBy: true,
locations: [
{
type: 'address',
address: '1 Example Street, Berlin',
label: '<string>',
price: 1500,
currency: 'usd',
capacity: 50000.5
}
]
})
};
fetch('https://api.cal.com/v2/events', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.cal.com/v2/events",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'title' => 'Team offsite',
'startTime' => '2030-01-01T10:00:00.000Z',
'endTime' => '2030-01-01T11:00:00.000Z',
'timeZone' => 'Europe/Berlin',
'slug' => 'team-offsite-2030',
'description' => '<string>',
'visibility' => 'PUBLIC',
'capacity' => 50000.5,
'waitlistEnabled' => false,
'requiresApproval' => false,
'showOrganizerEmail' => true,
'guestList' => 'names',
'showPresentedBy' => true,
'locations' => [
[
'type' => 'address',
'address' => '1 Example Street, Berlin',
'label' => '<string>',
'price' => 1500,
'currency' => 'usd',
'capacity' => 50000.5
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.cal.com/v2/events"
payload := strings.NewReader("{\n \"title\": \"Team offsite\",\n \"startTime\": \"2030-01-01T10:00:00.000Z\",\n \"endTime\": \"2030-01-01T11:00:00.000Z\",\n \"timeZone\": \"Europe/Berlin\",\n \"slug\": \"team-offsite-2030\",\n \"description\": \"<string>\",\n \"visibility\": \"PUBLIC\",\n \"capacity\": 50000.5,\n \"waitlistEnabled\": false,\n \"requiresApproval\": false,\n \"showOrganizerEmail\": true,\n \"guestList\": \"names\",\n \"showPresentedBy\": true,\n \"locations\": [\n {\n \"type\": \"address\",\n \"address\": \"1 Example Street, Berlin\",\n \"label\": \"<string>\",\n \"price\": 1500,\n \"currency\": \"usd\",\n \"capacity\": 50000.5\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<authorization>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.cal.com/v2/events")
.header("Authorization", "<authorization>")
.header("Content-Type", "application/json")
.body("{\n \"title\": \"Team offsite\",\n \"startTime\": \"2030-01-01T10:00:00.000Z\",\n \"endTime\": \"2030-01-01T11:00:00.000Z\",\n \"timeZone\": \"Europe/Berlin\",\n \"slug\": \"team-offsite-2030\",\n \"description\": \"<string>\",\n \"visibility\": \"PUBLIC\",\n \"capacity\": 50000.5,\n \"waitlistEnabled\": false,\n \"requiresApproval\": false,\n \"showOrganizerEmail\": true,\n \"guestList\": \"names\",\n \"showPresentedBy\": true,\n \"locations\": [\n {\n \"type\": \"address\",\n \"address\": \"1 Example Street, Berlin\",\n \"label\": \"<string>\",\n \"price\": 1500,\n \"currency\": \"usd\",\n \"capacity\": 50000.5\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cal.com/v2/events")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<authorization>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"title\": \"Team offsite\",\n \"startTime\": \"2030-01-01T10:00:00.000Z\",\n \"endTime\": \"2030-01-01T11:00:00.000Z\",\n \"timeZone\": \"Europe/Berlin\",\n \"slug\": \"team-offsite-2030\",\n \"description\": \"<string>\",\n \"visibility\": \"PUBLIC\",\n \"capacity\": 50000.5,\n \"waitlistEnabled\": false,\n \"requiresApproval\": false,\n \"showOrganizerEmail\": true,\n \"guestList\": \"names\",\n \"showPresentedBy\": true,\n \"locations\": [\n {\n \"type\": \"address\",\n \"address\": \"1 Example Street, Berlin\",\n \"label\": \"<string>\",\n \"price\": 1500,\n \"currency\": \"usd\",\n \"capacity\": 50000.5\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"status": "success",
"data": {
"uuid": "<string>",
"slug": "<string>",
"title": "<string>",
"startTime": "2023-11-07T05:31:56Z",
"endTime": "2023-11-07T05:31:56Z",
"checkInOpensAt": "2023-11-07T05:31:56Z",
"checkInClosesAt": "2023-11-07T05:31:56Z",
"timeZone": "<string>",
"visibility": "PUBLIC",
"hidden": true,
"status": "draft",
"locations": [
{
"id": "<string>",
"price": 2500,
"currency": "usd",
"type": "address",
"address": "123 Event Street",
"label": "<string>",
"capacity": 50000.5
}
],
"requiresApproval": true,
"waitlistEnabled": true,
"showOrganizerEmail": true,
"guestList": "hidden",
"showPresentedBy": true,
"hosts": [
{
"userId": 123,
"name": "Jane Doe",
"username": "jane",
"avatarUrl": "<string>"
}
],
"description": "<string>",
"publishedAt": "2023-11-07T05:31:56Z",
"cancelledAt": "2023-11-07T05:31:56Z",
"coverImageUrl": "<string>",
"confirmedCount": 123,
"capacity": 100,
"cancellationReason": "<string>",
"userId": 123,
"teamId": 123
}
}Create an Event
Creates a draft Event for the authenticated user. A draft is not public and nobody can register until it is published with POST /v2/events/{uuid}/publish. To create an Event owned by a team, use POST /v2/teams/{teamId}/events.
startTime and endTime are ISO 8601 in UTC; startTime must not be in the past and endTime must be after startTime.
guestList controls whether guests see names, a count, or neither. locations sets where the Event happens; set price and currency on a location to charge for that place.
Events are fixed-date RSVP pages served at cal.com/; they are not event types (bookable meeting templates) or calendar events.
Learn more about API access control at https://cal.com/docs/api-reference/v2/access-control. If accessed using an OAuth access token, the EVENT_WRITE scope is required.
curl --request POST \
--url https://api.cal.com/v2/events \
--header 'Authorization: <authorization>' \
--header 'Content-Type: application/json' \
--data '
{
"title": "Team offsite",
"startTime": "2030-01-01T10:00:00.000Z",
"endTime": "2030-01-01T11:00:00.000Z",
"timeZone": "Europe/Berlin",
"slug": "team-offsite-2030",
"description": "<string>",
"visibility": "PUBLIC",
"capacity": 50000.5,
"waitlistEnabled": false,
"requiresApproval": false,
"showOrganizerEmail": true,
"guestList": "names",
"showPresentedBy": true,
"locations": [
{
"type": "address",
"address": "1 Example Street, Berlin",
"label": "<string>",
"price": 1500,
"currency": "usd",
"capacity": 50000.5
}
]
}
'import requests
url = "https://api.cal.com/v2/events"
payload = {
"title": "Team offsite",
"startTime": "2030-01-01T10:00:00.000Z",
"endTime": "2030-01-01T11:00:00.000Z",
"timeZone": "Europe/Berlin",
"slug": "team-offsite-2030",
"description": "<string>",
"visibility": "PUBLIC",
"capacity": 50000.5,
"waitlistEnabled": False,
"requiresApproval": False,
"showOrganizerEmail": True,
"guestList": "names",
"showPresentedBy": True,
"locations": [
{
"type": "address",
"address": "1 Example Street, Berlin",
"label": "<string>",
"price": 1500,
"currency": "usd",
"capacity": 50000.5
}
]
}
headers = {
"Authorization": "<authorization>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<authorization>', 'Content-Type': 'application/json'},
body: JSON.stringify({
title: 'Team offsite',
startTime: '2030-01-01T10:00:00.000Z',
endTime: '2030-01-01T11:00:00.000Z',
timeZone: 'Europe/Berlin',
slug: 'team-offsite-2030',
description: '<string>',
visibility: 'PUBLIC',
capacity: 50000.5,
waitlistEnabled: false,
requiresApproval: false,
showOrganizerEmail: true,
guestList: 'names',
showPresentedBy: true,
locations: [
{
type: 'address',
address: '1 Example Street, Berlin',
label: '<string>',
price: 1500,
currency: 'usd',
capacity: 50000.5
}
]
})
};
fetch('https://api.cal.com/v2/events', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.cal.com/v2/events",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'title' => 'Team offsite',
'startTime' => '2030-01-01T10:00:00.000Z',
'endTime' => '2030-01-01T11:00:00.000Z',
'timeZone' => 'Europe/Berlin',
'slug' => 'team-offsite-2030',
'description' => '<string>',
'visibility' => 'PUBLIC',
'capacity' => 50000.5,
'waitlistEnabled' => false,
'requiresApproval' => false,
'showOrganizerEmail' => true,
'guestList' => 'names',
'showPresentedBy' => true,
'locations' => [
[
'type' => 'address',
'address' => '1 Example Street, Berlin',
'label' => '<string>',
'price' => 1500,
'currency' => 'usd',
'capacity' => 50000.5
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.cal.com/v2/events"
payload := strings.NewReader("{\n \"title\": \"Team offsite\",\n \"startTime\": \"2030-01-01T10:00:00.000Z\",\n \"endTime\": \"2030-01-01T11:00:00.000Z\",\n \"timeZone\": \"Europe/Berlin\",\n \"slug\": \"team-offsite-2030\",\n \"description\": \"<string>\",\n \"visibility\": \"PUBLIC\",\n \"capacity\": 50000.5,\n \"waitlistEnabled\": false,\n \"requiresApproval\": false,\n \"showOrganizerEmail\": true,\n \"guestList\": \"names\",\n \"showPresentedBy\": true,\n \"locations\": [\n {\n \"type\": \"address\",\n \"address\": \"1 Example Street, Berlin\",\n \"label\": \"<string>\",\n \"price\": 1500,\n \"currency\": \"usd\",\n \"capacity\": 50000.5\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<authorization>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.cal.com/v2/events")
.header("Authorization", "<authorization>")
.header("Content-Type", "application/json")
.body("{\n \"title\": \"Team offsite\",\n \"startTime\": \"2030-01-01T10:00:00.000Z\",\n \"endTime\": \"2030-01-01T11:00:00.000Z\",\n \"timeZone\": \"Europe/Berlin\",\n \"slug\": \"team-offsite-2030\",\n \"description\": \"<string>\",\n \"visibility\": \"PUBLIC\",\n \"capacity\": 50000.5,\n \"waitlistEnabled\": false,\n \"requiresApproval\": false,\n \"showOrganizerEmail\": true,\n \"guestList\": \"names\",\n \"showPresentedBy\": true,\n \"locations\": [\n {\n \"type\": \"address\",\n \"address\": \"1 Example Street, Berlin\",\n \"label\": \"<string>\",\n \"price\": 1500,\n \"currency\": \"usd\",\n \"capacity\": 50000.5\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cal.com/v2/events")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<authorization>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"title\": \"Team offsite\",\n \"startTime\": \"2030-01-01T10:00:00.000Z\",\n \"endTime\": \"2030-01-01T11:00:00.000Z\",\n \"timeZone\": \"Europe/Berlin\",\n \"slug\": \"team-offsite-2030\",\n \"description\": \"<string>\",\n \"visibility\": \"PUBLIC\",\n \"capacity\": 50000.5,\n \"waitlistEnabled\": false,\n \"requiresApproval\": false,\n \"showOrganizerEmail\": true,\n \"guestList\": \"names\",\n \"showPresentedBy\": true,\n \"locations\": [\n {\n \"type\": \"address\",\n \"address\": \"1 Example Street, Berlin\",\n \"label\": \"<string>\",\n \"price\": 1500,\n \"currency\": \"usd\",\n \"capacity\": 50000.5\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"status": "success",
"data": {
"uuid": "<string>",
"slug": "<string>",
"title": "<string>",
"startTime": "2023-11-07T05:31:56Z",
"endTime": "2023-11-07T05:31:56Z",
"checkInOpensAt": "2023-11-07T05:31:56Z",
"checkInClosesAt": "2023-11-07T05:31:56Z",
"timeZone": "<string>",
"visibility": "PUBLIC",
"hidden": true,
"status": "draft",
"locations": [
{
"id": "<string>",
"price": 2500,
"currency": "usd",
"type": "address",
"address": "123 Event Street",
"label": "<string>",
"capacity": 50000.5
}
],
"requiresApproval": true,
"waitlistEnabled": true,
"showOrganizerEmail": true,
"guestList": "hidden",
"showPresentedBy": true,
"hosts": [
{
"userId": 123,
"name": "Jane Doe",
"username": "jane",
"avatarUrl": "<string>"
}
],
"description": "<string>",
"publishedAt": "2023-11-07T05:31:56Z",
"cancelledAt": "2023-11-07T05:31:56Z",
"coverImageUrl": "<string>",
"confirmedCount": 123,
"capacity": 100,
"cancellationReason": "<string>",
"userId": 123,
"teamId": 123
}
}Headers
value must be Bearer <token> where <token> is api key prefixed with cal_, managed user access token, or OAuth access token
Body
The Event's title.
1 - 255"Team offsite"
When the Event starts, in ISO 8601 format in UTC timezone. It must not be in the past.
"2030-01-01T10:00:00.000Z"
When the Event ends, in ISO 8601 format in UTC timezone. It must be after startTime.
"2030-01-01T11:00:00.000Z"
The IANA time zone the Event's times are shown in.
"Europe/Berlin"
Public page slug (cal.com/{slug}): 10-100 lowercase letters, digits and hyphens. Generated from the title when omitted.
"team-offsite-2030"
What the Event is about, shown on its page.
5000Once published: PUBLIC is listed on the owner's page, UNLISTED only opens from its link. Defaults to PUBLIC.
PUBLIC, UNLISTED The most guests the Event can take. Omit or pass null for unlimited. Ignored once any location has its own capacity: the Event then takes the sum of the location capacities, or is unlimited if any location has none. The waitlist only opens when the Event or the chosen location is full, so it only works when capacity is set on the Event or on a location.
1 <= x <= 100000Let guests join a waitlist when the Event is full. The waitlist only opens when the Event or the chosen location is full, so it only works when capacity is set on the Event or on a location.
Registrations wait for a host's approval.
Show the organizer's email to guests.
Who guests can see on the Event's page. names lists them, count shows how many, hidden shows neither. Defaults to names.
hidden, names, count Show who the Event is presented by.
Where the Event happens. Links can repeat. An Event can have one address and one conferencing location, either an integration or the organizer's default app.
- Option 1
- Option 2
- Option 3
- Option 4
Show child attributes
Show child attributes
Was this page helpful?