Marcações
A API de Marcações permite-lhe marcar compromissos para os seus contactos nos seus tipos de evento, e depois obter, listar, atualizar, cancelar ou eliminá-los. Também responde à pergunta que surge primeiro na maioria dos fluxos de marcação — que horários estão realmente livres — e cobre a parte do calendário: listar os Google Calendars que tem ligados e importar eventos que já existem neles. Quando uma ligação ao Google Calendar está ativa, o evento de calendário correspondente é criado e mantido sincronizado automaticamente em segundo plano. Os restaurantes que utilizam o Zenchef ou o Formitable para o seu próprio sistema de reservas também podem ser verificados e ligados aqui, para que o Agente de IA reserve mesas reais em vez de marcações internas.
Todos os caminhos nesta página são relativos ao URL base https://api.youraiconnector.com/v1. Cada pedido necessita da sua chave de API — consulte Autenticação para obter a lista completa de formas de a enviar. Os exemplos abaixo utilizam o cabeçalho X-API-Key, com um exemplo cURL que mostra também o formulário de consulta ?apiKey=.
Eventos vs. marcações: Um tipo de evento é uma definição de espaço reservável (o tipo de reunião, a sua duração, as suas salas). Uma marcação é uma instância reservada de um tipo de evento para um contacto específico. Reserva uma marcação referenciando o contacto e o tipo de evento.
O objeto de marcação
Cada endpoint que devolve uma marcação utiliza a mesma estrutura:
| Campo | Descrição |
|---|---|
id |
ID único da marcação. |
contact_id |
ID do contacto com quem a marcação foi feita. |
event_id |
ID do tipo de evento em que a marcação foi feita. |
status |
Confirmed ou Canceled. |
start_time |
Início da marcação, ISO 8601 em UTC. |
end_time |
Fim da marcação, ISO 8601 em UTC. |
created_at |
Quando a marcação foi criada. |
last_modified_at |
Quando a marcação foi alterada pela última vez. |
room_name |
Sala ou recurso onde a marcação foi feita, quando o tipo de evento utiliza salas. |
description |
Descrição de formato livre da marcação. |
summary |
Resumo ou título curto. |
cancelation_reason |
Motivo fornecido quando a marcação foi cancelada, se aplicável. |
google_calendar_event_id |
ID do evento do Google Calendar associado. Definido assim que a sincronização do calendário termina; null quando nenhum calendário está ligado ou enquanto a sincronização ainda está em curso. |
calendar_synced |
true assim que a marcação estiver ligada a um evento de calendário. |
imported |
true quando a marcação foi importada de um calendário externo em vez de reservada diretamente. |
is_recurring |
true quando a marcação faz parte de uma série recorrente. |
recurrence_frequency |
Frequência de repetição da marcação, quando recorrente. |
recurring_event_id |
ID da série recorrente a que esta marcação pertence. |
recurring_interval |
Intervalo entre repetições, quando recorrente. |
recurring_sequence |
Posição desta marcação dentro da sua série recorrente. |
end_after_x_occurrences |
Número de ocorrências após as quais a série recorrente termina. |
booking_provider |
Sistema de origem de onde veio a reserva, quando feita através de um fornecedor de reservas ligado. |
Sobre a sincronização de calendário: Logo após reservar ou alterar uma marcação, o
google_calendar_event_idpode ainda sernulle ocalendar_syncedpode serfalseporque a sincronização é executada em segundo plano um momento depois. Obtenha a marcação novamente pouco depois para ver os campos de calendário preenchidos.
Encontrar horários disponíveis
GET /appointments/available-slots
Devolve os horários que estão genuinamente livres num tipo de evento entre dois momentos. Esta é normalmente a primeira chamada num fluxo de marcação: mostre estes horários, deixe a pessoa escolher um e, em seguida, envie a hora escolhida para Marcar um compromisso.
A resposta já tem em conta o horário de funcionamento e a duração dos intervalos do próprio tipo de evento, as suas salas, as marcações que já efetuou nele e tudo o que está bloqueado nos Google Calendars ligados — por isso, um horário que aparece aqui é um horário que pode marcar.
| Parâmetro de consulta | Obrigatório | Descrição |
|---|---|---|
event_id |
Sim | O tipo de evento a verificar. Deve pertencer à sua conta. |
start_time |
Sim | Início da janela para a qual pretende horários, data-hora ISO 8601. |
end_time |
Sim | Fim da janela, data-hora ISO 8601. O dia final completo está incluído. |
Os resultados são devolvidos agrupados por dia — e, quando o tipo de evento utiliza salas, um grupo por sala por dia:
| Campo | Descrição |
|---|---|
date |
O dia que o grupo cobre, escrito DD/MM/YYYY. |
day |
Nome do dia da semana em minúsculas, por exemplo monday. |
room_name |
A sala ou recurso a que este grupo pertence, quando o tipo de evento utiliza salas. |
available_slots |
Os blocos marcáveis nesse dia, do mais cedo para o mais tarde. |
Cada entrada em available_slots tem:
| Campo | Descrição |
|---|---|
start_time |
Início do bloco como HH:mm. |
end_time |
Fim do bloco como HH:mm. |
available |
true — apenas é devolvido tempo livre. |
spots_left |
Quantas marcações ainda cabem neste bloco. Apenas presente em tipos de evento que aceitam mais do que uma marcação por intervalo. |
Os horários são locais ao tipo de evento, não UTC.
date,start_timeeend_timesão valores de relógio de parede no fuso horário do próprio tipo de evento (a sua substituição, ou o fuso horário da sua conta quando não tem nenhum). Marcar um compromisso espera um instante UTC ISO 8601, por isso converta o horário que escolheu antes de o enviar.
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"])
Resposta (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 }
]
}
]
}
Um dia sem nada livre simplesmente não aparece. A falta de event_id, start_time ou end_time devolve 400; um tipo de evento que não está na sua conta devolve 404.
Reservar uma marcação
POST /appointments
Reserva uma nova marcação para um contacto num dos seus tipos de evento. A hora de fim é calculada automaticamente a partir da duração do espaço do tipo de evento.
A reserva é verificada quanto a conflitos: se o espaço solicitado se sobrepuser a uma marcação confirmada existente no mesmo tipo de evento, o pedido falha com um 409 e nada é criado.
| Campo | Obrigatório | Descrição |
|---|---|---|
contact_id |
Sim | ID do contacto para o qual reservar. Deve pertencer à sua conta. |
event_id |
Sim | ID do tipo de evento em que reservar. Deve pertencer à sua conta. |
start_time |
Sim | Início pretendido como uma data-hora ISO 8601. |
room_name |
Não | Nome da sala ou recurso, quando o tipo de evento utiliza salas. |
cURL (utilizando o formulário 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"])
Resposta (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
}
}
Obter um agendamento
GET /appointments/{appointmentId}
Devolve um único agendamento pelo seu ID, incluindo o seu estado de sincronização de calendário.
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"])
Resposta (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 agendamentos
GET /appointments
Lista os agendamentos da sua conta, do mais recente para o mais antigo, com paginação baseada em cursor.
| Parâmetro de consulta | Obrigatório | Descrição |
|---|---|---|
contact_id |
Não | Devolve apenas agendamentos para este contacto. As listagens filtradas por contacto incluem apenas agendamentos confirmados |
date |
Não | Devolve apenas agendamentos neste dia de calendário (YYYY-MM-DD). Requer contact_id. |
status |
Não | Filtrar por Confirmed ou Canceled. Disponível apenas sem contact_id. |
limit |
Não | Tamanho da página, um número inteiro entre 1 e 100. Predefinição 50. |
cursor |
Não | O valor next_cursor de uma resposta anterior. |
Algumas regras a ter em conta:
- Sem filtros, obtém todos os agendamentos da conta, página a página.
- Por contacto — defina
contact_idpara ver os agendamentos confirmados de um contacto. Pode restringir a um único dia passando tambémdate. - Por estado — defina
status(semcontact_id) para listar apenas agendamentosConfirmedou apenasCanceledem toda a conta. - O filtro
datesemcontact_id, oustatus=Canceledjuntamente comcontact_id, devolve um400.
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"])
Resposta (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 navegar entre os resultados, passe o next_cursor de uma resposta como o cursor do pedido seguinte. Continue até que next_cursor seja null. Consulte Erros e Paginação para o padrão de paginação partilhado.
Atualizar um agendamento
PUT /appointments/{appointmentId}
Reagende um compromisso ou altere os seus detalhes. Envie apenas os campos que pretende alterar — é necessário pelo menos um. O início e o fim combinados devem manter-se por ordem cronológica (end_time deve ser posterior a start_time). As alterações são sincronizadas automaticamente com o evento do calendário associado.
| Campo | Descrição |
|---|---|
start_time |
Novo início, data-hora ISO 8601. |
end_time |
Novo fim, data-hora ISO 8601. Deve ser posterior à hora de início. |
room_name |
Novo nome da sala ou recurso. |
description |
Nova descrição, ou null para a limpar. |
summary |
Novo resumo, ou null para o limpar. |
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"])
Resposta (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 um agendamento
POST /appointments/{appointmentId}/cancel
Cancela um agendamento confirmado, registando opcionalmente um motivo. O agendamento permanece na sua conta com o estado Canceled e o evento de calendário associado é removido automaticamente em segundo plano. O cancelamento de um agendamento já cancelado devolve um 400.
| Campo | Obrigatório | Descrição |
|---|---|---|
cancellation_reason |
Não | Motivo do cancelamento, guardado no agendamento. |
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"])
Resposta (200 OK):
{
"success": true,
"appointment_id": "aBcD1234eFgH5678"
}
Eliminar um agendamento
DELETE /appointments/{appointmentId}
Elimina permanentemente um agendamento e as suas referências. Se apenas pretende cancelar a marcação mantendo o registo, utilize cancelar em vez disso.
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"])
Resposta (200 OK):
{
"success": true
}
Listar os seus Google Calendars ligados
GET /appointments/google-calendars
Devolve os Google Calendars disponíveis nesta conta, diretamente do Google — útil para mostrar ao titular da conta um seletor de qual calendário importar abaixo, ou apenas para confirmar que a ligação está ativa.
Isto só funciona depois de a conta ter ligado o Google Calendar (Definições → Integrações) com, pelo menos, acesso de leitura. Se não o tiver feito, ou se o acesso concedido já não incluir o âmbito de leitura do calendário, receberá um 400 a indicar-lhe que deve ligá-lo (ou ligá-lo novamente).
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"])
Resposta (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 tem o formato CalendarListEntry da própria Google, pelo que os nomes dos campos seguem a camelCase da Google e não a snake_case habitual desta API — são dados da Google transmitidos tal como estão, não os nossos. Uma ligação em falta ou revogada devolve um 400 com um erro a explicar que o Google Calendar precisa de ser ligado (ou ligado novamente).
Importar eventos de um Google Calendar
POST /appointments/import-calendar-events
Extrai os eventos que já se encontram nos Google Calendar(s) ligados a uma campanha ou a um Agente de IA e transforma-os em marcações — útil na primeira vez que liga um calendário que já tem reservas. Isto pode demorar algum tempo (cada evento passa por um processo de extração para determinar a quem se destina), pelo que nunca é executado em linha: o pedido coloca em fila de espera um trabalho de fundo e devolve-lhe um job_id para consulta.
| Campo | Obrigatório | Descrição |
|---|---|---|
campaign_id |
Um destes dois | A campanha cujos calendários ligados devem ser importados. |
agent_id |
Um destes dois | O Agente de IA cujos calendários ligados devem ser importados. |
identifier |
Sim | "EMAIL" ou "PHONE_NUMBER" — que informação de contacto extrair de cada evento do calendário para corresponder ou criar o contacto a que pertence. |
Envie exatamente um de campaign_id / agent_id, nunca ambos e nunca nenhum — qualquer uma destas combinações devolve um 400. O que enviar tem de pertencer à sua conta, caso contrário receberá um 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"])
Resposta (202 Accepted):
{
"success": true,
"job_id": "jK9mQ2xR7pL4wN1t",
"status": "queued",
"campaign_id": null,
"agent_id": "agent_abc123"
}
campaign_id e agent_id devolvem o que enviou; o outro é sempre null.
Consultar o trabalho de importação
GET /appointments/import-calendar-events/{jobId}
curl "https://api.youraiconnector.com/v1/appointments/import-calendar-events/jK9mQ2xR7pL4wN1t" \
-H "X-API-Key: YOUR_API_KEY"
Resposta (200 OK):
{
"success": true,
"job_id": "jK9mQ2xR7pL4wN1t",
"status": "completed",
"message": "Imported 12 events as appointments.",
"error": null
}
status |
Significado |
|---|---|
queued |
Ainda não processado. Continue a consultar. |
processing |
A importação está em curso. Continue a consultar. |
completed |
Concluído — message contém um breve resumo legível. |
failed |
Algo correu mal — error contém o motivo. |
GET num jobId que não existe (ou que pertence a uma conta diferente) devolve 404.
Integrações de reservas de restaurantes (Zenchef / Formitable)
O Zenchef e o Formitable são sistemas de reserva de restaurantes através dos quais o seu Agente de IA pode reservar mesas reais. Cada um tem um widget de reserva público e não autenticado (https://api.youraiconnector.com/v1/zenchef-widget/... e https://api.youraiconnector.com/v1/formitable-widget/...) que é apresentado no chat para o cliente — essas rotas de widget são páginas HTML simples destinadas a ser abertas num navegador, não pontos de extremidade de API JSON, pelo que não estão documentadas aqui. O que se segue são os pontos de extremidade de gestão de conta: verificar se um ID de restaurante pertence ao titular da conta e, em seguida, adicioná-lo, atualizá-lo ou removê-lo.
Zenchef
A ligação de um restaurante Zenchef é um processo de verificação de dois passos, para que o titular da conta prove que realmente gere o restaurante antes de este ser ligado ao bot: primeiro, verifique se o ID existe (sem revelar o nome), depois peça-lhe para escrever o nome do restaurante e verifique se corresponde.
Passo 1 — Verificar se um ID de restaurante existe
POST /appointments/zenchef-restaurants/check
| Campo | Obrigatório | Descrição |
|---|---|---|
restaurant_id |
Sim | O ID do restaurante Zenchef a verificar. |
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" }'
Resposta (200 OK):
{
"success": true,
"data": { "exists": true, "requiresNameVerification": true }
}
exists: false significa que nenhum restaurante Zenchef tem esse ID — não há mais nada a fazer. Limitado a 10 verificações por cada 5 minutos por conta; exceder este limite devolve 429.
Passo 2 — Verificar o nome do restaurante
POST /appointments/zenchef-restaurants/verify-name
| Campo | Obrigatório | Descrição |
|---|---|---|
restaurant_id |
Sim | O ID do restaurante Zenchef do passo 1. |
user_input_name |
Sim | O nome que o titular da conta escreveu — comparado com o nome real do restaurante no Zenchef (insensível a maiúsculas/minúsculas e espaços). |
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" }'
Resposta (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 o nome não correspondeu — restaurantDetails é omitido, peça ao titular da conta para tentar novamente. Limitado a 3 tentativas por cada 5 minutos (mais restrito do que a verificação de existência, uma vez que este é o passo de prova real). Um restaurant_id que já não é resolvido no Zenchef devolve 404.
Passo 3 — Guardar o restaurante
POST /appointments/zenchef-restaurants
| Campo | Obrigatório | Descrição |
|---|---|---|
restaurant_id |
Sim | 1–64 caracteres, letras/números/underscore/hífen. |
restaurant_name |
Sim | O nome do restaurante verificado do passo 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" }'
Resposta (201 Created):
{ "success": true, "data": { "restaurantId": "12345" } }
Atualizar um restaurante Zenchef guardado
PUT /appointments/zenchef-restaurants/{restaurantId}
| Campo | Obrigatório | Descrição |
|---|---|---|
restaurant_name |
Não | Novo nome de apresentação. |
is_active |
Não | Defina false para impedir que o bot efetue reservas neste restaurante sem o remover. |
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 }'
Resposta (200 OK): mesma estrutura que a resposta de guardar acima.
Remover um 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"
Resposta (200 OK): { "success": true, "data": { "restaurantId": "12345" } }
Um restaurantId que não esteja atualmente na conta devolve 404 ao atualizar ou eliminar.
Formitable
O Formitable não necessita da prova de nome em dois passos como o Zenchef — os seus IDs de restaurante já estão delimitados por empresa, pelo que uma chamada de verificação é suficiente. Também possui uma consulta de detalhes utilizada para colocar em cache o URL do website do restaurante durante a configuração.
Verificar um ID de restaurante
POST /appointments/formitable-restaurants/verify
| Campo | Obrigatório | Descrição |
|---|---|---|
restaurant_id |
Sim | O ID de restaurante Formitable. |
language |
Não | Etiqueta de idioma para o pedido de sondagem. O valor predefinido é "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" }'
Resposta (200 OK):
{
"success": true,
"data": {
"verified": true,
"restaurantDetails": {
"restaurantId": "the-blue-door",
"productCount": 4,
"sampleProductTitle": "Dinner for two",
"language": "en"
}
}
}
Um restaurant_id que o Formitable não reconheça devolve 404. Limitado a 10 tentativas por cada 5 minutos por conta.
Obter detalhes do restaurante
GET /appointments/formitable-restaurants/{restaurantId}/details?language=en
Obtém o perfil público do restaurante a partir do Formitable, incluindo o seu website — utilizado para colocar em cache o URL do website durante a configuração do restaurante. language é um parâmetro de consulta opcional, com o valor predefinido "en".
curl "https://api.youraiconnector.com/v1/appointments/formitable-restaurants/the-blue-door/details?language=en" \
-H "X-API-Key: YOUR_API_KEY"
Resposta (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 o restaurante
POST /appointments/formitable-restaurants
| Campo | Obrigatório | Descrição |
|---|---|---|
restaurant_id |
Sim | 1–64 caracteres, letras/números/underscore/hífen. |
restaurant_name |
Sim | Nome a apresentar. |
language |
Sim | Etiqueta de idioma ISO, p. ex. "en" ou "en-GB". |
website_url |
Não | O website do restaurante, a partir da consulta de detalhes acima. Deve 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"
}'
Resposta (201 Created): { "success": true, "data": { "restaurantId": "the-blue-door" } }
Atualizar um restaurante Formitable guardado
PUT /appointments/formitable-restaurants/{restaurantId}
| Campo | Obrigatório | Descrição |
|---|---|---|
restaurant_name |
Não | Novo nome a apresentar. |
language |
Não | Nova etiqueta de idioma ISO. |
is_active |
Não | Defina false para impedir que o bot efetue reservas neste restaurante sem o remover. |
website_url |
Não | Novo URL do website. |
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 }'
Resposta (200 OK): mesma estrutura que a resposta de guardar acima.
Remover um 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"
Resposta (200 OK): { "success": true, "data": { "restaurantId": "the-blue-door" } }
Um restaurantId que não esteja atualmente na conta devolve 404 ao atualizar ou eliminar.
Estrutura de erro em todos os endpoints Zenchef/Formitable: ao contrário do resto desta página, os erros aqui apresentam o seu estado duas vezes — uma como estado HTTP e outra como
error_codeno corpo — por exemplo{ "success": false, "error": "Restaurant not found", "error_code": 404 }. Trate-o da mesma forma que qualquer outro erro: verifiquesuccess, leiaerrorpara obter a mensagem.
Erros da API de marcações
Os endpoints de marcações devolvem o envelope de erro padrão:
{
"success": false,
"error": "Appointment not found"
}
| Estado | Quando ocorre num endpoint de marcação |
|---|---|
400 |
Falta um campo obrigatório ou este é inválido — por exemplo, um start_time incorreto, uma end_time que não é posterior a start_time, uma combinação de filtros inválida, ausência de campos para atualizar ou uma marcação já cancelada. |
404 |
A marcação, o contacto ou o tipo de evento não foi encontrado. |
409 |
O intervalo de tempo solicitado já está ocupado (conflito de agendamento). |
Os códigos partilhados que qualquer endpoint pode devolver — 401, 403 (o seu plano não inclui acesso à API), 429 (limite de taxa) e 500 — estão listados com orientações de repetição em Erros e Paginação.
Próximos passos
- Contactos — crie e procure os contactos para os quais efetua reservas.
- Mensagens e Conversas — envie uma confirmação ou um lembrete a um contacto.
- Webhooks — receba notificações quando os agendamentos forem alterados.