Your AI Connector Docs

Appuntamenti

L’API Appointments ti consente di prenotare appuntamenti per i tuoi contatti sui tuoi tipi di evento, quindi di recuperarli, elencarli, aggiornarli, annullarli o eliminarli. Risponde anche alla domanda che sorge per prima nella maggior parte dei flussi di prenotazione — quali orari sono effettivamente liberi — e copre il lato calendario: elencando i Google Calendar che hai collegato e importando gli eventi che vi sono già presenti. Quando una connessione a Google Calendar è attiva, l’evento del calendario corrispondente viene creato e mantenuto sincronizzato automaticamente in background. I ristoranti che utilizzano Zenchef, Formitable, OpenTable o TheFork per il proprio sistema di prenotazione possono anche essere verificati e collegati qui, in modo che l’Agente AI prenoti tavoli reali invece di appuntamenti interni — e le attività basate su appuntamenti che gestiscono la propria programmazione in Trafft possono connettersi allo stesso modo.

Tutti i percorsi in questa pagina sono relativi all’URL di base https://api.youraiconnector.com/v1. Ogni richiesta richiede la tua chiave API: consulta Autenticazione per l’elenco completo delle modalità di invio. Gli esempi seguenti utilizzano l’intestazione X-API-Key, con un esempio cURL che mostra anche il formato di query ?apiKey=.

Eventi vs. appuntamenti: Una tipologia di evento è la definizione di uno slot prenotabile (il tipo di riunione, la sua durata, le sue sale). Un appuntamento è una singola istanza prenotata di una tipologia di evento per uno specifico contatto. Prenoti un appuntamento facendo riferimento al contatto e alla tipologia di evento.


L’oggetto appuntamento

Ogni endpoint che restituisce un appuntamento utilizza la stessa struttura:

Campo Descrizione
id ID univoco dell’appuntamento.
contact_id ID del contatto con cui è stato prenotato l’appuntamento.
event_id ID del tipo di evento per cui è stato prenotato l’appuntamento. null per prenotazioni esterne — appuntamenti registrati senza un tipo di evento.
status Confirmed o Canceled.
start_time Inizio dell’appuntamento, ISO 8601 in UTC.
end_time Fine dell’appuntamento, ISO 8601 in UTC.
created_at Quando è stato creato l’appuntamento.
last_modified_at Quando l’appuntamento è stato modificato l’ultima volta.
room_name Stanza o risorsa in cui è prenotato l’appuntamento, quando il tipo di evento utilizza le stanze.
description Descrizione a formato libero dell’appuntamento.
summary Breve riepilogo o titolo. Per una prenotazione esterna, questo è il title con cui è stata registrata.
external_reference Il tuo ID personale per questa prenotazione (dal tuo CRM o sistema di prenotazione), così come l’hai inviato, o null.
cancelation_reason Motivo fornito per la cancellazione dell’appuntamento, se presente.
google_calendar_event_id ID dell’evento di Google Calendar collegato. Impostato una volta completata la sincronizzazione del calendario; null quando nessun calendario è collegato o mentre la sincronizzazione è ancora in corso.
calendar_synced true una volta che l’appuntamento è collegato a un evento del calendario.
imported true quando l’appuntamento è stato importato da un calendario esterno anziché prenotato direttamente.
is_recurring true quando l’appuntamento fa parte di una serie ricorrente.
recurrence_frequency Frequenza di ripetizione dell’appuntamento, quando ricorrente.
recurring_event_id ID della serie ricorrente a cui appartiene questo appuntamento.
recurring_interval Intervallo tra le ripetizioni, quando ricorrente.
recurring_sequence Posizione di questo appuntamento all’interno della sua serie ricorrente.
end_after_x_occurrences Numero di occorrenze dopo le quali termina la serie ricorrente.
booking_provider Sistema di origine da cui proviene la prenotazione, quando effettuata tramite un fornitore di prenotazioni collegato.

Informazioni sulla sincronizzazione del calendario: Subito dopo aver prenotato o modificato un appuntamento, google_calendar_event_id potrebbe essere ancora null e calendar_synced potrebbe essere false perché la sincronizzazione viene eseguita in background poco dopo. Recupera nuovamente l’appuntamento poco dopo per visualizzare i campi del calendario popolati.


Trova gli slot disponibili

GET /appointments/available-slots

