Your AI Connector Docs

Janji Temu

API Janji Temu memungkinkan Anda membuat janji temu untuk kontak Anda pada jenis acara Anda, lalu mengambil, mencantumkan, memperbarui, membatalkan, atau menghapusnya. API ini juga menjawab pertanyaan yang paling sering muncul dalam alur pemesanan — waktu mana yang sebenarnya kosong — dan mencakup sisi kalender: mencantumkan Kalender Google yang telah Anda hubungkan dan mengimpor acara yang sudah ada di dalamnya. Saat koneksi Kalender Google aktif, acara kalender yang cocok akan dibuat dan disinkronkan secara otomatis di latar belakang. Restoran yang menggunakan Zenchef, Formitable, OpenTable, atau TheFork untuk sistem reservasi mereka sendiri juga dapat diverifikasi dan dihubungkan di sini, sehingga Agen AI memesan meja sungguhan alih-alih janji temu internal — dan bisnis berbasis janji temu yang menjalankan jadwal mereka di Trafft dapat menghubungkannya dengan cara yang sama.

Semua jalur di halaman ini relatif terhadap URL dasar https://api.youraiconnector.com/v1. Setiap permintaan memerlukan kunci API Anda — lihat Autentikasi untuk daftar lengkap cara mengirimkannya. Contoh di bawah menggunakan header X-API-Key, dengan satu contoh cURL yang juga menunjukkan formulir kueri ?apiKey=.

Acara vs. janji temu: Jenis acara adalah definisi slot yang dapat dipesan (jenis pertemuan, durasinya, ruangannya). Janji temu adalah satu instans yang dipesan dari jenis acara untuk kontak tertentu. Anda memesan janji temu dengan mereferensikan kontak dan jenis acara tersebut.


Objek janji temu

Setiap endpoint yang mengembalikan janji temu menggunakan bentuk yang sama:

Bidang Deskripsi
id ID unik janji temu.
contact_id ID kontak yang membuat janji temu.
event_id ID jenis acara tempat janji temu dipesan. null untuk pemesanan eksternal — janji temu yang dicatat tanpa jenis acara.
status Confirmed atau Canceled.
start_time Waktu mulai janji temu, ISO 8601 dalam UTC.
end_time Waktu berakhir janji temu, ISO 8601 dalam UTC.
created_at Kapan janji temu dibuat.
last_modified_at Kapan janji temu terakhir diubah.
room_name Ruangan atau sumber daya tempat janji temu dipesan, saat jenis acara menggunakan ruangan.
description Deskripsi bebas janji temu.
summary Ringkasan atau judul singkat. Untuk pemesanan eksternal, ini adalah title yang digunakan saat mencatatnya.
external_reference ID Anda sendiri untuk pemesanan ini (dari CRM atau sistem pemesanan Anda), seperti yang Anda kirimkan, atau null.
cancelation_reason Alasan yang diberikan saat janji temu dibatalkan, jika ada.
google_calendar_event_id ID acara Google Kalender yang ditautkan. Ditetapkan setelah sinkronisasi kalender selesai; null jika tidak ada kalender yang terhubung atau saat sinkronisasi masih berlangsung.
calendar_synced true setelah janji temu ditautkan ke acara kalender.
imported true saat janji temu diimpor dari kalender eksternal, bukan dipesan secara langsung.
is_recurring true saat janji temu merupakan bagian dari seri berulang.
recurrence_frequency Seberapa sering janji temu berulang, jika berulang.
recurring_event_id ID seri berulang tempat janji temu ini berada.
recurring_interval Interval antar pengulangan, jika berulang.
recurring_sequence Posisi janji temu ini dalam seri berulangnya.
end_after_x_occurrences Jumlah kejadian setelah seri berulang berakhir.
booking_provider Sistem sumber asal pemesanan, saat dipesan melalui penyedia reservasi yang terhubung.

Tentang sinkronisasi kalender: Tepat setelah Anda memesan atau mengubah janji temu, google_calendar_event_id mungkin masih null dan calendar_synced mungkin false karena sinkronisasi berjalan di latar belakang beberapa saat kemudian. Ambil kembali janji temu tersebut beberapa saat kemudian untuk melihat bidang kalender yang telah terisi.


Temukan slot yang tersedia

GET /appointments/available-slots

Mengembalikan waktu yang benar-benar kosong pada satu jenis acara di antara dua momen. Ini biasanya merupakan panggilan pertama dalam alur pemesanan: tampilkan slot ini, biarkan orang tersebut memilih satu, lalu kirim waktu yang dipilih ke Buat janji temu.

Jawaban tersebut sudah memperhitungkan jam buka dan durasi slot jenis acara itu sendiri, ruangannya, janji temu yang sudah Anda buat, dan semua yang diblokir di Kalender Google yang terhubung — jadi slot yang dikembalikan di sini adalah slot yang dapat Anda pesan.

Parameter kueri Wajib Deskripsi
event_id Ya Jenis acara yang akan diperiksa. Harus milik akun Anda. Temukan di aplikasi dengan membuka jenis acara di halaman Janji Temu (tab Jenis Acara): jendela edit menampilkan ID Jenis Acara beserta tombol salin.
start_time Ya Awal jendela waktu yang slotnya Anda inginkan, dalam format tanggal-waktu ISO 8601.
end_time Ya Akhir jendela waktu, dalam format tanggal-waktu ISO 8601. Seluruh hari terakhir disertakan.

Hasil dikembalikan dikelompokkan berdasarkan hari — dan, jika jenis acara menggunakan ruangan, satu grup per ruangan per hari:

Bidang Deskripsi
date Hari yang dicakup oleh grup, ditulis DD/MM/YYYY.
day Nama hari kerja dalam huruf kecil, contohnya monday.
room_name Ruangan atau sumber daya milik grup ini, jika jenis acara menggunakan ruangan.
available_slots Blok yang dapat dipesan pada hari itu, diurutkan dari yang paling awal.

Setiap entri dalam available_slots memiliki:

Bidang Deskripsi
start_time Awal blok sebagai HH:mm.
end_time Akhir blok sebagai HH:mm.
available true — hanya waktu kosong yang dikembalikan.
spots_left Berapa banyak pemesanan yang masih muat di blok ini. Hanya ada pada jenis acara yang menerima lebih dari satu pemesanan per slot.

Waktu bersifat lokal untuk jenis acara, bukan UTC. date, start_time, dan end_time adalah nilai jam dinding di zona waktu jenis acara itu sendiri (penggantiannya, atau zona waktu akun Anda jika tidak ada). Buat janji temu mengharapkan instan UTC ISO 8601, jadi konversikan slot yang Anda pilih sebelum mengirimnya.

cURL

curl "https://api.youraiconnector.com/v1/appointments/available-slots?event_id=event_xyz789&start_time=2026-06-15T00:00:00.000Z&end_time=2026-06-19T00:00:00.000Z" \
  -H "X-API-Key: YOUR_API_KEY"

