Citas
La API de Citas le permite reservar citas para sus contactos en sus tipos de evento, así como obtener, listar, actualizar, cancelar o eliminar dichas citas. También responde a la pregunta que surge primero en la mayoría de los flujos de reserva —qué horarios están realmente libres— y cubre el aspecto del calendario: listar los calendarios de Google que tiene conectados e importar eventos que ya existen en ellos. Cuando una conexión de Google Calendar está activa, el evento de calendario correspondiente se crea y se mantiene sincronizado automáticamente en segundo plano. Los restaurantes que utilizan Zenchef o Formitable para su propio sistema de reservas también pueden ser verificados y conectados aquí, de modo que el Agente de IA reserve mesas reales en lugar de citas internas.
Todas las rutas en esta página son relativas a la URL base https://api.youraiconnector.com/v1. Cada solicitud requiere su clave de API; consulte Autenticación para ver la lista completa de formas de enviarla. Los ejemplos a continuación utilizan el encabezado X-API-Key, y un ejemplo de cURL muestra también el formato de consulta ?apiKey=.
Eventos vs. citas: Un tipo de evento es una definición de espacio reservable (el tipo de reunión, su duración, sus salas). Una cita es una instancia reservada de un tipo de evento para un contacto específico. Usted reserva una cita haciendo referencia al contacto y al tipo de evento.
El objeto de cita
Cada endpoint que devuelve una cita utiliza la misma estructura:
| Campo | Descripción |
|---|---|
id |
ID único de la cita. |
contact_id |
ID del contacto con el que se reserva la cita. |
event_id |
ID del tipo de evento en el que se reservó la cita. |
status |
Confirmed o Canceled. |
start_time |
Inicio de la cita, ISO 8601 en UTC. |
end_time |
Fin de la cita, ISO 8601 en UTC. |
created_at |
Cuándo se creó la cita. |
last_modified_at |
Cuándo se cambió la cita por última vez. |
room_name |
Sala o recurso en el que se reserva la cita, cuando el tipo de evento utiliza salas. |
description |
Descripción de formato libre de la cita. |
summary |
Resumen o título breve. |
cancelation_reason |
Motivo proporcionado cuando se canceló la cita, si existe. |
google_calendar_event_id |
ID del evento de Google Calendar vinculado. Se establece una vez que se completa la sincronización del calendario; null cuando no hay ningún calendario conectado o mientras la sincronización aún está en curso. |
calendar_synced |
true una vez que la cita está vinculada a un evento de calendario. |
imported |
true cuando la cita se importó desde un calendario externo en lugar de reservarse directamente. |
is_recurring |
true cuando la cita es parte de una serie recurrente. |
recurrence_frequency |
Con qué frecuencia se repite la cita, cuando es recurrente. |
recurring_event_id |
ID de la serie recurrente a la que pertenece esta cita. |
recurring_interval |
Intervalo entre repeticiones, cuando es recurrente. |
recurring_sequence |
Posición de esta cita dentro de su serie recurrente. |
end_after_x_occurrences |
Número de ocurrencias después de las cuales finaliza la serie recurrente. |
booking_provider |
Sistema de origen del que proviene la reserva, cuando se reserva a través de un proveedor de reservas conectado. |
Acerca de la sincronización de calendario: Justo después de reservar o cambiar una cita,
google_calendar_event_idpuede seguir siendonullycalendar_syncedpuede serfalseporque la sincronización se ejecuta en segundo plano un momento después. Vuelva a obtener la cita poco después para ver los campos de calendario completados.
Encontrar espacios disponibles
GET /appointments/available-slots
Devuelve los horarios que están realmente libres en un tipo de evento entre dos momentos. Esta suele ser la primera llamada en un flujo de reserva: mostrar estos espacios, dejar que la persona elija uno y, a continuación, enviar la hora elegida a Reservar una cita.
La respuesta ya tiene en cuenta el horario de apertura y la duración del espacio del tipo de evento, sus salas, las citas que ya ha reservado en él y todo lo bloqueado en los calendarios de Google conectados; por lo tanto, un espacio que se devuelve aquí es uno que puede reservar.
| Parámetro de consulta | Requerido | Descripción |
|---|---|---|
event_id |
Sí | El tipo de evento a consultar. Debe pertenecer a su cuenta. |
start_time |
Sí | Inicio de la ventana para la que desea espacios, fecha y hora en formato ISO 8601. |
end_time |
Sí | Fin de la ventana, fecha y hora en formato ISO 8601. Se incluye el día final completo. |
Los resultados se devuelven agrupados por día y, cuando el tipo de evento utiliza salas, un grupo por sala por día:
| Campo | Descripción |
|---|---|
date |
El día que cubre el grupo, escrito DD/MM/YYYY. |
day |
Nombre del día de la semana en minúsculas, por ejemplo monday. |
room_name |
La sala o recurso al que pertenece este grupo, cuando el tipo de evento utiliza salas. |
available_slots |
Los bloques reservables en ese día, ordenados del más temprano al más tardío. |
Cada entrada en available_slots tiene:
| Campo | Descripción |
|---|---|
start_time |
Inicio del bloque como HH:mm. |
end_time |
Fin del bloque como HH:mm. |
available |
true — solo se devuelve el tiempo libre. |
spots_left |
Cuántas reservas aún caben en este bloque. Solo presente en tipos de evento que aceptan más de una reserva por espacio. |
Los horarios son locales al tipo de evento, no UTC.
date,start_timeyend_timeson valores de reloj de pared en la zona horaria propia del tipo de evento (su anulación, o la zona horaria de su cuenta cuando no tiene ninguna). Reservar una cita espera un instante UTC en formato ISO 8601, así que convierta el espacio que eligió antes de enviarlo.
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"])
Respuesta (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 día sin disponibilidad simplemente no aparece. Si faltan event_id, start_time o end_time, se devuelve 400; un tipo de evento que no está en su cuenta devuelve 404.
Reservar una cita
POST /appointments
Reserva una nueva cita para un contacto en uno de sus tipos de evento. La hora de finalización se calcula automáticamente a partir de la duración del espacio del tipo de evento.
La reserva se verifica para detectar conflictos: si el espacio solicitado se superpone con una cita confirmada existente en el mismo tipo de evento, la solicitud falla con un 409 y no se crea nada.
| Campo | Requerido | Descripción |
|---|---|---|
contact_id |
Sí | ID del contacto para el que reservar. Debe pertenecer a su cuenta. |
event_id |
Sí | ID del tipo de evento en el que reservar. Debe pertenecer a su cuenta. |
start_time |
Sí | Inicio deseado como fecha y hora ISO 8601. |
room_name |
No | Nombre de la sala o recurso, cuando el tipo de evento utiliza salas. |
cURL (usando el formato de consulta ?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"])
Respuesta (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
}
}
Obtener una cita
GET /appointments/{appointmentId}
Devuelve una única cita por su ID, incluido su estado de sincronización de 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"])
Respuesta (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
}
}
Listar citas
GET /appointments
Enumera las citas de su cuenta, de la más reciente a la más antigua, con paginación basada en cursor.
| Parámetro de consulta | Obligatorio | Descripción |
|---|---|---|
contact_id |
No | Solo devuelve citas para este contacto. Los listados filtrados por contacto incluyen solo citas confirmadas. |
date |
No | Solo devuelve citas en este día del calendario (YYYY-MM-DD). Requiere contact_id. |
status |
No | Filtrar por Confirmed o Canceled. Solo disponible sin contact_id. |
limit |
No | Tamaño de página, un número entero entre 1 y 100. El valor predeterminado es 50. |
cursor |
No | El valor next_cursor de una respuesta anterior. |
Algunas reglas a tener en cuenta:
- Sin filtros, obtendrá todas las citas de la cuenta, página por página.
- Por contacto: establezca
contact_idpara ver las citas confirmadas de un contacto. Puede restringir esto a un solo día pasando tambiéndate. - Por estado: establezca
status(sincontact_id) para listar solo las citasConfirmedo solo lasCanceleden toda la cuenta. - El filtro
datesincontact_id, ostatus=Canceledjunto concontact_id, devuelve un400.
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"])
Respuesta (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
}
Para paginar los resultados, pase el next_cursor de una respuesta como el cursor de la siguiente solicitud. Continúe hasta que next_cursor sea null. Consulte Errores y paginación para conocer el patrón de paginación compartido.
Actualizar una cita
PUT /appointments/{appointmentId}
Reprogramar una cita o cambiar sus detalles. Envíe solo los campos que desea cambiar; al menos uno es obligatorio. El inicio y el fin combinados deben permanecer en orden cronológico (end_time debe ser posterior a start_time). Los cambios se sincronizan automáticamente con el evento del calendario vinculado.
| Campo | Descripción |
|---|---|
start_time |
Nueva fecha y hora de inicio, en formato ISO 8601. |
end_time |
Nueva fecha y hora de finalización, en formato ISO 8601. Debe ser posterior a la hora de inicio. |
room_name |
Nuevo nombre de sala o recurso. |
description |
Nueva descripción, o null para borrarla. |
summary |
Nuevo resumen, o null para borrarlo. |
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"])
Respuesta (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
}
}
Cancelar una cita
POST /appointments/{appointmentId}/cancel
Cancela una cita confirmada, registrando opcionalmente un motivo. La cita permanece en su cuenta con el estado Canceled y el evento de calendario vinculado se elimina automáticamente en segundo plano. Cancelar una cita que ya ha sido cancelada devuelve un 400.
| Campo | Obligatorio | Descripción |
|---|---|---|
cancellation_reason |
No | Motivo de la cancelación, almacenado en la cita. |
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"])
Respuesta (200 OK):
{
"success": true,
"appointment_id": "aBcD1234eFgH5678"
}
Eliminar una cita
DELETE /appointments/{appointmentId}
Elimina permanentemente una cita y sus referencias. Si solo desea cancelar la reserva manteniendo el registro, utilice cancelar en su lugar.
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"])
Respuesta (200 OK):
{
"success": true
}
Listar sus calendarios de Google conectados
GET /appointments/google-calendars
Devuelve los calendarios de Google disponibles en esta cuenta, directamente desde Google; es útil para mostrar al titular de la cuenta un selector desde el cual importar, o simplemente para confirmar que la conexión está activa.
Esto solo funciona una vez que la cuenta ha conectado Google Calendar (Ajustes → Integraciones) con al menos acceso de lectura. Si no lo ha hecho, o si el acceso concedido ya no incluye el ámbito de lectura de calendario, obtendrá un 400 que le indicará que lo (re)conecte.
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"])
Respuesta (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"
}
]
}
Cada entrada tiene la forma del propio CalendarListEntry de Google, por lo que los nombres de los campos siguen el camelCase de Google, no el snake_case habitual de esta API; es decir, son los datos de Google transmitidos tal cual, no los nuestros. Una conexión faltante o revocada devuelve un 400 con un error que explica que Google Calendar debe ser (re)conectado.
Importar eventos desde un Google Calendar
POST /appointments/import-calendar-events
Extrae los eventos que ya se encuentran en los Google Calendar conectados de una campaña o un Agente de IA y los convierte en citas; es útil la primera vez que conecta un calendario que ya tiene reservas. Esto puede llevar tiempo (cada evento pasa por un proceso de extracción para determinar a quién pertenece), por lo que nunca se ejecuta en línea: la solicitud pone en cola un trabajo en segundo plano y le devuelve un job_id para realizar consultas.
| Campo | Obligatorio | Descripción |
|---|---|---|
campaign_id |
Uno de estos dos | La campaña desde cuyos calendarios conectados importar. |
agent_id |
Uno de estos dos | El Agente de IA desde cuyos calendarios conectados importar. |
identifier |
Sí | "EMAIL" o "PHONE_NUMBER": qué pieza de información de contacto extraer de cada evento del calendario para buscar o crear el contacto al que pertenece. |
Envíe exactamente uno de campaign_id / agent_id, nunca ambos y nunca ninguno; cualquier otra combinación devuelve un 400. Cualquiera que envíe debe pertenecer a su cuenta, o recibirá 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"])
Respuesta (202 Accepted):
{
"success": true,
"job_id": "jK9mQ2xR7pL4wN1t",
"status": "queued",
"campaign_id": null,
"agent_id": "agent_abc123"
}
campaign_id y agent_id devuelven el valor que usted envió; el otro es siempre null.
Consultar el trabajo de importación
GET /appointments/import-calendar-events/{jobId}
curl "https://api.youraiconnector.com/v1/appointments/import-calendar-events/jK9mQ2xR7pL4wN1t" \
-H "X-API-Key: YOUR_API_KEY"
Respuesta (200 OK):
{
"success": true,
"job_id": "jK9mQ2xR7pL4wN1t",
"status": "completed",
"message": "Imported 12 events as appointments.",
"error": null
}
status |
Significado |
|---|---|
queued |
Aún no se ha procesado. Siga consultando. |
processing |
La importación está en curso. Siga consultando. |
completed |
Finalizado: message contiene un breve resumen legible para humanos. |
failed |
Algo salió mal: error contiene el motivo. |
GET en un jobId que no existe (o que pertenece a una cuenta diferente) devuelve un 404.
Integraciones de reservas de restaurantes (Zenchef / Formitable)
Zenchef y Formitable son sistemas de reserva de restaurantes a través de los cuales su Agente de IA puede reservar mesas reales. Cada uno tiene un widget de reserva público y sin autenticar (https://api.youraiconnector.com/v1/zenchef-widget/... y https://api.youraiconnector.com/v1/formitable-widget/...) que se muestra dentro del chat para el comensal; esas rutas del widget son páginas HTML simples destinadas a abrirse en un navegador, no puntos finales de API JSON, por lo que no están documentadas aquí. A continuación, se presentan los puntos finales de gestión de cuentas: verificar que un ID de restaurante pertenece al titular de la cuenta y, posteriormente, añadirlo, actualizarlo o eliminarlo.
Zenchef
Conectar un restaurante de Zenchef es una verificación de dos pasos, por lo que el titular de la cuenta demuestra que realmente dirige el restaurante antes de que se conecte al bot: primero se comprueba que el ID existe (sin revelar el nombre) y, a continuación, se le pide que escriba el nombre del restaurante para verificar que coincide.
Paso 1 — Comprobar que existe un ID de restaurante
POST /appointments/zenchef-restaurants/check
| Campo | Obligatorio | Descripción |
|---|---|---|
restaurant_id |
Sí | El ID del restaurante Zenchef que se va a comprobar. |
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" }'
Respuesta (200 OK):
{
"success": true,
"data": { "exists": true, "requiresNameVerification": true }
}
exists: false significa que ningún restaurante de Zenchef tiene ese ID; no hay nada más que hacer. Limitado a 10 comprobaciones por cada 5 minutos por cuenta; exceder este límite devuelve 429.
Paso 2 — Verificar el nombre del restaurante
POST /appointments/zenchef-restaurants/verify-name
| Campo | Obligatorio | Descripción |
|---|---|---|
restaurant_id |
Sí | El ID del restaurante Zenchef del paso 1. |
user_input_name |
Sí | El nombre que escribió el titular de la cuenta, comparado con el nombre real del restaurante en Zenchef (sin distinguir entre mayúsculas y minúsculas ni espacios en blanco). |
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" }'
Respuesta (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 que el nombre no coincidió; restaurantDetails se omite, pida al titular de la cuenta que lo intente de nuevo. Limitado a 3 intentos cada 5 minutos (más estricto que la comprobación de existencia, ya que este es el paso de prueba real). Un restaurant_id que ya no se resuelve en Zenchef devuelve 404.
Paso 3 — Guardar el restaurante
POST /appointments/zenchef-restaurants
| Campo | Obligatorio | Descripción |
|---|---|---|
restaurant_id |
Sí | 1–64 caracteres, letras/números/guion bajo/guion. |
restaurant_name |
Sí | El nombre del restaurante verificado del paso 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" }'
Respuesta (201 Created):
{ "success": true, "data": { "restaurantId": "12345" } }
Actualizar un restaurante Zenchef guardado
PUT /appointments/zenchef-restaurants/{restaurantId}
| Campo | Obligatorio | Descripción |
|---|---|---|
restaurant_name |
No | Nuevo nombre de visualización. |
is_active |
No | Establezca false para evitar que el bot realice reservas en este restaurante sin eliminarlo. |
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 }'
Respuesta (200 OK): misma estructura que la respuesta de guardado anterior.
Eliminar un restaurante 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"
Respuesta (200 OK): { "success": true, "data": { "restaurantId": "12345" } }
Un restaurantId que no esté actualmente en la cuenta devuelve 404 al intentar actualizar o eliminar.
Formitable
Formitable no necesita la prueba de nombre de dos pasos que requiere Zenchef; sus ID de restaurante ya están definidos por negocio, por lo que una llamada de verificación es suficiente. También cuenta con una búsqueda de detalles que se utiliza para almacenar en caché la URL del sitio web del restaurante durante la configuración.
Verificar un ID de restaurante
POST /appointments/formitable-restaurants/verify
| Campo | Obligatorio | Descripción |
|---|---|---|
restaurant_id |
Sí | El ID de restaurante de Formitable. |
language |
No | Etiqueta de idioma para la solicitud de sondeo. El valor predeterminado es "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" }'
Respuesta (200 OK):
{
"success": true,
"data": {
"verified": true,
"restaurantDetails": {
"restaurantId": "the-blue-door",
"productCount": 4,
"sampleProductTitle": "Dinner for two",
"language": "en"
}
}
}
Un restaurant_id que Formitable no reconoce devuelve 404. Limitado a 10 intentos por cada 5 minutos por cuenta.
Obtener detalles del restaurante
GET /appointments/formitable-restaurants/{restaurantId}/details?language=en
Obtiene el perfil público del restaurante desde Formitable, incluida su página web; se utiliza para almacenar en caché la URL del sitio web mientras se configura el restaurante. language es un parámetro de consulta opcional, cuyo valor predeterminado es "en".
curl "https://api.youraiconnector.com/v1/appointments/formitable-restaurants/the-blue-door/details?language=en" \
-H "X-API-Key: YOUR_API_KEY"
Respuesta (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"
}
}
Guardar el restaurante
POST /appointments/formitable-restaurants
| Campo | Obligatorio | Descripción |
|---|---|---|
restaurant_id |
Sí | 1–64 caracteres, letras/números/guion bajo/guion. |
restaurant_name |
Sí | Nombre para mostrar. |
language |
Sí | Etiqueta de idioma ISO, p. ej., "en" o "en-GB". |
website_url |
No | El sitio web del restaurante, obtenido de la búsqueda de detalles anterior. Debe ser 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"
}'
Respuesta (201 Created): { "success": true, "data": { "restaurantId": "the-blue-door" } }
Actualizar un restaurante Formitable guardado
PUT /appointments/formitable-restaurants/{restaurantId}
| Campo | Obligatorio | Descripción |
|---|---|---|
restaurant_name |
No | Nuevo nombre para mostrar. |
language |
No | Nueva etiqueta de idioma ISO. |
is_active |
No | Establezca false para evitar que el bot realice reservas en este restaurante sin eliminarlo. |
website_url |
No | Nueva URL del sitio 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 }'
Respuesta (200 OK): misma estructura que la respuesta de guardado anterior.
Eliminar un restaurante 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"
Respuesta (200 OK): { "success": true, "data": { "restaurantId": "the-blue-door" } }
Un restaurantId que no esté actualmente en la cuenta devuelve 404 al intentar actualizar o eliminar.
Estructura de error en todos los endpoints de Zenchef/Formitable: a diferencia del resto de esta página, los errores aquí incluyen su estado dos veces (una como estado HTTP y otra como
error_codeen el cuerpo), por ejemplo{ "success": false, "error": "Restaurant not found", "error_code": 404 }. Manéjelo de la misma manera que cualquier otro error: verifiquesuccessy leaerrorpara obtener el mensaje.
Errores de la API de citas
Los endpoints de citas devuelven el sobre de error estándar:
{
"success": false,
"error": "Appointment not found"
}
| Estado | Cuándo ocurre en un endpoint de citas |
|---|---|
400 |
Falta un campo obligatorio o no es válido; por ejemplo, un start_time incorrecto, una end_time que no es posterior a start_time, una combinación de filtros no válida, no hay campos para actualizar o una cita ya cancelada. |
404 |
No se encontró la cita, el contacto o el tipo de evento. |
409 |
La franja horaria solicitada ya está ocupada (conflicto de reserva). |
Los códigos compartidos que puede devolver cualquier endpoint — 401, 403 (su plan no incluye acceso a la API), 429 (límite de tasa) y 500 — se enumeran con orientación sobre reintentos en Errores y paginación.
Próximos pasos
- Contactos — cree y busque los contactos para los que realiza reservas.
- Mensajes y conversaciones — envíe a un contacto una confirmación o un recordatorio.
- Webhooks — reciba notificaciones cuando cambien las citas.