Restituisce gli orari che sono effettivamente liberi per un tipo di evento tra due momenti. Questa è solitamente la prima chiamata in un flusso di prenotazione: mostra questi slot, lascia che la persona ne scelga uno, quindi invia l’orario scelto a Prenota un appuntamento.

La risposta tiene già conto degli orari di apertura e della durata dello slot del tipo di evento, delle sue sale, degli appuntamenti che hai già prenotato su di esso e di tutto ciò che è bloccato sui Google Calendar collegati — quindi uno slot restituito qui è uno slot che puoi prenotare.

Parametro di query Obbligatorio Descrizione
event_id Sì Il tipo di evento da controllare. Deve appartenere al tuo account. Trovalo nell’app aprendo il tipo di evento nella pagina Appuntamenti (scheda Tipi di evento): la finestra di modifica mostra il suo ID tipo di evento con un pulsante di copia.
start_time Sì Inizio della finestra per cui desideri gli slot, data-ora ISO 8601.
end_time Sì Fine della finestra, data-ora ISO 8601. L’intero giorno finale è incluso.

I risultati vengono restituiti raggruppati per giorno — e, quando il tipo di evento utilizza le sale, un gruppo per sala per giorno:

Campo Descrizione
date Il giorno coperto dal gruppo, scritto DD/MM/YYYY.
day Nome del giorno della settimana in minuscolo, ad esempio monday.
room_name La sala o la risorsa a cui appartiene questo gruppo, quando il tipo di evento utilizza le sale.
available_slots I blocchi prenotabili in quel giorno, dal più presto al più tardi.

Ogni voce in available_slots ha:

Campo Descrizione
start_time Inizio del blocco come HH:mm.
end_time Fine del blocco come HH:mm.
available true — viene restituito solo il tempo libero.
spots_left Quante prenotazioni rientrano ancora in questo blocco. Presente solo sui tipi di evento che accettano più di una prenotazione per slot.

Gli orari sono locali rispetto al tipo di evento, non UTC. date, start_time e end_time sono valori di orologio locale nel fuso orario del tipo di evento (il suo override, o il fuso orario del tuo account quando non ne ha uno). Prenota un appuntamento si aspetta un istante UTC ISO 8601, quindi converti lo slot che hai scelto prima di inviarlo.

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"])

Risposta (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 }
      ]
    }
  ]
}

Un giorno senza disponibilità semplicemente non appare. event_id, start_time o end_time mancanti restituiscono 400; un tipo di evento che non è sul tuo account restituisce 404.


Prenota un appuntamento

POST /appointments

Crea un appuntamento per uno dei tuoi contatti. Ci sono due modi per utilizzarlo:

  • Su uno dei tuoi tipi di evento — invia event_id e la prenotazione funzionerà esattamente come ha sempre fatto: la disponibilità e la capacità vengono rispettate, l’ora di fine viene calcolata in base alla durata dello slot del tipo di evento e l’appuntamento si sincronizza con il tuo Google Calendar quando ne è collegato uno.
  • Come prenotazione esterna — ometti event_id e invia invece un title. Questo registra una prenotazione effettuata altrove (il tuo CRM, un programma di lezioni, un altro strumento di prenotazione) in modo che appaia nella pagina Appuntamenti insieme al resto.

Una prenotazione per una tipologia di evento con stanze deve avvenire in un orario proposto da Trova slot disponibili: all’interno degli orari della stanza, al di fuori del periodo di preavviso, entro il limite temporale di prenotazione della tipologia di evento, sulla griglia degli slot, non nel passato e non bloccato su un calendario collegato. Qualsiasi altro orario viene rifiutato con un 400 e non viene creato nulla. Lo stesso vale per un room_name che non corrisponde a nessuna delle stanze della tipologia di evento (il messaggio elenca i nomi validi). I tempi di buffer impostati sulla tipologia di evento (Buffer prima e Buffer dopo nell’editor della tipologia di evento, buffer_before e buffer_after in minuti) vengono mantenuti liberi attorno a ogni prenotazione.

Una prenotazione su un tipo di evento è anche soggetta a controllo dei conflitti: se lo slot è già pieno, la richiesta fallisce con un 409 e non viene creato nulla. Una prenotazione esterna non ha un tipo di evento associato, quindi non viene effettuato alcun controllo rispetto alla tua disponibilità o capacità e nulla viene sincronizzato con un calendario.