JavaScript

const params = new URLSearchParams({
  event_id: "event_xyz789",
  start_time: "2026-06-15T00:00:00.000Z",
  end_time: "2026-06-19T00:00:00.000Z",
});
const res = await fetch(
  `https://api.youraiconnector.com/v1/appointments/available-slots?${params}`,
  { headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.data);

Python

import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/appointments/available-slots",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={
        "event_id": "event_xyz789",
        "start_time": "2026-06-15T00:00:00.000Z",
        "end_time": "2026-06-19T00:00:00.000Z",
    },
)
print(res.json()["data"])

Respons (200 OK):

{
  "success": true,
  "data": [
    {
      "date": "15/06/2026",
      "day": "monday",
      "room_name": "Room A",
      "available_slots": [
        { "start_time": "10:00", "end_time": "10:30", "available": true },
        { "start_time": "10:30", "end_time": "11:00", "available": true }
      ]
    },
    {
      "date": "16/06/2026",
      "day": "tuesday",
      "room_name": "Room A",
      "available_slots": [
        { "start_time": "09:00", "end_time": "09:30", "available": true, "spots_left": 2 }
      ]
    }
  ]
}

Hari yang tidak memiliki waktu kosong tidak akan muncul. event_id, start_time, atau end_time yang hilang akan mengembalikan 400; jenis acara yang tidak ada di akun Anda akan mengembalikan 404.


Pesan janji temu

POST /appointments

Membuat janji temu untuk salah satu kontak Anda. Ada dua cara untuk menggunakannya:

  • Pada salah satu jenis acara Anda — kirim event_id, dan pemesanan akan berfungsi seperti biasanya: ketersediaan dan kapasitas dihormati, waktu berakhir dihitung dari durasi slot jenis acara, dan janji temu disinkronkan ke Google Kalender Anda saat kalender terhubung.
  • Sebagai pemesanan eksternal — kosongkan event_id dan kirim title sebagai gantinya. Ini mencatat pemesanan yang dilakukan di tempat lain (CRM Anda sendiri, jadwal kelas, alat pemesanan lain) agar muncul di halaman Janji Temu bersama yang lainnya.

Pemesanan pada jenis acara dengan ruangan harus dilakukan pada waktu yang ditawarkan oleh Temukan slot yang tersedia: di dalam jam operasional ruangan, di luar periode pemberitahuan, dalam batas waktu seberapa jauh jenis acara dapat dipesan, pada kisi slot, bukan di masa lalu, dan tidak diblokir di kalender yang terhubung. Waktu lainnya akan ditolak dengan 400 dan tidak ada yang dibuat. Begitu pula dengan room_name yang tidak cocok dengan ruangan jenis acara mana pun (pesan tersebut mencantumkan nama-nama yang valid). Waktu penyangga yang ditetapkan pada jenis acara (Buffer before dan Buffer after di editor jenis acara, buffer_before dan buffer_after dalam menit) tetap dikosongkan di sekitar setiap pemesanan.

Pemesanan pada jenis acara juga diperiksa konfliknya: jika slot sudah penuh, permintaan gagal dengan 409 dan tidak ada yang dibuat. Pemesanan eksternal tidak memiliki jenis acara di belakangnya, jadi tidak ada yang diperiksa terhadap ketersediaan atau kapasitas Anda dan tidak ada yang disinkronkan ke kalender.

Melakukan percobaan ulang (retry) itu aman. Jika kontak yang sama sudah memiliki pemesanan yang dikonfirmasi pada jenis acara yang sama di waktu mulai yang sama (di ruangan yang sama, jika Anda menentukannya), misalnya karena permintaan pertama Anda mengalami timeout setelah berhasil diproses, Anda akan mendapatkan kembali pemesanan tersebut dengan 200 dan "replayed": true alih-alih pemesanan kedua atau 409.

external_reference berfungsi sebagai kunci idempoten. Kunci ini unik untuk akun Anda: jika sebuah janji temu sudah memiliki referensi yang Anda kirimkan, janji temu tersebut akan dikembalikan dengan 200 dan "replayed": true dan tidak ada yang baru dibuat, bahkan jika percobaan ulang menyebutkan waktu atau kontak yang berbeda dan apa pun status janji temu tersebut. Gunakan untuk pemesanan berbayar (kirim ID pembayaran atau pesanan Anda), dan kirim referensi baru untuk pemesanan yang benar-benar baru.

Bidang Wajib Deskripsi
contact_id Ya ID kontak yang akan dipesan. Harus milik akun Anda.
start_time Ya Waktu mulai yang diinginkan sebagai tanggal-waktu ISO 8601. Waktu yang dikirim tanpa offset zona waktu akan dibaca dalam zona waktu akun Anda.
event_id Tidak ID jenis acara untuk pemesanan. Harus milik akun Anda. Kosongkan untuk mencatat pemesanan eksternal.
title Hanya tanpa event_id Nama janji temu yang ditampilkan di halaman Janji Temu — misalnya, nama kelas. Maksimal 200 karakter. Ini akan dikembalikan sebagai summary.
end_time Tidak Waktu berakhir pemesanan eksternal sebagai tanggal-waktu ISO 8601, setelah start_time. Tidak diperlukan dengan event_id: waktu berakhir kemudian diambil dari durasi slot jenis acara.
duration_minutes Tidak Berapa lama pemesanan eksternal berlangsung, angka bulat dalam menit dari 1 hingga 1440. Gunakan ini atau end_time, jangan keduanya. Jika tidak keduanya, pemesanan eksternal berlangsung selama 60 menit.
description Tidak Catatan bentuk bebas untuk disimpan bersama janji temu.
room_name Tidak Nama ruangan atau sumber daya, saat jenis acara menggunakan ruangan. Harus cocok dengan salah satu ruangannya. Kosongkan untuk memesan ruangan kosong pertama.
external_reference Tidak ID Anda sendiri untuk pemesanan ini, sehingga Anda dapat mencocokkannya kembali dengan catatan di CRM atau sistem pemesanan Anda. Maksimal 255 karakter. Ini akan dikembalikan pada setiap pembacaan dan dalam webhook Janji Temu Dipesan, Dibatalkan, dan Dijadwalkan Ulang. Unik untuk akun Anda: referensi yang sudah digunakan akan mengembalikan janji temu tersebut alih-alih memesan lagi (lihat di atas).

Kirim event_id dan title bersamaan, atau tidak keduanya, dan permintaan akan mengembalikan 400 — begitu pula saat mengirim end_time dan duration_minutes sekaligus.

cURL (menggunakan formulir kueri ?apiKey=)

curl -X POST "https://api.youraiconnector.com/v1/appointments?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contact_id": "contact_abc123",
    "event_id": "event_xyz789",
    "start_time": "2026-06-15T10:00:00.000Z",
    "room_name": "Room A"
  }'

