curl --request POST \
--url https://app.famulor.io/api/v1/booking-event-types \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Intro call",
"slug": "acme-intro",
"duration_min": 30,
"timezone": "Europe/Berlin",
"availability": {
"mon": [
{
"start": "09:00",
"end": "17:00"
}
],
"tue": [
{
"start": "09:00",
"end": "17:00"
}
],
"wed": [
{
"start": "09:00",
"end": "17:00"
}
],
"thu": [
{
"start": "09:00",
"end": "17:00"
}
],
"fri": [
{
"start": "09:00",
"end": "17:00"
}
]
}
}
'import requests
url = "https://app.famulor.io/api/v1/booking-event-types"
payload = {
"name": "Intro call",
"slug": "acme-intro",
"duration_min": 30,
"timezone": "Europe/Berlin",
"availability": {
"mon": [
{
"start": "09:00",
"end": "17:00"
}
],
"tue": [
{
"start": "09:00",
"end": "17:00"
}
],
"wed": [
{
"start": "09:00",
"end": "17:00"
}
],
"thu": [
{
"start": "09:00",
"end": "17:00"
}
],
"fri": [
{
"start": "09:00",
"end": "17:00"
}
]
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Intro call',
slug: 'acme-intro',
duration_min: 30,
timezone: 'Europe/Berlin',
availability: {
mon: [{start: '09:00', end: '17:00'}],
tue: [{start: '09:00', end: '17:00'}],
wed: [{start: '09:00', end: '17:00'}],
thu: [{start: '09:00', end: '17:00'}],
fri: [{start: '09:00', end: '17:00'}]
}
})
};
fetch('https://app.famulor.io/api/v1/booking-event-types', 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://app.famulor.io/api/v1/booking-event-types",
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([
'name' => 'Intro call',
'slug' => 'acme-intro',
'duration_min' => 30,
'timezone' => 'Europe/Berlin',
'availability' => [
'mon' => [
[
'start' => '09:00',
'end' => '17:00'
]
],
'tue' => [
[
'start' => '09:00',
'end' => '17:00'
]
],
'wed' => [
[
'start' => '09:00',
'end' => '17:00'
]
],
'thu' => [
[
'start' => '09:00',
'end' => '17:00'
]
],
'fri' => [
[
'start' => '09:00',
'end' => '17:00'
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"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://app.famulor.io/api/v1/booking-event-types"
payload := strings.NewReader("{\n \"name\": \"Intro call\",\n \"slug\": \"acme-intro\",\n \"duration_min\": 30,\n \"timezone\": \"Europe/Berlin\",\n \"availability\": {\n \"mon\": [\n {\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n }\n ],\n \"tue\": [\n {\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n }\n ],\n \"wed\": [\n {\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n }\n ],\n \"thu\": [\n {\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n }\n ],\n \"fri\": [\n {\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n }\n ]\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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://app.famulor.io/api/v1/booking-event-types")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Intro call\",\n \"slug\": \"acme-intro\",\n \"duration_min\": 30,\n \"timezone\": \"Europe/Berlin\",\n \"availability\": {\n \"mon\": [\n {\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n }\n ],\n \"tue\": [\n {\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n }\n ],\n \"wed\": [\n {\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n }\n ],\n \"thu\": [\n {\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n }\n ],\n \"fri\": [\n {\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n }\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.famulor.io/api/v1/booking-event-types")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"Intro call\",\n \"slug\": \"acme-intro\",\n \"duration_min\": 30,\n \"timezone\": \"Europe/Berlin\",\n \"availability\": {\n \"mon\": [\n {\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n }\n ],\n \"tue\": [\n {\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n }\n ],\n \"wed\": [\n {\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n }\n ],\n \"thu\": [\n {\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n }\n ],\n \"fri\": [\n {\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n }\n ]\n }\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"slug": "<string>",
"workspace": "<string>",
"description": "<string>",
"duration_min": 242,
"timezone": "<string>",
"availability": {},
"buffer_before_min": 123,
"buffer_after_min": 123,
"min_notice_min": 123,
"max_days_ahead": 123,
"slot_increment_min": 123,
"calendar_connection_id": "<string>",
"reminder_hours": 123,
"is_active": true,
"booking_fields": [
{
"id": "<string>",
"type": "email",
"label": "<string>",
"required": true,
"placeholder": "<string>",
"options": [
"<string>"
],
"disable_if_prefilled": true
}
],
"phone_required": true,
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"email_required": true,
"sender_email_address_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"confirmation_email_subject": "<string>",
"confirmation_email_body": "<string>",
"email_templates": {
"cancellation": {
"subject": "<string>",
"body": "<string>"
},
"reschedule": {
"subject": "<string>",
"body": "<string>"
},
"reminder": {
"subject": "<string>",
"body": "<string>"
},
"host_confirmation": {
"subject": "<string>",
"body": "<string>"
},
"host_cancellation": {
"subject": "<string>",
"body": "<string>"
},
"host_reschedule": {
"subject": "<string>",
"body": "<string>"
}
},
"email_locale": "en",
"guest_emails_enabled": true,
"hour_cycle": "24h"
}
}Create a booking event type
Create an event type. The slug is unique within the workspace and becomes the public booking page URL /book/{workspace}/{slug}. Requires an admin-level credential; requires Calendar integrations in the workspace plan.
Required scope: bookings:write (keys without scope restrictions have full access).
curl --request POST \
--url https://app.famulor.io/api/v1/booking-event-types \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Intro call",
"slug": "acme-intro",
"duration_min": 30,
"timezone": "Europe/Berlin",
"availability": {
"mon": [
{
"start": "09:00",
"end": "17:00"
}
],
"tue": [
{
"start": "09:00",
"end": "17:00"
}
],
"wed": [
{
"start": "09:00",
"end": "17:00"
}
],
"thu": [
{
"start": "09:00",
"end": "17:00"
}
],
"fri": [
{
"start": "09:00",
"end": "17:00"
}
]
}
}
'import requests
url = "https://app.famulor.io/api/v1/booking-event-types"
payload = {
"name": "Intro call",
"slug": "acme-intro",
"duration_min": 30,
"timezone": "Europe/Berlin",
"availability": {
"mon": [
{
"start": "09:00",
"end": "17:00"
}
],
"tue": [
{
"start": "09:00",
"end": "17:00"
}
],
"wed": [
{
"start": "09:00",
"end": "17:00"
}
],
"thu": [
{
"start": "09:00",
"end": "17:00"
}
],
"fri": [
{
"start": "09:00",
"end": "17:00"
}
]
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Intro call',
slug: 'acme-intro',
duration_min: 30,
timezone: 'Europe/Berlin',
availability: {
mon: [{start: '09:00', end: '17:00'}],
tue: [{start: '09:00', end: '17:00'}],
wed: [{start: '09:00', end: '17:00'}],
thu: [{start: '09:00', end: '17:00'}],
fri: [{start: '09:00', end: '17:00'}]
}
})
};
fetch('https://app.famulor.io/api/v1/booking-event-types', 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://app.famulor.io/api/v1/booking-event-types",
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([
'name' => 'Intro call',
'slug' => 'acme-intro',
'duration_min' => 30,
'timezone' => 'Europe/Berlin',
'availability' => [
'mon' => [
[
'start' => '09:00',
'end' => '17:00'
]
],
'tue' => [
[
'start' => '09:00',
'end' => '17:00'
]
],
'wed' => [
[
'start' => '09:00',
'end' => '17:00'
]
],
'thu' => [
[
'start' => '09:00',
'end' => '17:00'
]
],
'fri' => [
[
'start' => '09:00',
'end' => '17:00'
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"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://app.famulor.io/api/v1/booking-event-types"
payload := strings.NewReader("{\n \"name\": \"Intro call\",\n \"slug\": \"acme-intro\",\n \"duration_min\": 30,\n \"timezone\": \"Europe/Berlin\",\n \"availability\": {\n \"mon\": [\n {\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n }\n ],\n \"tue\": [\n {\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n }\n ],\n \"wed\": [\n {\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n }\n ],\n \"thu\": [\n {\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n }\n ],\n \"fri\": [\n {\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n }\n ]\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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://app.famulor.io/api/v1/booking-event-types")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Intro call\",\n \"slug\": \"acme-intro\",\n \"duration_min\": 30,\n \"timezone\": \"Europe/Berlin\",\n \"availability\": {\n \"mon\": [\n {\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n }\n ],\n \"tue\": [\n {\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n }\n ],\n \"wed\": [\n {\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n }\n ],\n \"thu\": [\n {\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n }\n ],\n \"fri\": [\n {\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n }\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.famulor.io/api/v1/booking-event-types")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"Intro call\",\n \"slug\": \"acme-intro\",\n \"duration_min\": 30,\n \"timezone\": \"Europe/Berlin\",\n \"availability\": {\n \"mon\": [\n {\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n }\n ],\n \"tue\": [\n {\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n }\n ],\n \"wed\": [\n {\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n }\n ],\n \"thu\": [\n {\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n }\n ],\n \"fri\": [\n {\n \"start\": \"09:00\",\n \"end\": \"17:00\"\n }\n ]\n }\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"slug": "<string>",
"workspace": "<string>",
"description": "<string>",
"duration_min": 242,
"timezone": "<string>",
"availability": {},
"buffer_before_min": 123,
"buffer_after_min": 123,
"min_notice_min": 123,
"max_days_ahead": 123,
"slot_increment_min": 123,
"calendar_connection_id": "<string>",
"reminder_hours": 123,
"is_active": true,
"booking_fields": [
{
"id": "<string>",
"type": "email",
"label": "<string>",
"required": true,
"placeholder": "<string>",
"options": [
"<string>"
],
"disable_if_prefilled": true
}
],
"phone_required": true,
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"email_required": true,
"sender_email_address_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"confirmation_email_subject": "<string>",
"confirmation_email_body": "<string>",
"email_templates": {
"cancellation": {
"subject": "<string>",
"body": "<string>"
},
"reschedule": {
"subject": "<string>",
"body": "<string>"
},
"reminder": {
"subject": "<string>",
"body": "<string>"
},
"host_confirmation": {
"subject": "<string>",
"body": "<string>"
},
"host_cancellation": {
"subject": "<string>",
"body": "<string>"
},
"host_reschedule": {
"subject": "<string>",
"body": "<string>"
}
},
"email_locale": "en",
"guest_emails_enabled": true,
"hour_cycle": "24h"
}
}Authorizations
API key (fam_..., created under Settings → API Keys) or an OAuth 2.0 access token (fam_at_...). REST operations also require API Access for the credential's workspace. Keys can be restricted to scopes such as assistants:read, calls:write, campaigns:write, automations:read, dashboards:read, dashboards:write, leads:write, segments:write, loop:read, loop:write, phone_numbers:write, sip_trunks:write, knowledge:write, voices:read, billing:read, billing:write, settings:write, platform:read, platform:write; a *:write scope implies the matching *:read. Automation and dashboard endpoints also accept the legacy calls:* scope. Keys without scope restrictions have full access within the workspace's available capabilities.
Body
128^[a-z0-9-]{3,64}$5 <= x <= 480"Europe/Berlin"
{
"mon": [{ "start": "09:00", "end": "17:00" }],
"fri": [{ "start": "09:00", "end": "12:00" }]
}
2000Custom booking questions, in display order. Name is always required; email_required and phone_required control the system contact fields.
30Show child attributes
Show child attributes
Require the visitor's phone number (E.164) to book. When false (default), phone is still asked but optional.
Whether an invitee email is required. Google Meet and Microsoft Teams always require a valid email.
Active verified email address belonging to this workspace. Null uses automatic workspace or inherited reseller SMTP, then the platform identity for eligible workspaces.
Custom initial confirmation subject; empty uses the standard subject. Supports the same booking variables as the message.
200Custom plain-text confirmation. Supported variables are returned by GET /booking-email-templates. Blank/null restores the localized standard message.
10000Complete replacement of the six additional guest/host email templates. Omit to preserve saved values; null or {} restores all six defaults. Confirmation uses the existing confirmation subject/body fields. GET /booking-email-templates returns standard templates and supported variables.
Show child attributes
Show child attributes
Language of the standard booking email texts (guest and host) for this event type. null (default) uses each recipient's language. Custom subject/body text is sent as written.
en, de, fr, es, null Send emails to the invitee. false = no confirmation, cancellation, reschedule or reminder emails to guests and no invitations from the connected calendar (the guest is not added as an attendee); host notifications still send.
Time format for the weekly availability editor and host emails. Availability values remain HH:mm. Guest emails follow the guest's saved booking-page preference, falling back to this format for older bookings.
12h, 24h Response
The created event type.
An event type of the native booking engine. Each active event type has a public, embeddable booking page at /book/{workspace}/{slug}.
Show child attributes
Show child attributes