Riprovare è sicuro. Se lo stesso contatto ha già una prenotazione confermata sullo stesso tipo di evento allo stesso orario di inizio (nella stessa stanza, quando ne specifichi una), ad esempio perché la tua prima richiesta è andata in timeout dopo essere stata elaborata, riceverai quella prenotazione con un 200 e "replayed": true invece di una seconda prenotazione o un 409.

Un external_reference funziona come chiave di idempotenza. È univoco nel tuo account: se un appuntamento contiene già il riferimento che invii, tale appuntamento viene restituito con un 200 e "replayed": true e non viene creato nulla di nuovo, anche se il tentativo di riprova indica un orario o un contatto diverso e indipendentemente dallo stato dell’appuntamento. Usalo per le prenotazioni a pagamento (invia il tuo ID pagamento o ordine) e invia un nuovo riferimento per una prenotazione effettivamente nuova.

Campo Obbligatorio Descrizione
contact_id Sì ID del contatto per cui effettuare la prenotazione. Deve appartenere al tuo account.
start_time Sì Inizio desiderato come data-ora ISO 8601. Un orario inviato senza offset del fuso orario viene letto nel fuso orario del tuo account.
event_id No ID del tipo di evento su cui prenotare. Deve appartenere al tuo account. Lascialo vuoto per registrare una prenotazione esterna.
title Solo senza event_id Il nome con cui l’appuntamento viene mostrato nella pagina Appuntamenti — ad esempio, il nome del corso. Fino a 200 caratteri. Viene restituito come summary.
end_time No Fine di una prenotazione esterna come data-ora ISO 8601, successiva a start_time. Non necessaria con un event_id: l’orario di fine viene quindi ricavato dalla durata dello slot del tipo di evento.
duration_minutes No Quanto dura una prenotazione esterna, un numero intero di minuti da 1 a 1440. Usa questo o end_time, non entrambi. Senza nessuno dei due, una prenotazione esterna dura 60 minuti.
description No Note a forma libera da conservare con l’appuntamento.
room_name No Nome della stanza o della risorsa, quando il tipo di evento utilizza le stanze. Deve corrispondere a una delle sue stanze. Lascialo vuoto per prenotare la prima stanza libera.
external_reference No Il tuo ID per questa prenotazione, in modo da poterlo abbinare al record nel tuo CRM o sistema di prenotazione. Fino a 255 caratteri. Viene restituito a ogni lettura e nei webhook di Appuntamento Prenotato, Cancellato e Ripianificato. Univoco nel tuo account: un riferimento già in uso restituisce quell’appuntamento invece di prenotarne uno nuovo (vedi sopra).

Invia event_id e title insieme, o nessuno dei due, e la richiesta restituirà un 400 — così come l’invio di entrambi end_time e duration_minutes.

cURL (utilizzando il formato di query ?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"])

Risposta (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
  }
}

Registrazione di una prenotazione effettuata altrove

Stesso endpoint, senza un tipo di evento: un title e un start_time sono sufficienti, e duration_minutes imposta la durata.

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"])

Risposta (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
  }
}

Le prenotazioni esterne sono appuntamenti ordinari a tutti gli effetti: appaiono nella pagina Appuntamenti e in Elenca appuntamenti, possono essere riprogrammate, annullate o eliminate nell’app o tramite questa API, l’email di notifica della prenotazione viene inviata come al solito e il trigger di automazione Appuntamento prenotato e il webhook si attivano per loro come per qualsiasi altra prenotazione effettuata tramite l’API. Le uniche differenze sono quelle sopra indicate: nessun controllo di disponibilità o capacità, nessuna sincronizzazione del calendario e event_id rimane null.


Ottieni un appuntamento

GET /appointments/{appointmentId}

Restituisce un singolo appuntamento tramite il suo ID, incluso il suo stato di sincronizzazione del calendario.

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"])

Risposta (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
  }
}

Elenca appuntamenti

GET /appointments

Elenca gli appuntamenti per il tuo account, dal più recente, con paginazione basata su cursore.