JavaScript

const res = await fetch("https://api.youraiconnector.com/v1/appointments", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    contact_id: "contact_abc123",
    event_id: "event_xyz789",
    start_time: "2026-06-15T10:00:00.000Z",
    room_name: "Room A",
  }),
});
const data = await res.json();
console.log(data.appointment_id);

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/appointments",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={
        "contact_id": "contact_abc123",
        "event_id": "event_xyz789",
        "start_time": "2026-06-15T10:00:00.000Z",
        "room_name": "Room A",
    },
)
print(res.json()["appointment_id"])

Respons (201 Created):

{
  "success": true,
  "appointment_id": "aBcD1234eFgH5678",
  "appointment": {
    "id": "aBcD1234eFgH5678",
    "contact_id": "contact_abc123",
    "event_id": "event_xyz789",
    "status": "Confirmed",
    "start_time": "2026-06-15T10:00:00.000Z",
    "end_time": "2026-06-15T10:30:00.000Z",
    "created_at": "2026-06-10T09:00:00.000Z",
    "last_modified_at": "2026-06-10T09:00:00.000Z",
    "room_name": "Room A",
    "google_calendar_event_id": null,
    "calendar_synced": false
  }
}

Mencatat pemesanan yang dilakukan di tempat lain

Endpoint yang sama, tanpa jenis acara: title dan start_time sudah cukup, dan duration_minutes mengatur berapa lama pemesanan berlangsung.

cURL

curl -X POST "https://api.youraiconnector.com/v1/appointments" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contact_id": "contact_abc123",
    "title": "Beginner guitar class",
    "start_time": "2026-06-15T10:00:00.000Z",
    "duration_minutes": 90,
    "external_reference": "class-slot-4812"
  }'

JavaScript

const res = await fetch("https://api.youraiconnector.com/v1/appointments", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    contact_id: "contact_abc123",
    title: "Beginner guitar class",
    start_time: "2026-06-15T10:00:00.000Z",
    duration_minutes: 90,
  }),
});
const data = await res.json();
console.log(data.appointment_id);

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/appointments",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={
        "contact_id": "contact_abc123",
        "title": "Beginner guitar class",
        "start_time": "2026-06-15T10:00:00.000Z",
        "duration_minutes": 90,
    },
)
print(res.json()["appointment_id"])

Respons (201 Created):

{
  "success": true,
  "appointment_id": "eFgH5678aBcD1234",
  "appointment": {
    "id": "eFgH5678aBcD1234",
    "contact_id": "contact_abc123",
    "event_id": null,
    "status": "Confirmed",
    "start_time": "2026-06-15T10:00:00.000Z",
    "end_time": "2026-06-15T11:30:00.000Z",
    "created_at": "2026-06-10T09:00:00.000Z",
    "last_modified_at": "2026-06-10T09:00:00.000Z",
    "summary": "Beginner guitar class",
    "google_calendar_event_id": null,
    "calendar_synced": false
  }
}

Pemesanan eksternal adalah janji temu biasa setelahnya: janji temu tersebut muncul di halaman Janji Temu dan di Daftar janji temu, dapat dijadwalkan ulang, dibatalkan, atau dihapus di aplikasi atau melalui API ini, email notifikasi pemesanan dikirim seperti biasa, dan pemicu otomatisasi Janji temu dipesan serta webhook akan aktif untuk janji temu tersebut seperti halnya pemesanan lain yang dilakukan melalui API. Satu-satunya perbedaan adalah yang disebutkan di atas — tidak ada pemeriksaan ketersediaan atau kapasitas, tidak ada sinkronisasi kalender, dan event_id tetap null.


Mendapatkan janji temu

GET /appointments/{appointmentId}

Mengembalikan satu janji temu berdasarkan ID-nya, termasuk status sinkronisasi kalendernya.

cURL

curl "https://api.youraiconnector.com/v1/appointments/aBcD1234eFgH5678" \
  -H "X-API-Key: YOUR_API_KEY"

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/appointments/aBcD1234eFgH5678",
  { headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.appointment);

Python

import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/appointments/aBcD1234eFgH5678",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
print(res.json()["appointment"])

Respons (200 OK):

{
  "success": true,
  "appointment": {
    "id": "aBcD1234eFgH5678",
    "contact_id": "contact_abc123",
    "event_id": "event_xyz789",
    "status": "Confirmed",
    "start_time": "2026-06-15T10:00:00.000Z",
    "end_time": "2026-06-15T10:30:00.000Z",
    "room_name": "Room A",
    "google_calendar_event_id": "abc123googleevent",
    "calendar_synced": true
  }
}

Mencantumkan janji temu

GET /appointments

Mencantumkan janji temu untuk akun Anda, yang terbaru terlebih dahulu, dengan penomoran halaman berbasis kursor.

Parameter kueri Wajib Deskripsi
contact_id Tidak Hanya mengembalikan janji temu untuk kontak ini. Daftar yang difilter berdasarkan kontak hanya menyertakan janji temu yang dikonfirmasi saja.
date Tidak Hanya mengembalikan janji temu pada hari kalender ini (YYYY-MM-DD). Memerlukan contact_id.
status Tidak Filter berdasarkan Confirmed atau Canceled. Hanya tersedia tanpa contact_id.
limit Tidak Ukuran halaman, bilangan bulat antara 1 dan 100. Default 50.
cursor Tidak Nilai next_cursor dari respons sebelumnya.

Beberapa aturan yang perlu diingat:

  • Tanpa filter, Anda mendapatkan setiap janji temu di akun, halaman demi halaman.
  • Berdasarkan kontak — atur contact_id untuk melihat janji temu yang dikonfirmasi dari satu kontak. Anda dapat mempersempitnya ke satu hari dengan juga menyertakan date.
  • Berdasarkan status — atur status (tanpa contact_id) untuk mencantumkan hanya janji temu Confirmed atau hanya Canceled di seluruh akun.
  • Filter date tanpa contact_id, atau status=Canceled bersama dengan contact_id, mengembalikan 400.

cURL

curl "https://api.youraiconnector.com/v1/appointments?contact_id=contact_abc123&date=2026-06-15" \
  -H "X-API-Key: YOUR_API_KEY"

JavaScript

const params = new URLSearchParams({
  contact_id: "contact_abc123",
  date: "2026-06-15",
});
const res = await fetch(
  `https://api.youraiconnector.com/v1/appointments?${params}`,
  { headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.appointments, data.next_cursor);

Python

import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/appointments",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"contact_id": "contact_abc123", "date": "2026-06-15"},
)
data = res.json()
print(data["appointments"], data["next_cursor"])

Respons (200 OK):

{
  "success": true,
  "appointments": [
    {
      "id": "aBcD1234eFgH5678",
      "contact_id": "contact_abc123",
      "event_id": "event_xyz789",
      "status": "Confirmed",
      "start_time": "2026-06-15T10:00:00.000Z",
      "end_time": "2026-06-15T10:30:00.000Z",
      "calendar_synced": true
    }
  ],
  "next_cursor": null
}

