Spotkania
Interfejs API Appointments umożliwia rezerwowanie wizyt dla Twoich kontaktów w ramach typów wydarzeń, a następnie ich pobieranie, wyświetlanie, aktualizowanie, anulowanie lub usuwanie. Odpowiada również na pytanie, które pojawia się jako pierwsze w większości procesów rezerwacji — które terminy są faktycznie wolne — oraz obsługuje stronę kalendarza: wyświetlanie połączonych kalendarzy Google i importowanie wydarzeń, które już się w nich znajdują. Gdy połączenie z Kalendarzem Google jest aktywne, pasujące wydarzenie w kalendarzu jest tworzone i automatycznie synchronizowane w tle. Restauracje korzystające z systemów Zenchef, Formitable, OpenTable lub TheFork do własnych rezerwacji mogą być również zweryfikowane i połączone w tym miejscu, dzięki czemu Agent AI rezerwuje rzeczywiste stoliki zamiast wewnętrznych wizyt — firmy usługowe prowadzące harmonogram w Trafft mogą połączyć się w ten sam sposób.
Wszystkie ścieżki na tej stronie są względne względem podstawowego adresu URL https://api.youraiconnector.com/v1. Każde żądanie wymaga Twojego klucza API — zobacz Uwierzytelnianie, aby uzyskać pełną listę sposobów jego przesyłania. Poniższe przykłady wykorzystują nagłówek X-API-Key, a jeden z przykładów cURL pokazuje również formularz zapytania ?apiKey=.
Wydarzenia a spotkania: Typ wydarzenia to definicja dostępnego terminu (rodzaj spotkania, jego długość, sale). Spotkanie to jedna zarezerwowana instancja typu wydarzenia dla konkretnego kontaktu. Spotkanie rezerwuje się poprzez odwołanie do kontaktu oraz typu wydarzenia.
Obiekt spotkania
Każdy punkt końcowy, który zwraca spotkanie, używa tego samego formatu:
| Pole | Opis |
|---|---|
id |
Unikalny identyfikator spotkania. |
contact_id |
Identyfikator kontaktu, z którym umówiono spotkanie. |
event_id |
Identyfikator typu wydarzenia, na który umówiono spotkanie. null dla rezerwacji zewnętrznych — spotkań zarejestrowanych bez typu wydarzenia. |
status |
Confirmed lub Canceled. |
start_time |
Początek spotkania, ISO 8601 w UTC. |
end_time |
Koniec spotkania, ISO 8601 w UTC. |
created_at |
Czas utworzenia spotkania. |
last_modified_at |
Czas ostatniej zmiany spotkania. |
room_name |
Pokój lub zasób, w którym zarezerwowano spotkanie, gdy typ wydarzenia korzysta z pokoi. |
description |
Dowolny opis spotkania. |
summary |
Krótkie podsumowanie lub tytuł. W przypadku rezerwacji zewnętrznej jest to title, z którym została zarejestrowana. |
external_reference |
Twój własny identyfikator tej rezerwacji (z Twojego systemu CRM lub systemu rezerwacji), w takiej formie, w jakiej go przesłałeś, lub null. |
cancelation_reason |
Powód podany przy anulowaniu spotkania, jeśli istnieje. |
google_calendar_event_id |
Identyfikator powiązanego wydarzenia w Kalendarzu Google. Ustawiany po zakończeniu synchronizacji kalendarza; null, gdy żaden kalendarz nie jest połączony lub gdy synchronizacja jest w toku. |
calendar_synced |
true, gdy spotkanie zostanie powiązane z wydarzeniem w kalendarzu. |
imported |
true, gdy spotkanie zostało zaimportowane z zewnętrznego kalendarza zamiast bezpośredniego umówienia. |
is_recurring |
true, gdy spotkanie jest częścią serii cyklicznej. |
recurrence_frequency |
Częstotliwość powtarzania spotkania, jeśli jest cykliczne. |
recurring_event_id |
Identyfikator serii cyklicznej, do której należy to spotkanie. |
recurring_interval |
Interwał między powtórzeniami, jeśli spotkanie jest cykliczne. |
recurring_sequence |
Pozycja tego spotkania w serii cyklicznej. |
end_after_x_occurrences |
Liczba wystąpień, po których seria cykliczna się kończy. |
booking_provider |
System źródłowy, z którego pochodzi rezerwacja, jeśli została dokonana za pośrednictwem połączonego dostawcy rezerwacji. |
O synchronizacji kalendarza: Bezpośrednio po zarezerwowaniu lub zmianie spotkania pole
google_calendar_event_idmoże nadal mieć wartośćnull, acalendar_syncedmoże byćfalse, ponieważ synchronizacja odbywa się w tle chwilę później. Pobierz spotkanie ponownie po krótkim czasie, aby zobaczyć wypełnione pola kalendarza.
Znajdź dostępne terminy
GET /appointments/available-slots
Zwraca terminy, które są faktycznie wolne dla danego typu wydarzenia pomiędzy dwoma punktami w czasie. Jest to zazwyczaj pierwsze wywołanie w procesie rezerwacji: wyświetl te terminy, pozwól użytkownikowi wybrać jeden z nich, a następnie wyślij wybrany czas do Zarezerwuj spotkanie.
Odpowiedź uwzględnia już godziny otwarcia i długość slotu danego typu wydarzenia, jego sale, spotkania, które już zostały zarezerwowane, oraz wszystko, co jest zablokowane w połączonych Kalendarzach Google — więc każdy zwrócony termin jest terminem, który możesz zarezerwować.
| Parametr zapytania | Wymagany | Opis |
|---|---|---|
event_id |
Tak | Typ wydarzenia do sprawdzenia. Musi należeć do Twojego konta. Znajdziesz go w aplikacji, otwierając typ wydarzenia na stronie Spotkania (zakładka Typy wydarzeń): okno edycji pokazuje jego Identyfikator typu wydarzenia wraz z przyciskiem kopiowania. |
start_time |
Tak | Początek okna czasowego, dla którego chcesz uzyskać dostępne terminy, w formacie daty i godziny ISO 8601. |
end_time |
Tak | Koniec okna czasowego, w formacie daty i godziny ISO 8601. Uwzględniany jest cały dzień końcowy. |
Wyniki są pogrupowane według dni — a w przypadku, gdy typ wydarzenia korzysta z sal, jedna grupa na salę na dzień:
| Pole | Opis |
|---|---|
date |
Dzień, którego dotyczy grupa, zapisany jako DD/MM/YYYY. |
day |
Nazwa dnia tygodnia małymi literami, na przykład monday. |
room_name |
Sala lub zasób, do którego należy ta grupa, jeśli typ wydarzenia korzysta z sal. |
available_slots |
Dostępne bloki rezerwacyjne w tym dniu, od najwcześniejszego. |
Każdy wpis w available_slots zawiera:
| Pole | Opis |
|---|---|
start_time |
Początek bloku jako HH:mm. |
end_time |
Koniec bloku jako HH:mm. |
available |
true — zwracany jest tylko wolny czas. |
spots_left |
Ile rezerwacji jeszcze mieści się w tym bloku. Obecne tylko w typach wydarzeń, które przyjmują więcej niż jedną rezerwację na slot. |
Czasy są lokalne dla typu wydarzenia, a nie w UTC.
date,start_timeorazend_timeto wartości zegarowe w strefie czasowej typu wydarzenia (jego nadpisaniu lub strefie czasowej Twojego konta, jeśli nie określono inaczej). Zarezerwuj spotkanie oczekuje momentu w formacie ISO 8601 UTC, więc przekonwertuj wybrany termin przed jego wysłaniem.
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"])
Odpowiedź (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 }
]
}
]
}
Dzień, w którym nie ma wolnych terminów, po prostu się nie pojawia. Brak event_id, start_time lub end_time zwraca 400; typ wydarzenia, którego nie ma na Twoim koncie, zwraca 404.
Zarezerwuj spotkanie
POST /appointments
Tworzy spotkanie dla jednego z Twoich kontaktów. Można to zrobić na dwa sposoby:
- Dla jednego z Twoich typów wydarzeń — wyślij
event_id, a rezerwacja zadziała dokładnie tak, jak zawsze: dostępność i pojemność są przestrzegane, czas zakończenia jest obliczany na podstawie czasu trwania slotu typu wydarzenia, a spotkanie synchronizuje się z Twoim Kalendarzem Google, jeśli jest on połączony. - Jako rezerwacja zewnętrzna — pomiń
event_idi wyślij zamiast tegotitle. Rejestruje to rezerwację dokonaną w innym miejscu (Twój własny CRM, harmonogram zajęć, inne narzędzie do rezerwacji), dzięki czemu pojawia się ona na stronie Spotkania obok pozostałych.
Rezerwacja typu wydarzenia z pokojami musi dotyczyć czasu, który Znajdź dostępne terminy by zaoferował: w godzinach pracy pokoju, poza okresem wyprzedzenia, w zakresie wyprzedzenia, z jakim można rezerwować dany typ wydarzenia, w siatce terminów, nie w przeszłości i nie zablokowany w połączonym kalendarzu. Każdy inny czas jest odrzucany za pomocą 400 i nic nie jest tworzone. Podobnie jest w przypadku room_name, który nie pasuje do żadnego z pokoi typu wydarzenia (komunikat zawiera listę prawidłowych nazw). Czasy buforowe ustawione dla typu wydarzenia (Bufor przed i Bufor po w edytorze typu wydarzenia, odpowiednio buffer_before i buffer_after w minutach) są utrzymywane jako wolne wokół każdej rezerwacji.
Rezerwacja typu wydarzenia jest również sprawdzana pod kątem konfliktów: jeśli termin jest już zajęty, żądanie kończy się niepowodzeniem z 409 i nic nie jest tworzone. Rezerwacja zewnętrzna nie ma przypisanego typu wydarzenia, więc nic nie jest sprawdzane pod kątem Twojej dostępności lub pojemności i nic nie jest synchronizowane z kalendarzem.
Ponawianie prób jest bezpieczne. Jeśli ten sam kontakt ma już potwierdzoną rezerwację tego samego typu wydarzenia w tym samym czasie rozpoczęcia (w tym samym pokoju, jeśli go nazwiesz), na przykład dlatego, że Twoje pierwsze żądanie przekroczyło limit czasu po jego przetworzeniu, otrzymasz tę rezerwację z powrotem z 200 i "replayed": true zamiast drugiej rezerwacji lub 409.
external_reference działa jako klucz idempotentności. Jest unikalny w ramach Twojego konta: jeśli spotkanie już posiada przesłany identyfikator, zwracane jest to spotkanie wraz z 200 i "replayed": true, a nic nowego nie jest tworzone, nawet jeśli ponowienie zawiera inny czas lub kontakt, niezależnie od statusu tego spotkania. Używaj go do płatnych rezerwacji (przesyłając swój identyfikator płatności lub zamówienia) i przesyłaj nowy identyfikator dla rzeczywiście nowej rezerwacji.
| Pole | Wymagane | Opis |
|---|---|---|
contact_id |
Tak | Identyfikator kontaktu, dla którego dokonywana jest rezerwacja. Musi należeć do Twojego konta. |
start_time |
Tak | Pożądany czas rozpoczęcia w formacie ISO 8601. Czas przesłany bez przesunięcia strefy czasowej jest odczytywany w strefie czasowej Twojego konta. |
event_id |
Nie | Identyfikator typu wydarzenia, dla którego dokonywana jest rezerwacja. Musi należeć do Twojego konta. Pozostaw puste, aby zarejestrować rezerwację zewnętrzną. |
title |
Tylko bez event_id |
Nazwa, pod którą spotkanie jest wyświetlane na stronie Spotkań — na przykład nazwa zajęć. Do 200 znaków. Jest zwracana jako summary. |
end_time |
Nie | Koniec rezerwacji zewnętrznej w formacie ISO 8601, późniejszy niż start_time. Niepotrzebne przy event_id: czas zakończenia jest wtedy pobierany z czasu trwania slotu typu wydarzenia. |
duration_minutes |
Nie | Czas trwania rezerwacji zewnętrznej, liczba całkowita od 1 do 1440 minut. Użyj tego lub end_time, nie obu jednocześnie. Jeśli nie podano żadnego, rezerwacja zewnętrzna trwa 60 minut. |
description |
Nie | Dowolne notatki przechowywane wraz ze spotkaniem. |
room_name |
Nie | Nazwa sali lub zasobu, gdy typ wydarzenia korzysta z sal. Musi pasować do jednej z sal. Pozostaw puste, aby zarezerwować pierwszą wolną salę. |
external_reference |
Nie | Twój własny identyfikator tej rezerwacji, dzięki któremu możesz dopasować ją do rekordu w swoim systemie CRM lub systemie rezerwacji. Do 255 znaków. Jest zwracany przy każdym odczycie oraz w webhookach Appointment Booked, Cancelled i Rescheduled. Unikalny w ramach Twojego konta: identyfikator, który jest już w użyciu, zwraca istniejące spotkanie zamiast tworzyć nową rezerwację (patrz wyżej). |
Wyślij event_id i title razem lub żadnego z nich, a żądanie zwróci 400 — podobnie jak wysłanie zarówno end_time, jak i duration_minutes.
cURL (używając formularza zapytania ?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"])
Odpowiedź (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
}
}
Rejestrowanie rezerwacji dokonanej w innym miejscu
Ten sam punkt końcowy, bez typu wydarzenia: wystarczy title i start_time, a duration_minutes określa, jak długo trwa rezerwacja.
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"])
Odpowiedź (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
}
}
Rezerwacje zewnętrzne są od tego momentu zwykłymi spotkaniami: pojawiają się na stronie Spotkania oraz w Liście spotkań, można je zmieniać, anulować lub usuwać w aplikacji lub przez to API, e-mail z powiadomieniem o rezerwacji jest wysyłany jak zwykle, a wyzwalacz automatyzacji Spotkanie umówione oraz webhook uruchamiają się dla nich tak samo, jak dla każdej innej rezerwacji dokonanej przez API. Jedyne różnice to te powyżej — brak sprawdzania dostępności lub pojemności, brak synchronizacji z kalendarzem, a event_id pozostaje null.
Uzyskaj spotkanie
GET /appointments/{appointmentId}
Zwraca pojedyncze spotkanie na podstawie jego identyfikatora, w tym jego stan synchronizacji z kalendarzem.
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"])
Odpowiedź (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
}
}
Wyświetl listę spotkań
GET /appointments
Wyświetla listę spotkań dla Twojego konta, od najnowszego, z wykorzystaniem stronicowania opartego na kursorze.
| Parametr zapytania | Wymagany | Opis |
|---|---|---|
contact_id |
Nie | Zwraca tylko spotkania dla tego kontaktu. Listy filtrowane według kontaktu zawierają tylko potwierdzone spotkania |
date |
Nie | Zwraca tylko spotkania z tego dnia kalendarzowego (YYYY-MM-DD). Wymaga contact_id. |
status |
Nie | Filtruj według Confirmed lub Canceled. Dostępne tylko bez contact_id. |
limit |
Nie | Rozmiar strony, liczba całkowita od 1 do 100. Domyślnie 50. |
cursor |
Nie | Wartość next_cursor z poprzedniej odpowiedzi. |
Kilka zasad, o których warto pamiętać:
- Bez filtrów otrzymasz każde spotkanie na koncie, strona po stronie.
- Według kontaktu — ustaw
contact_id, aby zobaczyć potwierdzone spotkania danego kontaktu. Możesz zawęzić to do jednego dnia, przekazując równieżdate. - Według statusu — ustaw
status(bezcontact_id), aby wyświetlić tylko spotkaniaConfirmedlub tylkoCanceledna całym koncie. - Filtr
datebezcontact_idlubstatus=Canceledwraz zcontact_idzwraca400.
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"])
Odpowiedź (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
}
Aby przeglądać wyniki, przekaż next_cursor z jednej odpowiedzi jako cursor w następnym żądaniu. Kontynuuj, aż next_cursor będzie null. Zobacz Błędy i stronicowanie, aby poznać wspólny wzorzec stronicowania.
Zaktualizuj spotkanie
PUT /appointments/{appointmentId}
Zmień termin spotkania lub edytuj jego szczegóły. Wyślij tylko te pola, które chcesz zmienić — wymagane jest co najmniej jedno. Połączony czas rozpoczęcia i zakończenia musi zachowywać porządek chronologiczny (end_time musi być po start_time). Zmiany są automatycznie synchronizowane z powiązanym wydarzeniem w kalendarzu.
Przeniesienie potwierdzonej rezerwacji typu wydarzenia (nowy start_time lub room_name) jest sprawdzane pod kątem konfliktów tak samo jak nowa rezerwacja: termin, który jest już zajęty, zwraca 409 i nic się nie zmienia, a room_name, który nie pasuje do żadnego z pokoi typu wydarzenia, zwraca 400. Wyślij tylko start_time, a rezerwacja zachowa swoją długość. Twoje własne godziny otwarcia i okres wyprzedzenia nie są tutaj stosowane, więc nadal możesz przenieść rezerwację na dowolny wolny czas.
| Pole | Opis |
|---|---|
start_time |
Nowy czas rozpoczęcia, format ISO 8601. Czas przesłany bez przesunięcia strefy czasowej jest odczytywany w strefie czasowej typu wydarzenia (lub Twojego konta), tak samo jak przy rezerwacji. |
end_time |
Nowy czas zakończenia, format ISO 8601, odczytywany w ten sam sposób. Musi być późniejszy niż czas rozpoczęcia. |
room_name |
Nowa nazwa sali lub zasobu. |
description |
Nowy opis lub null, aby go wyczyścić. |
summary |
Nowe podsumowanie lub null, aby je wyczyścić. |
external_reference |
Nowy identyfikator (do 255 znaków) lub null, aby go wyczyścić. Identyfikator, który posiada już inne spotkanie, zostanie odrzucony z 409 i "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"])
Odpowiedź (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
}
}
Anulowanie spotkania
POST /appointments/{appointmentId}/cancel
Anuluje potwierdzone spotkanie, opcjonalnie rejestrując powód. Spotkanie pozostaje na Twoim koncie ze statusem Canceled, a powiązane wydarzenie w kalendarzu jest automatycznie usuwane w tle. Anulowanie już anulowanego spotkania zwraca 400.
| Pole | Wymagane | Opis |
|---|---|---|
cancellation_reason |
Nie | Powód anulowania, zapisywany w spotkaniu. |
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"])
Odpowiedź (200 OK):
{
"success": true,
"appointment_id": "aBcD1234eFgH5678"
}
Wyślij ponownie potwierdzenie rezerwacji
POST /appointments/{appointmentId}/resend-confirmation
Wysyła kontaktowi ponownie potwierdzenie rezerwacji, na przykład gdy twierdzi on, że wiadomość nie dotarła lub trafiła do spamu. Składa się z dwóch części, z których obie są wysyłane, chyba że wyłączysz jedną z nich: e-mail z potwierdzeniem (taki sam, jaki kontakt otrzymał w momencie rezerwacji) oraz, jeśli spotkanie znajduje się w Twoim Kalendarzu Google, zaproszenie z Kalendarza Google. Obie wiadomości są wysyłane na adres e-mail kontaktu.
| Pole | Wymagane | Opis |
|---|---|---|
email |
Nie | false pomija e-mail z potwierdzeniem. Domyślnie true. |
calendar_invite |
Nie | false pomija zaproszenie z Kalendarza Google. Domyślnie true. |
Każda część zwraca własny wynik: sent, not_requested, no_contact_email, turned_off_for_event_type (przełącznik Wyślij e-mail o spotkaniu do kontaktu w typie wydarzenia jest wyłączony), not_on_google_calendar, imported (spotkania zaimportowane z Twojego kalendarza nie otrzymują e-maila z potwierdzeniem) lub failed.
200gdy wysłano przynajmniej jedną część.recipientto adres, na który została wysłana.409w przypadku anulowanego spotkania, spotkania, które już się odbyło, lub rezerwacji dokonanej przez Zenchef, Formitable, OpenTable, TheFork lub Trafft (ten system wysyła własne potwierdzenie).codetoappointment_canceled,appointment_in_pastlubmanaged_by_provider.422gdy nie można było nic wysłać, z podaniem przyczyny werror.
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())
Odpowiedź (200 OK):
{
"success": true,
"appointment_id": "aBcD1234eFgH5678",
"email": "sent",
"calendar_invite": "sent",
"recipient": "jane@example.com"
}
Usuwanie spotkania
DELETE /appointments/{appointmentId}
Trwale usuwa spotkanie i jego odniesienia. Jeśli chcesz tylko odwołać rezerwację, zachowując rekord, użyj zamiast tego anuluj.
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"])
Odpowiedź (200 OK):
{
"success": true
}
Wyświetl swoje połączone Kalendarze Google
GET /appointments/google-calendars
Zwraca kalendarze Google dostępne na tym koncie, bezpośrednio z Google — przydatne do pokazania właścicielowi konta selektora kalendarza, z którego ma importować dane, lub po prostu do potwierdzenia, że połączenie jest aktywne.
Działa to tylko wtedy, gdy konto ma połączony Kalendarz Google (Ustawienia → Integracje) z co najmniej dostępem do odczytu. Jeśli tak nie jest lub przyznany dostęp nie obejmuje już zakresu odczytu kalendarza, otrzymasz 400 z informacją o konieczności (ponownego) połączenia go.
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"])
Odpowiedź (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"
}
]
}
Każdy wpis ma własny format CalendarListEntry Google, więc nazwy pól są zgodne z camelCase Google, a nie ze standardowym snake_case tego API — są to dane Google przekazane w niezmienionej formie, a nie nasze. Brakujące lub cofnięte połączenie zwraca 400 z błędem wyjaśniającym, że Kalendarz Google wymaga (ponownego) połączenia.
Importuj wydarzenia z Kalendarza Google
POST /appointments/import-calendar-events
Pobiera wydarzenia znajdujące się już w połączonym(-ych) Kalendarzu(-ach) Google kampanii lub Agenta AI i zamienia je w spotkania — przydatne przy pierwszym łączeniu kalendarza, który ma już istniejące rezerwacje. Może to chwilę potrwać (każde wydarzenie przechodzi przez proces ekstrakcji, aby ustalić, dla kogo jest przeznaczone), więc nigdy nie działa w trybie inline: żądanie dodaje zadanie do kolejki w tle i zwraca job_id do odpytywania.
| Pole | Wymagane | Opis |
|---|---|---|
campaign_id |
Jedno z tych dwóch | Kampania, z której połączonych kalendarzy importować dane. |
agent_id |
Jedno z tych dwóch | Agent AI, z którego połączonych kalendarzy importować dane. |
identifier |
Tak | "EMAIL" lub "PHONE_NUMBER" — który element danych kontaktowych wyodrębnić z każdego wydarzenia w kalendarzu, aby dopasować lub utworzyć kontakt, do którego ono należy. |
Wyślij dokładnie jedno z campaign_id / agent_id, nigdy oba i nigdy żadnego — każda inna kombinacja zwraca 400. To, które wyślesz, musi należeć do Twojego konta, w przeciwnym razie otrzymasz 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"])
Odpowiedź (202 Accepted):
{
"success": true,
"job_id": "jK9mQ2xR7pL4wN1t",
"status": "queued",
"campaign_id": null,
"agent_id": "agent_abc123"
}
campaign_id i agent_id zwracają to, które wysłałeś; drugie jest zawsze null.
Odpytywanie zadania importu
GET /appointments/import-calendar-events/{jobId}
curl "https://api.youraiconnector.com/v1/appointments/import-calendar-events/jK9mQ2xR7pL4wN1t" \
-H "X-API-Key: YOUR_API_KEY"
Odpowiedź (200 OK):
{
"success": true,
"job_id": "jK9mQ2xR7pL4wN1t",
"status": "completed",
"message": "Imported 12 events as appointments.",
"error": null
}
status |
Znaczenie |
|---|---|
queued |
Jeszcze nieodebrane. Kontynuuj odpytywanie. |
processing |
Import jest w toku. Kontynuuj odpytywanie. |
completed |
Gotowe — message zawiera krótkie, czytelne podsumowanie. |
failed |
Coś poszło nie tak — error zawiera przyczynę. |
GET dla jobId, który nie istnieje (lub należy do innego konta), zwraca 404.
Zewnętrzne integracje rezerwacyjne (Zenchef / Formitable / OpenTable / TheFork / Trafft)
Zenchef i Formitable to systemy rezerwacji restauracji, za pośrednictwem których Twój Agent AI może rezerwować prawdziwe stoliki; Trafft to platforma do planowania dla firm usługowych, łączona raz na konto, a nie dla każdej restauracji z osobna. Obie platformy restauracyjne posiadają publiczny, nieuwierzytelniony widżet rezerwacyjny (https://api.youraiconnector.com/v1/zenchef-widget/... i https://api.youraiconnector.com/v1/formitable-widget/...), który wyświetla się w czacie dla klienta — te ścieżki widżetów to zwykłe strony HTML przeznaczone do otwierania w przeglądarce, a nie punkty końcowe JSON API, dlatego nie zostały tutaj opisane. Poniżej znajdują się punkty końcowe zarządzania kontem: weryfikacja, czy identyfikator restauracji należy do właściciela konta, a następnie dodawanie, aktualizowanie lub usuwanie go.
Zenchef
Podłączenie restauracji Zenchef to dwuetapowa weryfikacja, dzięki której właściciel konta potwierdza, że faktycznie prowadzi restaurację, zanim zostanie ona połączona z botem: najpierw sprawdź, czy identyfikator istnieje (bez ujawniania nazwy), a następnie poproś o samodzielne wpisanie nazwy restauracji i sprawdź, czy jest ona zgodna.
Krok 1 — Sprawdź, czy identyfikator restauracji istnieje
POST /appointments/zenchef-restaurants/check
| Pole | Wymagane | Opis |
|---|---|---|
restaurant_id |
Tak | Identyfikator restauracji Zenchef do sprawdzenia. |
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" }'
Odpowiedź (200 OK):
{
"success": true,
"data": { "exists": true, "requiresNameVerification": true }
}
exists: false oznacza, że żadna restauracja Zenchef nie posiada tego identyfikatora — nie ma nic więcej do zrobienia. Limit wynosi 10 sprawdzeń na 5 minut na konto; przekroczenie tego limitu zwraca 429.
Krok 2 — Zweryfikuj nazwę restauracji
POST /appointments/zenchef-restaurants/verify-name
| Pole | Wymagane | Opis |
|---|---|---|
restaurant_id |
Tak | Identyfikator restauracji Zenchef z kroku 1. |
user_input_name |
Tak | Nazwa wpisana przez właściciela konta — porównywana z rzeczywistą nazwą restauracji w Zenchef (wielkość liter i białe znaki są ignorowane). |
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" }'
Odpowiedź (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 oznacza, że nazwa nie pasuje — restaurantDetails jest pomijane, poproś właściciela konta o ponowną próbę. Limit wynosi 3 próby na 5 minut (bardziej rygorystyczny niż sprawdzenie istnienia, ponieważ jest to właściwy krok weryfikacyjny). restaurant_id, który nie jest już rozpoznawany w Zenchef, zwraca 404.
Krok 3 — Zapisz restaurację
POST /appointments/zenchef-restaurants
| Pole | Wymagane | Opis |
|---|---|---|
restaurant_id |
Tak | 1–64 znaki, litery/cyfry/podkreślnik/myślnik. |
restaurant_name |
Tak | Zweryfikowana nazwa restauracji z kroku 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" }'
Odpowiedź (201 Created):
{ "success": true, "data": { "restaurantId": "12345" } }
Aktualizacja zapisanej restauracji Zenchef
PUT /appointments/zenchef-restaurants/{restaurantId}
| Pole | Wymagane | Opis |
|---|---|---|
restaurant_name |
Nie | Nowa nazwa wyświetlana. |
is_active |
Nie | Ustaw false, aby powstrzymać bota przed dokonywaniem rezerwacji w tej restauracji bez jej usuwania. |
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 }'
Odpowiedź (200 OK): ten sam format co odpowiedź zapisu powyżej.
Usuń restaurację 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"
Odpowiedź (200 OK): { "success": true, "data": { "restaurantId": "12345" } }
restaurantId, którego obecnie nie ma na koncie, zwraca 404 przy aktualizacji lub usunięciu.
Formitable
Formitable nie wymaga dwuetapowego potwierdzenia nazwy, jak Zenchef — jego identyfikatory restauracji są już przypisane do konkretnej firmy, więc wystarczy jedno wywołanie weryfikacyjne. Posiada również funkcję wyszukiwania szczegółów, używaną do buforowania adresu URL strony internetowej restauracji podczas konfiguracji.
Zweryfikuj identyfikator restauracji
POST /appointments/formitable-restaurants/verify
| Pole | Wymagane | Opis |
|---|---|---|
restaurant_id |
Tak | Identyfikator restauracji Formitable. |
language |
Nie | Znacznik języka dla żądania sondowania. Domyślnie "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" }'
Odpowiedź (200 OK):
{
"success": true,
"data": {
"verified": true,
"restaurantDetails": {
"restaurantId": "the-blue-door",
"productCount": 4,
"sampleProductTitle": "Dinner for two",
"language": "en"
}
}
}
restaurant_id, którego Formitable nie rozpoznaje, zwraca 404. Limit prędkości wynosi 10 prób na 5 minut na konto.
Pobierz szczegóły restauracji
GET /appointments/formitable-restaurants/{restaurantId}/details?language=en
Pobiera publiczny profil restauracji z Formitable, w tym jej stronę internetową — używane do buforowania adresu URL strony podczas konfigurowania restauracji. language jest opcjonalnym parametrem zapytania, domyślnie ustawionym na "en".
curl "https://api.youraiconnector.com/v1/appointments/formitable-restaurants/the-blue-door/details?language=en" \
-H "X-API-Key: YOUR_API_KEY"
Odpowiedź (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"
}
}
Zapisz restaurację
POST /appointments/formitable-restaurants
| Pole | Wymagane | Opis |
|---|---|---|
restaurant_id |
Tak | 1–64 znaki, litery/cyfry/podkreślnik/myślnik. |
restaurant_name |
Tak | Nazwa wyświetlana. |
language |
Tak | Znacznik języka ISO, np. "en" lub "en-GB". |
website_url |
Nie | Strona internetowa restauracji, z powyższego wyszukiwania szczegółów. Musi być 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"
}'
Odpowiedź (201 Created): { "success": true, "data": { "restaurantId": "the-blue-door" } }
Zaktualizuj zapisaną restaurację Formitable
PUT /appointments/formitable-restaurants/{restaurantId}
| Pole | Wymagane | Opis |
|---|---|---|
restaurant_name |
Nie | Nowa nazwa wyświetlana. |
language |
Nie | Nowy znacznik języka ISO. |
is_active |
Nie | Ustaw false, aby powstrzymać bota przed dokonywaniem rezerwacji w tej restauracji bez jej usuwania. |
website_url |
Nie | Nowy adres URL strony internetowej. |
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 }'
Odpowiedź (200 OK): ten sam format co odpowiedź zapisu powyżej.
Usuń restaurację 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"
Odpowiedź (200 OK): { "success": true, "data": { "restaurantId": "the-blue-door" } }
restaurantId, którego obecnie nie ma na koncie, zwraca 404 przy aktualizacji lub usunięciu.
OpenTable
Restauracje OpenTable są dostępne za pośrednictwem danych uwierzytelniających partnera OpenTable platformy, a OpenTable pozwala tym danym widzieć tylko te restauracje, które połączyły ofertę platformy wewnątrz Marketplace Integracji OpenTable. Podobnie jak w przypadku Formitable, wystarczy jedno wywołanie weryfikacyjne: osiągalny identyfikator restauracji (numeryczny “RID”) potwierdza zarówno istnienie restauracji, jak i fakt, że połączyła ona integrację. Dopóki oferta partnera OpenTable nie zostanie włączona na platformie, wywołanie weryfikacyjne zwróci 503.
Weryfikacja restauracji OpenTable
POST /appointments/opentable-restaurants/verify
| Pole | Wymagane | Opis |
|---|---|---|
restaurant_id |
Tak | Identyfikator restauracji OpenTable (RID), liczba taka jak 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" }'
Odpowiedź (200 OK):
{
"success": true,
"data": {
"verified": true,
"restaurantDetails": {
"restaurantId": "1038007",
"diningAreaCount": 2,
"diningAreaNames": ["Main Room", "Garden"],
"tableTypes": ["default", "outdoor", "bar"]
}
}
}
verified: false oznacza, że żadna restauracja OpenTable nie posiada tego identyfikatora. 403 oznacza, że restauracja istnieje, ale nie połączyła jeszcze integracji platformy wewnątrz OpenTable. Limit wynosi 10 prób na 5 minut na konto.
Dodawanie restauracji OpenTable
POST /appointments/opentable-restaurants
| Pole | Wymagane | Opis |
|---|---|---|
restaurant_id |
Tak | Zweryfikowany identyfikator restauracji. |
restaurant_name |
Tak | Nazwa wyświetlana (etykieta; używana również przez AI do nazywania restauracji). |
website_url |
Nie | Adres URL http(s) pokazywany gościom, gdy AI przekierowuje ich do restauracji. |
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" }'
Odpowiedź (201 Created): { "success": true, "data": { "restaurantId": "1038007" } }
Aktualizacja zapisanej restauracji OpenTable
PUT /appointments/opentable-restaurants/{restaurantId}
Wyślij dowolne z restaurant_name, is_active (wstrzymaj za pomocą false) lub website_url (pusty ciąg znaków czyści pole); pominięte pola pozostają bez zmian.
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 }'
Odpowiedź (200 OK): { "success": true, "data": { "restaurantId": "1038007" } }
Usuwanie restauracji z 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"
Odpowiedź (200 OK): { "success": true, "data": { "restaurantId": "1038007" } }
Aktualizacja restaurantId, którego nie ma obecnie na koncie, zwraca 404.
TheFork
Restauracje TheFork są obsługiwane za pośrednictwem danych uwierzytelniających partnera TheFork, a platforma TheFork pozwala tym danym widzieć tylko te restauracje, które mają włączonego partnera platformy na swoim koncie TheFork. Podobnie jak w przypadku Formitable i OpenTable, wystarczy jedno wywołanie weryfikacyjne: osiągalny identyfikator restauracji (Restaurant ID) potwierdza zarówno istnienie restauracji, jak i to, że partner jest na niej włączony. Identyfikator to UUID nadawany restauracji przez TheFork w menedżerze TheFork Manager, przesyłany jako ciąg znaków. Dopóki TheFork nie zatwierdzi platformy jako partnera i nie wyda danych uwierzytelniających, wywołanie weryfikacyjne zwróci 503 — zobacz TheFork, aby dowiedzieć się, co to oznacza obecnie.
Weryfikacja restauracji TheFork
POST /appointments/thefork-restaurants/verify
| Pole | Wymagane | Opis |
|---|---|---|
restaurant_id |
Tak | Identyfikator restauracji TheFork, UUID, np. 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" }'
Odpowiedź (200 OK):
{
"success": true,
"data": {
"verified": true,
"restaurantDetails": {
"restaurantId": "9f2a1c34-5b6d-4e7f-8a90-1b2c3d4e5f60",
"partySizes": [1, 2, 3, 4, 5, 6, 7, 8]
}
}
}
partySizes to wielkości grup, które restauracja przyjmuje online w ciągu najbliższych 30 dni. 404 lub 403 oznacza, że TheFork nie udostępnił nam restauracji o tym identyfikatorze — albo identyfikator jest błędny, albo partner platformy nie jest jeszcze włączony dla tej restauracji; 400 oznacza, że identyfikator nie jest w formacie UUID. Limit wynosi 10 prób na 5 minut na konto.
Dodawanie restauracji TheFork
POST /appointments/thefork-restaurants
| Pole | Wymagane | Opis |
|---|---|---|
restaurant_id |
Tak | Zweryfikowany identyfikator restauracji (UUID). |
restaurant_name |
Tak | Nazwa wyświetlana (etykieta; używana również przez AI do nazywania restauracji). |
website_url |
Nie | Adres URL http(s) pokazywany gościom, gdy AI przekierowuje ich do restauracji. |
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" }'
Odpowiedź (201 Created): { "success": true, "data": { "restaurantId": "9f2a1c34-5b6d-4e7f-8a90-1b2c3d4e5f60" } }
Aktualizacja zapisanej restauracji TheFork
PUT /appointments/thefork-restaurants/{restaurantId}
Wyślij dowolne z restaurant_name, is_active (wstrzymaj za pomocą false) lub website_url (pusty ciąg znaków czyści pole); pominięte pola pozostają bez zmian.
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 }'
Odpowiedź (200 OK): { "success": true, "data": { "restaurantId": "9f2a1c34-5b6d-4e7f-8a90-1b2c3d4e5f60" } }
Usuwanie restauracji 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"
Odpowiedź (200 OK): { "success": true, "data": { "restaurantId": "9f2a1c34-5b6d-4e7f-8a90-1b2c3d4e5f60" } }
restaurantId, którego obecnie nie ma na koncie, zwraca 404 przy aktualizacji lub usunięciu.
Trafft
System Trafft łączy się raz dla całego konta, a nie dla każdej lokalizacji: jeden adres firmy oraz dane uwierzytelniające API z panelu administratora Trafft (Features & Integrations → API & Connectors, część planu Business w Trafft). Wywołanie połączenia sprawdza te dane uwierzytelniające w systemie Trafft przed zapisaniem czegokolwiek, więc błędny adres, błędne dane lub plan bez dostępu do API spowodują błąd na tym etapie, a nie podczas rozmowy z klientem. Klient secret jest przechowywany w formie zaszyfrowanej i nigdy nie jest zwracany przez żaden punkt końcowy.
Wszystkie trzy wywołania zapisu (POST, PUT, DELETE) wymagają uprawnienia edit dla integracji; status GET wymaga uprawnienia view dla integracji.
Połącz Trafft
POST /appointments/trafft/connect
| Pole | Wymagane | Opis |
|---|---|---|
subdomain |
Tak | Adres firmy — część przed .admin.trafft.com w adresie URL, pod którym się logujesz, np. acme. Pełny adres jest akceptowany i skracany do tej samej wartości. |
client_id |
Tak | Client ID ze strony API & Connectors w Trafft. |
client_secret |
Tak | Client Secret z tej samej strony. Przechowywany w formie zaszyfrowanej, nigdy nie jest zwracany. |
company_name |
Nie | Etykieta dla Twojej własnej listy. |
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"
}'
Odpowiedź (200 OK):
{
"success": true,
"data": {
"subdomain": "acme",
"service_count": 12,
"employee_count": 4,
"location_count": 2
}
}
Liczby są zwracane z systemu Trafft podczas sprawdzania — to najszybszy sposób, aby potwierdzić, że dane uwierzytelniające wskazują na konto, o które Ci chodziło.
Pobierz status połączenia
GET /appointments/trafft
curl "https://api.youraiconnector.com/v1/appointments/trafft" \
-H "X-API-Key: YOUR_API_KEY"
Odpowiedź (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 oznacza, że nic nie zostało jeszcze skonfigurowane. Klient secret nigdy nie jest uwzględniany w tej odpowiedzi.
Aktualizuj połączenie
PUT /appointments/trafft
| Pole | Wymagane | Opis |
|---|---|---|
is_active |
Nie | Ustaw false, aby wstrzymać — AI przestaje dodawać rezerwacje do Trafft, połączenie pozostaje aktywne. true wznawia działanie. |
company_name |
Nie | Nowa etykieta. |
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 }'
Odpowiedź (200 OK): ten sam obiekt połączenia co GET powyżej.
Rozłącz Trafft
DELETE /appointments/trafft
curl -X DELETE "https://api.youraiconnector.com/v1/appointments/trafft" \
-H "X-API-Key: YOUR_API_KEY"
Odpowiedź (200 OK): { "success": true }
Rozłączenie usuwa tylko zapisane dane uwierzytelniające. Rezerwacje znajdujące się już w Trafft pozostają nienaruszone.
Format błędu we wszystkich punktach końcowych Zenchef/Formitable/OpenTable/TheFork: w przeciwieństwie do reszty tej strony, błędy w tym miejscu zawierają status dwukrotnie — raz jako status HTTP, a raz jako
error_codew treści — na przykład{ "success": false, "error": "Restaurant not found", "error_code": 404 }. Obsługuj je w taki sam sposób jak każdy inny błąd: sprawdźsuccess, przeczytajerror, aby uzyskać komunikat.
Błędy API wizyt
Punkty końcowe wizyt zwracają standardową kopertę błędu:
{
"success": false,
"error": "Appointment not found"
}
| Status | Kiedy występuje w punkcie końcowym spotkań |
|---|---|
400 |
Brakuje wymaganego pola lub jest ono nieprawidłowe — na przykład błędny start_time, end_time niebędący po start_time, nieprawidłowa kombinacja filtrów, brak pól do aktualizacji lub już anulowane spotkanie. Podczas rezerwacji: nie przesłano ani event_id, ani title, przesłano oba jednocześnie, przesłano zarówno end_time, jak i duration_minutes, title powyżej 200 znaków lub duration_minutes poza zakresem 1–1440. |
404 |
Nie znaleziono spotkania, kontaktu lub typu wydarzenia. |
409 |
Żądany slot czasowy jest już zajęty (konflikt rezerwacji) lub przy aktualizacji external_reference jest już używany przez inne spotkanie. |
Wspólne kody, które może zwrócić każdy punkt końcowy — 401, 403 (Twój plan nie obejmuje dostępu do API), 429 (limit szybkości) oraz 500 — zostały wymienione wraz ze wskazówkami dotyczącymi ponawiania prób w sekcji Błędy i stronicowanie.
Następne kroki
- Kontakty — twórz i wyszukuj kontakty, dla których dokonujesz rezerwacji.
- Wiadomości i konwersacje — wysyłaj do kontaktu potwierdzenia lub przypomnienia.
- Webhooki — otrzymuj powiadomienia o zmianach w spotkaniach.