Parametro di query Obbligatorio Descrizione
contact_id No Restituisce solo gli appuntamenti per questo contatto. Gli elenchi filtrati per contatto includono solo gli appuntamenti confermati.
date No Restituisce solo gli appuntamenti in questo giorno del calendario (YYYY-MM-DD). Richiede contact_id.
status No Filtra per Confirmed o Canceled. Disponibile solo senza contact_id.
limit No Dimensione della pagina, un numero intero tra 1 e 100. Predefinito 50.
cursor No Il valore next_cursor da una risposta precedente.

Alcune regole da tenere a mente:

  • Senza filtri, ottieni ogni appuntamento sull’account, pagina per pagina.
  • Per contatto — imposta contact_id per vedere gli appuntamenti confermati di un contatto. Puoi restringere il campo a un singolo giorno passando anche date.
  • Per stato — imposta status (senza contact_id) per elencare solo gli appuntamenti Confirmed o solo Canceled nell’account.
  • Il filtro date senza contact_id, o status=Canceled insieme a contact_id, restituisce un 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"])

Risposta (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
}

Per scorrere i risultati, passa il next_cursor da una risposta come cursor della richiesta successiva. Continua finché next_cursor non è null. Vedi Errori e Paginazione per il pattern di paginazione condiviso.


Aggiorna un appuntamento

PUT /appointments/{appointmentId}

Ripianifica un appuntamento o modifica i suoi dettagli. Invia solo i campi che desideri modificare: almeno uno è obbligatorio. L’inizio e la fine combinati devono rimanere in ordine cronologico (end_time deve essere successivo a start_time). Le modifiche vengono sincronizzate automaticamente con l’evento del calendario collegato.

Lo spostamento di una prenotazione confermata su un tipo di evento (un nuovo start_time o room_name) è soggetto a controllo dei conflitti come una nuova prenotazione: uno slot già pieno risponde 409 e nulla cambia, e una room_name che non corrisponde a nessuna delle stanze del tipo di evento risponde 400. Invia solo start_time e la prenotazione manterrà la sua durata. I tuoi orari di apertura e il periodo di preavviso non vengono applicati qui, quindi puoi comunque spostare una prenotazione in qualsiasi orario libero.

Campo Descrizione
start_time Nuovo inizio, data-ora ISO 8601. Un orario inviato senza offset del fuso orario viene letto nel fuso orario del tipo di evento (o del tuo account), come durante la prenotazione.
end_time Nuova fine, data-ora ISO 8601, letta allo stesso modo. Deve essere successiva all’orario di inizio.
room_name Nuovo nome della stanza o della risorsa.
description Nuova descrizione, o null per cancellarla.
summary Nuovo riepilogo, o null per cancellarlo.
external_reference Nuovo riferimento (fino a 255 caratteri), o null per cancellarlo. Un riferimento già posseduto da un altro appuntamento viene rifiutato con un 409 e "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"])

Risposta (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
  }
}

Annulla un appuntamento

POST /appointments/{appointmentId}/cancel

Annulla un appuntamento confermato, registrando facoltativamente un motivo. L’appuntamento rimane nel tuo account con lo stato Canceled e l’evento del calendario collegato viene rimosso automaticamente in background. L’annullamento di un appuntamento già annullato restituisce un 400.

Campo Obbligatorio Descrizione
cancellation_reason No Motivo dell’annullamento, memorizzato nell’appuntamento.

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"])

Risposta (200 OK):

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

Invia nuovamente la conferma della prenotazione

POST /appointments/{appointmentId}/resend-confirmation

Invia nuovamente al contatto la conferma della prenotazione, ad esempio quando afferma di non averla mai ricevuta o che è finita nello spam. Si compone di due parti, entrambe inviate a meno che non ne venga disattivata una: l’email di conferma (la stessa ricevuta dal contatto al momento della prenotazione) e, quando l’appuntamento è presente sul tuo Google Calendar, l’invito di Google Calendar. Entrambi vengono inviati all’indirizzo email del contatto.

Campo Obbligatorio Descrizione
email No false salta l’email di conferma. Il valore predefinito è true.
calendar_invite No false salta l’invito di Google Calendar. Il valore predefinito è true.

Ogni parte restituisce il proprio esito: sent, not_requested, no_contact_email, turned_off_for_event_type (l’interruttore Invia email di appuntamento al contatto del tipo di evento è disattivato), not_on_google_calendar, imported (gli appuntamenti importati dal tuo calendario non ricevono alcuna email di conferma) o failed.

  • 200 quando almeno una parte è stata inviata. recipient è l’indirizzo a cui è stata inviata.
  • 409 per un appuntamento annullato, già concluso o una prenotazione effettuata tramite Zenchef, Formitable, OpenTable, TheFork o Trafft (quel sistema invia la propria conferma). code è appointment_canceled, appointment_in_past o managed_by_provider.
  • 422 quando non è stato possibile inviare nulla, con il motivo in 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())