Untuk menelusuri hasil, teruskan next_cursor dari satu respons sebagai cursor untuk permintaan berikutnya. Lanjutkan sampai next_cursor bernilai null. Lihat Error & Penomoran Halaman untuk pola penomoran halaman bersama.


Memperbarui janji temu

PUT /appointments/{appointmentId}

Jadwalkan ulang janji temu atau ubah detailnya. Kirim hanya kolom yang ingin Anda ubah — setidaknya satu kolom wajib diisi. Gabungan waktu mulai dan berakhir harus tetap dalam urutan kronologis (end_time harus setelah start_time). Perubahan akan disinkronkan ke acara kalender yang tertaut secara otomatis.

Memindahkan pemesanan yang dikonfirmasi pada jenis acara (start_time atau room_name baru) diperiksa konfliknya seperti pemesanan baru: slot yang sudah penuh akan menjawab 409 dan tidak ada yang berubah, dan room_name yang tidak cocok dengan ruangan jenis acara mana pun akan menjawab 400. Kirim hanya start_time dan pemesanan akan mempertahankan durasinya. Jam buka dan periode pemberitahuan Anda sendiri tidak diterapkan di sini, sehingga Anda masih dapat memindahkan pemesanan ke waktu luang mana pun.

Bidang Deskripsi
start_time Waktu mulai baru, tanggal-waktu ISO 8601. Waktu yang dikirim tanpa offset zona waktu dibaca dalam zona waktu jenis acara (atau akun Anda), sama seperti saat memesan.
end_time Waktu berakhir baru, tanggal-waktu ISO 8601, dibaca dengan cara yang sama. Harus setelah waktu mulai.
room_name Nama ruangan atau sumber daya baru.
description Deskripsi baru, atau null untuk menghapusnya.
summary Ringkasan baru, atau null untuk menghapusnya.
external_reference Referensi baru (maksimal 255 karakter), atau null untuk menghapusnya. Referensi yang sudah dimiliki janji temu lain akan ditolak dengan 409 dan "code": "external_reference_taken".

cURL

curl -X PUT "https://api.youraiconnector.com/v1/appointments/aBcD1234eFgH5678" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "start_time": "2026-06-16T10:00:00.000Z",
    "end_time": "2026-06-16T10:30:00.000Z"
  }'

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/appointments/aBcD1234eFgH5678",
  {
    method: "PUT",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      start_time: "2026-06-16T10:00:00.000Z",
      end_time: "2026-06-16T10:30:00.000Z",
    }),
  }
);
const data = await res.json();
console.log(data.appointment);

Python

import requests

res = requests.put(
    "https://api.youraiconnector.com/v1/appointments/aBcD1234eFgH5678",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={
        "start_time": "2026-06-16T10:00:00.000Z",
        "end_time": "2026-06-16T10:30:00.000Z",
    },
)
print(res.json()["appointment"])

Respons (200 OK):

{
  "success": true,
  "appointment_id": "aBcD1234eFgH5678",
  "appointment": {
    "id": "aBcD1234eFgH5678",
    "contact_id": "contact_abc123",
    "event_id": "event_xyz789",
    "status": "Confirmed",
    "start_time": "2026-06-16T10:00:00.000Z",
    "end_time": "2026-06-16T10:30:00.000Z",
    "calendar_synced": true
  }
}

Membatalkan janji temu

POST /appointments/{appointmentId}/cancel

Membatalkan janji temu yang telah dikonfirmasi, dengan opsi untuk mencatat alasannya. Janji temu akan tetap ada di akun Anda dengan status Canceled, dan acara kalender yang tertaut akan dihapus secara otomatis di latar belakang. Membatalkan janji temu yang sudah dibatalkan akan mengembalikan 400.

Bidang Wajib Deskripsi
cancellation_reason Tidak Alasan pembatalan, disimpan pada janji temu.

cURL

curl -X POST "https://api.youraiconnector.com/v1/appointments/aBcD1234eFgH5678/cancel" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "cancellation_reason": "Client asked to reschedule next month"
  }'

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/appointments/aBcD1234eFgH5678/cancel",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      cancellation_reason: "Client asked to reschedule next month",
    }),
  }
);
const data = await res.json();
console.log(data.success);

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/appointments/aBcD1234eFgH5678/cancel",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={"cancellation_reason": "Client asked to reschedule next month"},
)
print(res.json()["success"])

Respons (200 OK):

{
  "success": true,
  "appointment_id": "aBcD1234eFgH5678"
}

Kirim ulang konfirmasi pemesanan

POST /appointments/{appointmentId}/resend-confirmation

Mengirimkan kembali konfirmasi pemesanan kepada kontak, misalnya saat mereka mengatakan pesan tersebut tidak pernah sampai atau masuk ke folder spam. Terdiri dari dua bagian, keduanya akan dikirim kecuali Anda menonaktifkan salah satunya: email konfirmasi (email yang sama dengan yang diterima kontak saat mereka memesan) dan, jika janji temu ada di Google Kalender Anda, undangan Google Kalender. Keduanya dikirim ke alamat email yang ada pada kontak.

Bidang Wajib Deskripsi
email Tidak false melewatkan email konfirmasi. Default-nya adalah true.
calendar_invite Tidak false melewatkan undangan Google Kalender. Default-nya adalah true.

Setiap bagian akan memberikan hasilnya masing-masing: sent, not_requested, no_contact_email, turned_off_for_event_type (tombol Kirim email janji temu ke kontak pada jenis acara sedang nonaktif), not_on_google_calendar, imported (janji temu yang diimpor dari kalender Anda tidak mendapatkan email konfirmasi) atau failed.

  • 200 jika setidaknya satu bagian berhasil dikirim. recipient adalah alamat tujuan pengiriman.
  • 409 untuk janji temu yang dibatalkan, janji temu yang sudah berlalu, atau pemesanan yang dilakukan melalui Zenchef, Formitable, OpenTable, TheFork, atau Trafft (sistem tersebut mengirimkan konfirmasinya sendiri). code adalah appointment_canceled, appointment_in_past, atau managed_by_provider.
  • 422 jika tidak ada yang dapat dikirim, dengan alasan yang tertera di error.

cURL

curl -X POST "https://api.youraiconnector.com/v1/appointments/aBcD1234eFgH5678/resend-confirmation" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/appointments/aBcD1234eFgH5678/resend-confirmation",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ calendar_invite: false }),
  }
);
const data = await res.json();
console.log(data.email, data.recipient);

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/appointments/aBcD1234eFgH5678/resend-confirmation",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={},
)
print(res.json())

Respons (200 OK):