Risposta (200 OK):

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

Elimina un appuntamento

DELETE /appointments/{appointmentId}

Elimina definitivamente un appuntamento e i suoi riferimenti. Se desideri solo annullare la prenotazione mantenendo il record, utilizza invece annulla.

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"])

Risposta (200 OK):

{
  "success": true
}

Elenca i tuoi Google Calendar collegati

GET /appointments/google-calendars

Restituisce i Google Calendar disponibili su questo account, direttamente da Google — utile per mostrare al titolare dell’account un selettore da cui importare il calendario qui sotto, o semplicemente per confermare che la connessione è attiva.

Questo funziona solo una volta che l’account ha collegato Google Calendar (Impostazioni → Integrazioni) con almeno l’accesso in lettura. Se non lo ha fatto, o se l’accesso concesso non include più l’ambito di lettura del calendario, riceverai un 400 che ti invita a (ri)collegarlo.

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"])

Risposta (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"
    }
  ]
}

Ogni voce ha la forma CalendarListEntry di Google, quindi i nomi dei campi seguono lo camelCase di Google, non il solito snake_case di questa API: si tratta dei dati di Google trasmessi così come sono, non dei nostri. Una connessione mancante o revocata restituisce 400 con un errore che spiega che Google Calendar deve essere (ri)collegato.


Importa eventi da un Google Calendar

POST /appointments/import-calendar-events

Estrae gli eventi già presenti nel/i Google Calendar collegato/i di una campagna o di un Agente AI e li trasforma in appuntamenti; è utile la prima volta che si collega un calendario che ha già delle prenotazioni. Questa operazione può richiedere del tempo (ogni evento viene analizzato per capire a chi è destinato), quindi non viene mai eseguita in linea: la richiesta accoda un processo in background e ti restituisce un job_id da interrogare.

Campo Obbligatorio Descrizione
campaign_id Uno di questi due La campagna da cui importare i calendari collegati.
agent_id Uno di questi due L’Agente AI da cui importare i calendari collegati.
identifier Sì "EMAIL" o "PHONE_NUMBER": quale informazione di contatto estrarre da ogni evento del calendario per trovare o creare il contatto a cui appartiene.

Invia esattamente uno tra campaign_id / agent_id, mai entrambi e mai nessuno dei due: qualsiasi altra combinazione restituisce un 400. Qualunque tu scelga di inviare deve appartenere al tuo account, altrimenti riceverai un 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"])

Risposta (202 Accepted):

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

campaign_id e agent_id rimandano quello che hai inviato; l’altro è sempre null.

Interroga il processo di importazione

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

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

Risposta (200 OK):

{
  "success": true,
  "job_id": "jK9mQ2xR7pL4wN1t",
  "status": "completed",
  "message": "Imported 12 events as appointments.",
  "error": null
}
status Significato
queued Non ancora preso in carico. Continua a interrogare.
processing L’importazione è in corso. Continua a interrogare.
completed Completato: message contiene un breve riepilogo leggibile.
failed Qualcosa è andato storto: error contiene il motivo.

GET su un jobId che non esiste (o appartiene a un account diverso) restituisce 404.


Integrazioni di prenotazione esterne (Zenchef / Formitable / OpenTable / TheFork / Trafft)

Zenchef e Formitable sono sistemi di prenotazione per ristoranti tramite i quali il tuo Agente IA può prenotare tavoli reali; Trafft è una piattaforma di pianificazione per attività basate su appuntamenti, collegata una volta per account anziché per ristorante. Le due piattaforme per ristoranti dispongono ciascuna di un widget di prenotazione pubblico e non autenticato (https://api.youraiconnector.com/v1/zenchef-widget/... e https://api.youraiconnector.com/v1/formitable-widget/...) che viene visualizzato all’interno della chat per il cliente — tali percorsi del widget sono semplici pagine HTML destinate ad essere aperte in un browser, non endpoint API JSON, quindi non sono documentati qui. Di seguito sono riportati gli endpoint di gestione dell’account: verifica che un ID ristorante appartenga al titolare dell’account, quindi aggiunta, aggiornamento o rimozione dello stesso.

Zenchef

La connessione di un ristorante Zenchef è una verifica in due passaggi, in modo che il titolare dell’account dimostri di gestire effettivamente il ristorante prima che venga collegato al bot: prima si verifica che l’ID esista (senza rivelare il nome), poi si chiede di digitare il nome del ristorante e si verifica che corrisponda.

Passaggio 1 — Verificare che un ID ristorante esista

POST /appointments/zenchef-restaurants/check

Campo Obbligatorio Descrizione
restaurant_id Sì L’ID del ristorante Zenchef da verificare.
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" }'

Risposta (200 OK):

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

exists: false significa che nessun ristorante Zenchef possiede quell’ID: non c’è altro da fare. Limitato a 10 controlli ogni 5 minuti per account; il superamento di questo limite restituisce 429.

Passaggio 2 — Verificare il nome del ristorante

POST /appointments/zenchef-restaurants/verify-name

Campo Obbligatorio Descrizione
restaurant_id Sì L’ID del ristorante Zenchef dal passaggio 1.
user_input_name Sì Il nome digitato dal titolare dell’account: confrontato con il nome reale del ristorante su Zenchef (non sensibile a maiuscole/minuscole o spazi).
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" }'

Risposta (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 significa che il nome non corrisponde: restaurantDetails viene omesso, chiedi al titolare dell’account di riprovare. Limitato a 3 tentativi ogni 5 minuti (più restrittivo del controllo di esistenza, poiché questo è il passaggio di prova effettivo). Un restaurant_id che non è più risolvibile su Zenchef restituisce 404.

Passaggio 3 — Salvare il ristorante

POST /appointments/zenchef-restaurants

Campo Obbligatorio Descrizione
restaurant_id Sì 1–64 caratteri, lettere/numeri/underscore/trattino.
restaurant_name Sì Il nome del ristorante verificato dal passaggio 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" }'

Risposta (201 Created):

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

Aggiornare un ristorante Zenchef salvato

PUT /appointments/zenchef-restaurants/{restaurantId}

Campo Obbligatorio Descrizione
restaurant_name No Nuovo nome visualizzato.
is_active No Imposta false per impedire al bot di effettuare prenotazioni presso questo ristorante senza rimuoverlo.
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 }'

Risposta (200 OK): stessa struttura della risposta di salvataggio sopra.

Rimuovere un ristorante 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"

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

Un restaurantId non attualmente presente nell’account restituisce 404 in caso di aggiornamento o eliminazione.

Formitable

Formitable non richiede la verifica del nome in due passaggi necessaria per Zenchef: i suoi ID ristorante sono già limitati per attività, quindi una sola chiamata di verifica è sufficiente. Dispone inoltre di una ricerca dei dettagli utilizzata per memorizzare nella cache l’URL del sito web del ristorante durante la configurazione.

Verificare un ID ristorante

POST /appointments/formitable-restaurants/verify

Campo Obbligatorio Descrizione
restaurant_id Sì L’ID ristorante Formitable.
language No Tag della lingua per la richiesta di sondaggio. L’impostazione predefinita è "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" }'

Risposta (200 OK):

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

Un restaurant_id non riconosciuto da Formitable restituisce 404. Limitato a 10 tentativi ogni 5 minuti per account.

Ottenere i dettagli del ristorante

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

Recupera il profilo pubblico del ristorante da Formitable, incluso il suo sito web: utilizzato per memorizzare nella cache l’URL del sito web durante la configurazione del ristorante. language è un parametro di query opzionale, con valore predefinito "en".

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

Risposta (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"
  }
}

Salva il ristorante

POST /appointments/formitable-restaurants

Campo Obbligatorio Descrizione
restaurant_id Sì 1–64 caratteri, lettere/numeri/underscore/trattino.
restaurant_name Sì Nome visualizzato.
language Sì Tag lingua ISO, ad es. "en" o "en-GB".
website_url No Il sito web del ristorante, dalla ricerca dei dettagli sopra. Deve essere 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"
  }'

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

Aggiorna un ristorante Formitable salvato

PUT /appointments/formitable-restaurants/{restaurantId}