{
  "success": true,
  "appointment_id": "aBcD1234eFgH5678",
  "email": "sent",
  "calendar_invite": "sent",
  "recipient": "jane@example.com"
}

Menghapus janji temu

DELETE /appointments/{appointmentId}

Menghapus janji temu dan referensinya secara permanen. Jika Anda hanya ingin membatalkan pemesanan namun tetap menyimpan catatannya, gunakan batal sebagai gantinya.

cURL

curl -X DELETE "https://api.youraiconnector.com/v1/appointments/aBcD1234eFgH5678" \
  -H "X-API-Key: YOUR_API_KEY"

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/appointments/aBcD1234eFgH5678",
  { method: "DELETE", headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.success);

Python

import requests

res = requests.delete(
    "https://api.youraiconnector.com/v1/appointments/aBcD1234eFgH5678",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
print(res.json()["success"])

Respons (200 OK):

{
  "success": true
}

Cantumkan Kalender Google Anda yang terhubung

GET /appointments/google-calendars

Mengembalikan Kalender Google yang tersedia di akun ini, langsung dari Google — berguna untuk menampilkan pemilih kalender kepada pemilik akun untuk menentukan kalender mana yang akan diimpor dari bawah, atau sekadar untuk mengonfirmasi bahwa koneksi sudah aktif.

Ini hanya berfungsi setelah akun menghubungkan Google Kalender (Pengaturan → Integrasi) dengan setidaknya akses baca. Jika belum, atau akses yang diberikan tidak lagi menyertakan cakupan baca-kalender, Anda akan mendapatkan 400 yang meminta Anda untuk (menghubungkan) kembali.

cURL

curl "https://api.youraiconnector.com/v1/appointments/google-calendars" \
  -H "X-API-Key: YOUR_API_KEY"

JavaScript

const res = await fetch("https://api.youraiconnector.com/v1/appointments/google-calendars", {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
console.log(data.data);

Python

import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/appointments/google-calendars",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
print(res.json()["data"])

Respons (200 OK):

{
  "success": true,
  "data": [
    {
      "id": "primary",
      "summary": "jane@example.com",
      "timeZone": "America/New_York",
      "accessRole": "owner",
      "primary": true
    },
    {
      "id": "abcdefg1234567890@group.calendar.google.com",
      "summary": "Bookings",
      "timeZone": "America/New_York",
      "accessRole": "writer"
    }
  ]
}

Setiap entri adalah bentuk CalendarListEntry milik Google sendiri, jadi nama bidang mengikuti camelCase Google, bukan snake_case API ini yang biasanya digunakan — itu adalah data Google yang diteruskan apa adanya, bukan data kami. Koneksi yang hilang atau dicabut akan mengembalikan 400 dengan kesalahan yang menjelaskan bahwa Google Kalender perlu (dihubungkan) kembali.


Impor acara dari Google Kalender

POST /appointments/import-calendar-events

Menarik acara yang sudah ada di Google Kalender kampanye atau Agen AI yang terhubung dan mengubahnya menjadi janji temu — berguna saat pertama kali Anda menghubungkan kalender yang sudah memiliki pemesanan. Proses ini mungkin memakan waktu (setiap acara melalui ekstraksi untuk mengetahui untuk siapa acara tersebut), jadi proses ini tidak pernah berjalan secara inline: permintaan akan mengantrekan pekerjaan latar belakang dan memberikan Anda job_id untuk melakukan polling.

Bidang Wajib Deskripsi
campaign_id Salah satu dari keduanya Kampanye yang kalender terhubungnya akan diimpor.
agent_id Salah satu dari keduanya Agen AI yang kalender terhubungnya akan diimpor.
identifier Ya "EMAIL" atau "PHONE_NUMBER" — bagian informasi kontak mana yang akan diekstrak dari setiap acara kalender untuk mencocokkan atau membuat kontak yang memilikinya.

Kirim tepat satu dari campaign_id / agent_id, jangan pernah keduanya dan jangan pernah tidak keduanya — kombinasi apa pun akan mengembalikan 400. Mana pun yang Anda kirim harus milik akun Anda, atau Anda akan mendapatkan 404.

cURL

curl -X POST "https://api.youraiconnector.com/v1/appointments/import-calendar-events?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "agent_abc123",
    "identifier": "EMAIL"
  }'

JavaScript

const res = await fetch("https://api.youraiconnector.com/v1/appointments/import-calendar-events", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    agent_id: "agent_abc123",
    identifier: "EMAIL",
  }),
});
const data = await res.json();
console.log(data.job_id);

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/appointments/import-calendar-events",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={"agent_id": "agent_abc123", "identifier": "EMAIL"},
)
print(res.json()["job_id"])

Respons (202 Accepted):

{
  "success": true,
  "job_id": "jK9mQ2xR7pL4wN1t",
  "status": "queued",
  "campaign_id": null,
  "agent_id": "agent_abc123"
}

campaign_id dan agent_id akan menggemakan kembali mana pun yang Anda kirim; yang lainnya akan selalu null.

Polling pekerjaan impor

GET /appointments/import-calendar-events/{jobId}

curl "https://api.youraiconnector.com/v1/appointments/import-calendar-events/jK9mQ2xR7pL4wN1t" \
  -H "X-API-Key: YOUR_API_KEY"

Respons (200 OK):

{
  "success": true,
  "job_id": "jK9mQ2xR7pL4wN1t",
  "status": "completed",
  "message": "Imported 12 events as appointments.",
  "error": null
}
status Arti
queued Belum diambil. Terus lakukan polling.
processing Impor sedang berjalan. Terus lakukan polling.
completed Selesai — message memiliki ringkasan singkat yang dapat dibaca manusia.
failed Terjadi kesalahan — error berisi alasannya.

GET pada jobId yang tidak ada (atau milik akun lain) akan mengembalikan 404.


Integrasi pemesanan eksternal (Zenchef / Formitable / OpenTable / TheFork / Trafft)

Zenchef dan Formitable adalah sistem reservasi restoran yang dapat digunakan oleh Agen AI Anda untuk memesan meja sungguhan; Trafft adalah platform penjadwalan untuk bisnis berbasis janji temu, yang dihubungkan satu kali per akun, bukan per restoran. Kedua platform restoran tersebut masing-masing memiliki widget pemesanan publik tanpa autentikasi (https://api.youraiconnector.com/v1/zenchef-widget/... dan https://api.youraiconnector.com/v1/formitable-widget/...) yang ditampilkan di dalam obrolan untuk pelanggan — rute widget tersebut adalah halaman HTML biasa yang dimaksudkan untuk dibuka di browser, bukan titik akhir API JSON, sehingga tidak didokumentasikan di sini. Berikut ini adalah titik akhir manajemen akun: memverifikasi apakah ID restoran milik pemegang akun, lalu menambah, memperbarui, atau menghapusnya.

Zenchef

Menghubungkan restoran Zenchef memerlukan verifikasi dua langkah, sehingga pemilik akun membuktikan bahwa mereka benar-benar mengelola restoran tersebut sebelum dihubungkan ke bot: pertama, periksa apakah ID ada (tanpa mengungkapkan namanya), kemudian minta mereka mengetikkan nama restoran sendiri dan verifikasi apakah cocok.

Langkah 1 — Periksa apakah ID restoran ada

POST /appointments/zenchef-restaurants/check

Bidang Wajib Deskripsi
restaurant_id Ya ID restoran Zenchef yang akan diperiksa.
curl -X POST "https://api.youraiconnector.com/v1/appointments/zenchef-restaurants/check?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "restaurant_id": "12345" }'

Respons (200 OK):

{
  "success": true,
  "data": { "exists": true, "requiresNameVerification": true }
}

exists: false berarti tidak ada restoran Zenchef yang memiliki ID tersebut — tidak ada lagi yang perlu dilakukan. Dibatasi hingga 10 pemeriksaan per 5 menit per akun; melebihi batas akan mengembalikan 429.

Langkah 2 — Verifikasi nama restoran

POST /appointments/zenchef-restaurants/verify-name

Bidang Wajib Deskripsi
restaurant_id Ya ID restoran Zenchef dari langkah 1.
user_input_name Ya Nama yang diketikkan oleh pemilik akun — dibandingkan dengan nama asli restoran di Zenchef (tidak peka terhadap huruf besar/kecil/spasi).
curl -X POST "https://api.youraiconnector.com/v1/appointments/zenchef-restaurants/verify-name?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "restaurant_id": "12345", "user_input_name": "The Blue Door Bistro" }'

Respons (200 OK):

{
  "success": true,
  "data": {
    "verified": true,
    "restaurantDetails": {
      "id": "12345",
      "name": "The Blue Door Bistro",
      "address": "1 Rue de Rivoli, Paris",
      "status": "active"
    }
  }
}

verified: false berarti nama tidak cocok — restaurantDetails dihilangkan, minta pemilik akun untuk mencoba lagi. Dibatasi hingga 3 percobaan per 5 menit (lebih ketat daripada pemeriksaan keberadaan, karena ini adalah langkah pembuktian yang sebenarnya). restaurant_id yang tidak lagi dapat diselesaikan di Zenchef akan mengembalikan 404.

Langkah 3 — Simpan restoran

POST /appointments/zenchef-restaurants

Bidang Wajib Deskripsi
restaurant_id Ya 1–64 karakter, huruf/angka/garis bawah/tanda hubung.
restaurant_name Ya Nama restoran terverifikasi dari langkah 2.
curl -X POST "https://api.youraiconnector.com/v1/appointments/zenchef-restaurants?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "restaurant_id": "12345", "restaurant_name": "The Blue Door Bistro" }'

Respons (201 Created):

{ "success": true, "data": { "restaurantId": "12345" } }

Perbarui restoran Zenchef yang disimpan

PUT /appointments/zenchef-restaurants/{restaurantId}

Bidang Wajib Deskripsi
restaurant_name Tidak Nama tampilan baru.
is_active Tidak Atur false untuk menghentikan bot agar tidak melakukan pemesanan pada restoran ini tanpa menghapusnya.
curl -X PUT "https://api.youraiconnector.com/v1/appointments/zenchef-restaurants/12345" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "is_active": false }'

Respons (200 OK): bentuk yang sama seperti respons simpan di atas.

Hapus restoran Zenchef

DELETE /appointments/zenchef-restaurants/{restaurantId}

curl -X DELETE "https://api.youraiconnector.com/v1/appointments/zenchef-restaurants/12345" \
  -H "X-API-Key: YOUR_API_KEY"

Respons (200 OK): { "success": true, "data": { "restaurantId": "12345" } }

restaurantId yang saat ini tidak ada di akun akan mengembalikan 404 saat diperbarui atau dihapus.

Formitable

Formitable tidak memerlukan bukti nama dua langkah seperti Zenchef — ID restorannya sudah dicakup per bisnis, jadi satu panggilan verifikasi sudah cukup. Formitable juga memiliki pencarian detail yang digunakan untuk menyimpan URL situs web restoran selama penyiapan.

Verifikasi ID restoran

POST /appointments/formitable-restaurants/verify

Bidang Wajib Deskripsi
restaurant_id Ya ID restoran Formitable.
language Tidak Tag bahasa untuk permintaan probe. Defaultnya adalah "nl".
curl -X POST "https://api.youraiconnector.com/v1/appointments/formitable-restaurants/verify?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "restaurant_id": "the-blue-door", "language": "en" }'

Respons (200 OK):

{
  "success": true,
  "data": {
    "verified": true,
    "restaurantDetails": {
      "restaurantId": "the-blue-door",
      "productCount": 4,
      "sampleProductTitle": "Dinner for two",
      "language": "en"
    }
  }
}

restaurant_id yang tidak dikenali oleh Formitable akan mengembalikan 404. Dibatasi hingga 10 percobaan per 5 menit per akun.

Dapatkan detail restoran

GET /appointments/formitable-restaurants/{restaurantId}/details?language=en

Mengambil profil publik restoran dari Formitable, termasuk situs webnya — digunakan untuk menyimpan URL situs web saat menyiapkan restoran. language adalah parameter kueri opsional, dengan default "en".

curl "https://api.youraiconnector.com/v1/appointments/formitable-restaurants/the-blue-door/details?language=en" \
  -H "X-API-Key: YOUR_API_KEY"

Respons (200 OK):

{
  "success": true,
  "data": {
    "uid": "the-blue-door",
    "name": "The Blue Door Bistro",
    "website": "https://thebluedoorbistro.com",
    "email": "info@thebluedoorbistro.com",
    "telephone": "+31201234567",
    "streetAddress": "Prinsengracht 1",
    "zipcode": "1015 AB",
    "city": "Amsterdam",
    "country": "Netherlands",
    "countryCode": "NL",
    "currency": "EUR"
  }
}

Simpan restoran

POST /appointments/formitable-restaurants

Bidang Wajib Deskripsi
restaurant_id Ya 1–64 karakter, huruf/angka/garis bawah/tanda hubung.
restaurant_name Ya Nama tampilan.
language Ya Tag bahasa ISO, contoh "en" atau "en-GB".
website_url Tidak Situs web restoran, dari pencarian detail di atas. Harus berupa http(s)://.
curl -X POST "https://api.youraiconnector.com/v1/appointments/formitable-restaurants?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "restaurant_id": "the-blue-door",
    "restaurant_name": "The Blue Door Bistro",
    "language": "en",
    "website_url": "https://thebluedoorbistro.com"
  }'

Respons (201 Created): { "success": true, "data": { "restaurantId": "the-blue-door" } }

Perbarui restoran Formitable yang disimpan

PUT /appointments/formitable-restaurants/{restaurantId}