Campo Obbligatorio Descrizione
restaurant_name No Nuovo nome visualizzato.
language No Nuovo tag lingua ISO.
is_active No Imposta false per impedire al bot di effettuare prenotazioni presso questo ristorante senza rimuoverlo.
website_url No Nuovo URL del sito web.
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 }'

Risposta (200 OK): stessa struttura della risposta di salvataggio sopra.

Rimuovi un ristorante 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"

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

Un restaurantId non attualmente presente nell’account restituisce 404 in caso di aggiornamento o eliminazione.

OpenTable

I ristoranti OpenTable vengono raggiunti tramite le credenziali partner OpenTable della piattaforma, e OpenTable consente a tali credenziali di vedere solo i ristoranti che hanno collegato l’elenco della piattaforma all’interno del Marketplace delle integrazioni di OpenTable. Quindi, come per Formitable, è sufficiente una chiamata di verifica: un ID Ristorante raggiungibile (il “RID” numerico) dimostra sia che il ristorante esiste, sia che ha collegato l’integrazione. Fino a quando l’elenco partner OpenTable non viene abilitato sulla piattaforma, la chiamata di verifica risponde 503.

Verifica un ristorante OpenTable

POST /appointments/opentable-restaurants/verify

Campo Obbligatorio Descrizione
restaurant_id Sì L’ID Ristorante OpenTable (RID), un numero come 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" }'

Risposta (200 OK):

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

verified: false significa che nessun ristorante OpenTable ha quell’ID. Un 403 significa che il ristorante esiste ma non ha ancora collegato l’integrazione della piattaforma all’interno di OpenTable. Limitato a 10 tentativi ogni 5 minuti per account.

Aggiungi un ristorante OpenTable

POST /appointments/opentable-restaurants

Campo Obbligatorio Descrizione
restaurant_id Sì L’ID Ristorante verificato.
restaurant_name Sì Nome visualizzato (un’etichetta; anche come l’IA chiama il ristorante).
website_url No Un URL http(s) mostrato agli ospiti quando l’IA li trasferisce al ristorante.
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" }'

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

Aggiorna un ristorante OpenTable salvato

PUT /appointments/opentable-restaurants/{restaurantId}

Invia uno qualsiasi tra restaurant_name, is_active (metti in pausa con false) o website_url (una stringa vuota lo cancella); i campi omessi rimangono invariati.

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 }'

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

Rimuovere un ristorante 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"

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

Un restaurantId non attualmente presente nell’account restituisce 404 durante l’aggiornamento.

TheFork

I ristoranti TheFork vengono raggiunti tramite le credenziali partner TheFork della piattaforma, e TheFork consente a tali credenziali di vedere solo i ristoranti che hanno il partner della piattaforma abilitato sul proprio account TheFork. Quindi, come per Formitable e OpenTable, una chiamata di verifica è sufficiente: un ID Ristorante raggiungibile dimostra sia che il ristorante esiste sia che il partner è abilitato su di esso. L’ID è l’UUID che TheFork assegna al ristorante in TheFork Manager, inviato come stringa. Finché TheFork non avrà approvato la piattaforma come partner e rilasciato le credenziali, la chiamata di verifica risponderà 503 — vedi TheFork per cosa significa oggi.

Verifica un ristorante TheFork

POST /appointments/thefork-restaurants/verify

Campo Obbligatorio Descrizione
restaurant_id Sì L’ID Ristorante TheFork, un UUID come 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" }'

Risposta (200 OK):

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

partySizes sono le dimensioni del gruppo che il ristorante accetta online nei prossimi 30 giorni. Un 404 o 403 significa che TheFork non ci ha fornito un ristorante con quell’ID — o l’ID è errato, o il partner della piattaforma non è ancora abilitato su quel ristorante; un 400 significa che l’ID non è un UUID. Limitato a 10 tentativi ogni 5 minuti per account.

Aggiungi un ristorante TheFork

POST /appointments/thefork-restaurants

Campo Obbligatorio Descrizione
restaurant_id Sì L’ID Ristorante verificato (UUID).
restaurant_name Sì Nome visualizzato (un’etichetta; è anche come l’AI chiama il ristorante).
website_url No Un URL http(s) mostrato agli ospiti quando l’AI li indirizza al ristorante.
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" }'

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

Aggiorna un ristorante TheFork salvato

PUT /appointments/thefork-restaurants/{restaurantId}