Bidang Wajib Deskripsi
restaurant_name Tidak Nama tampilan baru.
language Tidak Tag bahasa ISO baru.
is_active Tidak Atur false untuk menghentikan bot agar tidak melakukan pemesanan pada restoran ini tanpa menghapusnya.
website_url Tidak URL situs web baru.
curl -X PUT "https://api.youraiconnector.com/v1/appointments/formitable-restaurants/the-blue-door" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "is_active": false }'

Respons (200 OK): bentuk yang sama seperti respons simpan di atas.

Hapus restoran Formitable

DELETE /appointments/formitable-restaurants/{restaurantId}

curl -X DELETE "https://api.youraiconnector.com/v1/appointments/formitable-restaurants/the-blue-door" \
  -H "X-API-Key: YOUR_API_KEY"

Respons (200 OK): { "success": true, "data": { "restaurantId": "the-blue-door" } }

restaurantId yang saat ini tidak ada di akun akan mengembalikan 404 saat diperbarui atau dihapus.

OpenTable

Restoran OpenTable dijangkau melalui kredensial mitra OpenTable platform, dan OpenTable hanya mengizinkan kredensial tersebut untuk melihat restoran yang telah menghubungkan daftar platform di dalam Marketplace Integrasi OpenTable. Jadi, seperti Formitable, satu panggilan verifikasi sudah cukup: ID Restoran yang dapat dijangkau (numerik “RID”) membuktikan bahwa restoran tersebut ada dan telah menghubungkan integrasi tersebut. Hingga daftar mitra OpenTable diaktifkan di platform, panggilan verifikasi akan menjawab 503.

Verifikasi restoran OpenTable

POST /appointments/opentable-restaurants/verify

Bidang Wajib Deskripsi
restaurant_id Ya ID Restoran OpenTable (RID), angka seperti 1038007.
curl -X POST "https://api.youraiconnector.com/v1/appointments/opentable-restaurants/verify?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "restaurant_id": "1038007" }'

Respons (200 OK):

{
  "success": true,
  "data": {
    "verified": true,
    "restaurantDetails": {
      "restaurantId": "1038007",
      "diningAreaCount": 2,
      "diningAreaNames": ["Main Room", "Garden"],
      "tableTypes": ["default", "outdoor", "bar"]
    }
  }
}

verified: false berarti tidak ada restoran OpenTable yang memiliki ID tersebut. 403 berarti restoran tersebut ada tetapi belum menghubungkan integrasi platform di dalam OpenTable. Dibatasi hingga 10 percobaan per 5 menit per akun.

Tambahkan restoran OpenTable

POST /appointments/opentable-restaurants

Bidang Wajib Deskripsi
restaurant_id Ya ID Restoran yang telah diverifikasi.
restaurant_name Ya Nama tampilan (label; juga nama yang digunakan AI untuk menyebut restoran).
website_url Tidak URL http(s) yang ditampilkan kepada tamu saat AI mengalihkan mereka ke restoran.
curl -X POST "https://api.youraiconnector.com/v1/appointments/opentable-restaurants?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "restaurant_id": "1038007", "restaurant_name": "The Blue Door", "website_url": "https://thebluedoor.example" }'

Respons (201 Created): { "success": true, "data": { "restaurantId": "1038007" } }

Perbarui restoran OpenTable yang disimpan

PUT /appointments/opentable-restaurants/{restaurantId}

Kirim salah satu dari restaurant_name, is_active (jeda dengan false) atau website_url (string kosong akan menghapusnya); bidang yang dihilangkan tidak akan diubah.

curl -X PUT "https://api.youraiconnector.com/v1/appointments/opentable-restaurants/1038007" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "is_active": false }'

Respons (200 OK): { "success": true, "data": { "restaurantId": "1038007" } }

Menghapus restoran OpenTable

DELETE /appointments/opentable-restaurants/{restaurantId}

curl -X DELETE "https://api.youraiconnector.com/v1/appointments/opentable-restaurants/1038007" \
  -H "X-API-Key: YOUR_API_KEY"

Respons (200 OK): { "success": true, "data": { "restaurantId": "1038007" } }

restaurantId yang saat ini tidak ada di akun akan mengembalikan 404 saat diperbarui.

TheFork

Restoran TheFork dijangkau melalui kredensial mitra TheFork milik platform, dan TheFork hanya mengizinkan kredensial tersebut untuk melihat restoran yang telah mengaktifkan mitra platform di akun TheFork mereka. Jadi, seperti Formitable dan OpenTable, satu panggilan verifikasi sudah cukup: ID Restoran yang dapat dijangkau membuktikan bahwa restoran tersebut ada dan mitra telah diaktifkan di sana. ID tersebut adalah UUID yang diberikan TheFork kepada restoran di TheFork Manager, dikirim sebagai string. Sampai TheFork menyetujui platform sebagai mitra dan menerbitkan kredensial, panggilan verifikasi akan menjawab 503 — lihat TheFork untuk mengetahui apa artinya saat ini.

Verifikasi restoran TheFork

POST /appointments/thefork-restaurants/verify

Bidang Wajib Deskripsi
restaurant_id Ya ID Restoran TheFork, sebuah UUID seperti 9f2a1c34-5b6d-4e7f-8a90-1b2c3d4e5f60.
curl -X POST "https://api.youraiconnector.com/v1/appointments/thefork-restaurants/verify?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "restaurant_id": "9f2a1c34-5b6d-4e7f-8a90-1b2c3d4e5f60" }'

Respons (200 OK):

{
  "success": true,
  "data": {
    "verified": true,
    "restaurantDetails": {
      "restaurantId": "9f2a1c34-5b6d-4e7f-8a90-1b2c3d4e5f60",
      "partySizes": [1, 2, 3, 4, 5, 6, 7, 8]
    }
  }
}

partySizes adalah ukuran grup yang diterima restoran secara daring selama 30 hari ke depan. 404 atau 403 berarti TheFork tidak memberikan kami restoran dengan ID tersebut — entah ID-nya salah, atau mitra platform belum diaktifkan di restoran tersebut; 400 berarti ID tersebut bukan UUID. Dibatasi hingga 10 percobaan per 5 menit per akun.

Tambahkan restoran TheFork

POST /appointments/thefork-restaurants

Bidang Wajib Deskripsi
restaurant_id Ya ID Restoran yang telah diverifikasi (UUID).
restaurant_name Ya Nama tampilan (label; juga nama yang digunakan AI untuk menyebut restoran).
website_url Tidak URL http(s) yang ditampilkan kepada tamu saat AI mengalihkan mereka ke restoran.
curl -X POST "https://api.youraiconnector.com/v1/appointments/thefork-restaurants?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "restaurant_id": "9f2a1c34-5b6d-4e7f-8a90-1b2c3d4e5f60", "restaurant_name": "The Blue Door", "website_url": "https://thebluedoor.example" }'