Invia uno qualsiasi tra restaurant_name, is_active (metti in pausa con false) o website_url (una stringa vuota lo cancella); i campi omessi rimangono invariati.

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 }'

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

Rimuovi un ristorante 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"

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

Un restaurantId non attualmente presente nell’account restituisce 404 in caso di aggiornamento o eliminazione.

Trafft

Trafft viene collegato una volta per l’intero account, non per singola sede: un indirizzo aziendale più le credenziali API dal pannello di amministrazione di Trafft (Features & Integrations → API & Connectors, parte del piano Business di Trafft). La chiamata di connessione verifica tali credenziali su Trafft prima di memorizzare qualsiasi cosa, quindi un indirizzo errato, credenziali errate o un piano senza accesso API falliranno in questa fase anziché durante una conversazione con il cliente. Il client secret viene memorizzato crittografato e non viene mai restituito da alcun endpoint.

Tutte e tre le chiamate di scrittura (POST, PUT, DELETE) richiedono l’autorizzazione edit per le Integrazioni; lo stato GET richiede l’autorizzazione view per le Integrazioni.

Collega Trafft

POST /appointments/trafft/connect

Campo Obbligatorio Descrizione
subdomain Sì L’indirizzo aziendale — la parte prima di .admin.trafft.com nell’URL a cui accedi, ad es. acme. Un indirizzo completo viene accettato e ridotto allo stesso valore.
client_id Sì Client ID dalla pagina API & Connectors di Trafft.
client_secret Sì Client Secret dalla stessa pagina. Memorizzato crittografato, mai restituito.
company_name No Un’etichetta per il tuo elenco personale.
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"
  }'

Risposta (200 OK):

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

I conteggi vengono restituiti da Trafft durante la verifica — sono il modo più rapido per confermare che le credenziali puntino all’account desiderato.

Ottieni lo stato della connessione

GET /appointments/trafft

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

Risposta (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 significa che non è ancora stato configurato nulla. Il client secret non è mai incluso in questa risposta.

Aggiorna la connessione

PUT /appointments/trafft

Campo Obbligatorio Descrizione
is_active No Imposta false su pausa: l’IA smette di prenotare su Trafft, la connessione rimane attiva. true la riprende.
company_name No Nuova etichetta.
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 }'

Risposta (200 OK): lo stesso oggetto di connessione del GET qui sopra.

Disconnetti Trafft

DELETE /appointments/trafft

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

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

La disconnessione rimuove solo le credenziali memorizzate. Gli appuntamenti già presenti in Trafft rimangono invariati.

Formato dell’errore su tutti gli endpoint Zenchef/Formitable/OpenTable/TheFork: a differenza del resto di questa pagina, gli errori qui riportano il loro stato due volte — una come stato HTTP e una come error_code nel corpo — ad esempio { "success": false, "error": "Restaurant not found", "error_code": 404 }. Gestiscilo allo stesso modo di qualsiasi altro errore: controlla success, leggi error per il messaggio.


Errori dell’API Appuntamenti

Gli endpoint degli appuntamenti restituiscono il formato di errore standard:

{
  "success": false,
  "error": "Appointment not found"
}
Stato Quando si verifica su un endpoint di appuntamento
400 Un campo obbligatorio manca o non è valido — ad esempio un start_time errato, un end_time non successivo a start_time, una combinazione di filtri non valida, nessun campo da aggiornare o un appuntamento già annullato. Durante la prenotazione: non è stato inviato né event_id né title, entrambi inviati insieme, inviati sia end_time che duration_minutes, un title superiore a 200 caratteri o un duration_minutes al di fuori di 1–1440.
404 L’appuntamento, il contatto o il tipo di evento non è stato trovato.
409 Lo slot temporale richiesto è già occupato (conflitto di prenotazione) o, in caso di aggiornamento, il external_reference è già utilizzato da un altro appuntamento.

I codici condivisi che ogni endpoint può restituire — 401, 403 (il tuo piano non include l’accesso all’API), 429 (limite di frequenza) e 500 — sono elencati con indicazioni sui tentativi in Errori e Paginazione.



Passaggi successivi

  • Contatti — crea e cerca i contatti per cui effettui le prenotazioni.
  • Messaggi e conversazioni — invia a un contatto una conferma o un promemoria.
  • Webhook — ricevi notifiche quando gli appuntamenti cambiano.