Respons (201 Created): { "success": true, "data": { "restaurantId": "9f2a1c34-5b6d-4e7f-8a90-1b2c3d4e5f60" } }

Perbarui restoran TheFork yang disimpan

PUT /appointments/thefork-restaurants/{restaurantId}

Kirim salah satu dari restaurant_name, is_active (jeda dengan false) atau website_url (string kosong akan menghapusnya); bidang yang dihilangkan tidak akan diubah.

curl -X PUT "https://api.youraiconnector.com/v1/appointments/thefork-restaurants/9f2a1c34-5b6d-4e7f-8a90-1b2c3d4e5f60" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "is_active": false }'

Respons (200 OK): { "success": true, "data": { "restaurantId": "9f2a1c34-5b6d-4e7f-8a90-1b2c3d4e5f60" } }

Menghapus restoran TheFork

DELETE /appointments/thefork-restaurants/{restaurantId}

curl -X DELETE "https://api.youraiconnector.com/v1/appointments/thefork-restaurants/9f2a1c34-5b6d-4e7f-8a90-1b2c3d4e5f60" \
  -H "X-API-Key: YOUR_API_KEY"

Respons (200 OK): { "success": true, "data": { "restaurantId": "9f2a1c34-5b6d-4e7f-8a90-1b2c3d4e5f60" } }

restaurantId yang saat ini tidak ada di akun akan mengembalikan 404 saat diperbarui atau dihapus.

Trafft

Trafft dihubungkan satu kali untuk seluruh akun, bukan per lokasi: satu alamat perusahaan ditambah kredensial API dari panel admin Trafft (Features & Integrations → API & Connectors, bagian dari paket Bisnis Trafft). Panggilan koneksi memeriksa kredensial tersebut terhadap Trafft sebelum menyimpan apa pun, sehingga alamat yang salah, kredensial yang salah, atau paket tanpa akses API akan gagal di sini, bukan saat percakapan pelanggan. Klien rahasia (client secret) disimpan dalam bentuk terenkripsi dan tidak pernah dikembalikan oleh titik akhir mana pun.

Ketiga panggilan tulis (POST, PUT, DELETE) memerlukan izin edit Integrasi; status GET memerlukan izin view Integrasi.

Hubungkan Trafft

POST /appointments/trafft/connect

Bidang Wajib Deskripsi
subdomain Ya Alamat perusahaan — bagian sebelum .admin.trafft.com di URL tempat Anda masuk, contoh: acme. Alamat lengkap diterima dan akan disederhanakan ke nilai yang sama.
client_id Ya Client ID dari halaman API & Connectors Trafft.
client_secret Ya Client Secret dari halaman yang sama. Disimpan dalam bentuk terenkripsi, tidak pernah dikembalikan.
company_name Tidak Label untuk daftar Anda sendiri.
curl -X POST "https://api.youraiconnector.com/v1/appointments/trafft/connect?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "subdomain": "acme",
    "client_id": "YOUR_TRAFFT_CLIENT_ID",
    "client_secret": "YOUR_TRAFFT_CLIENT_SECRET",
    "company_name": "Acme Salon"
  }'

Respons (200 OK):

{
  "success": true,
  "data": {
    "subdomain": "acme",
    "service_count": 12,
    "employee_count": 4,
    "location_count": 2
  }
}

Jumlah data dikembalikan dari Trafft selama pemeriksaan — ini adalah cara tercepat untuk mengonfirmasi bahwa kredensial tersebut mengarah ke akun yang Anda maksud.

Dapatkan status koneksi

GET /appointments/trafft

curl "https://api.youraiconnector.com/v1/appointments/trafft" \
  -H "X-API-Key: YOUR_API_KEY"

Respons (200 OK):

{
  "success": true,
  "data": {
    "connected": true,
    "subdomain": "acme",
    "hostname": "acme.admin.trafft.com",
    "client_id": "YOUR_TRAFFT_CLIENT_ID",
    "company_name": "Acme Salon",
    "is_active": true,
    "service_count": 12,
    "employee_count": 4,
    "location_count": 2
  }
}

connected: false berarti belum ada yang disiapkan. Client secret tidak pernah disertakan dalam respons ini.

Perbarui koneksi

PUT /appointments/trafft

Bidang Wajib Deskripsi
is_active Tidak Atur false untuk menjeda — AI berhenti membuat pemesanan ke Trafft, koneksi tetap ada. true melanjutkannya kembali.
company_name Tidak Label baru.
curl -X PUT "https://api.youraiconnector.com/v1/appointments/trafft" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "is_active": false }'

Respons (200 OK): objek koneksi yang sama seperti GET di atas.

Putuskan Koneksi Trafft

DELETE /appointments/trafft

curl -X DELETE "https://api.youraiconnector.com/v1/appointments/trafft" \
  -H "X-API-Key: YOUR_API_KEY"

Respons (200 OK): { "success": true }

Memutuskan koneksi hanya menghapus kredensial yang tersimpan. Janji temu yang sudah ada di Trafft tidak akan terpengaruh.

Bentuk kesalahan pada semua endpoint Zenchef/Formitable/OpenTable/TheFork: tidak seperti bagian lain di halaman ini, kesalahan di sini membawa statusnya dua kali — sekali sebagai status HTTP dan sekali sebagai error_code di dalam body — sebagai contoh { "success": false, "error": "Restaurant not found", "error_code": 404 }. Tangani dengan cara yang sama seperti kesalahan lainnya: periksa success, baca error untuk pesannya.


Kesalahan API Janji Temu

Endpoint janji temu mengembalikan amplop kesalahan standar:

{
  "success": false,
  "error": "Appointment not found"
}
Status Kapan ini terjadi pada endpoint janji temu
400 Bidang wajib hilang atau tidak valid — misalnya start_time yang salah, end_time tidak setelah start_time, kombinasi filter tidak valid, tidak ada bidang untuk diperbarui, atau janji temu yang sudah dibatalkan. Saat memesan: tidak ada event_id atau title yang dikirim, keduanya dikirim bersamaan, end_time dan duration_minutes keduanya dikirim, title lebih dari 200 karakter, atau duration_minutes di luar 1–1440.
404 Janji temu, kontak, atau jenis acara tidak ditemukan.
409 Slot waktu yang diminta sudah terisi (konflik pemesanan), atau saat pembaruan, external_reference sudah digunakan oleh janji temu lain.

Kode bersama yang dapat dikembalikan oleh setiap endpoint — 401, 403 (paket Anda tidak menyertakan akses API), 429 (batas kecepatan) dan 500 — tercantum beserta panduan percobaan ulang di Kesalahan & Penomoran Halaman.



Langkah berikutnya

  • Kontak — buat dan cari kontak yang Anda buatkan pemesanannya.
  • Pesan & Percakapan — kirim konfirmasi atau pengingat kepada kontak.
  • Webhook — dapatkan pemberitahuan saat janji temu berubah.