Tema
Agenda
A API lê os serviços e os horários livres e cria e gerencia os agendamentos da Agenda da empresa. Todo agendamento criado por aqui aparece no calendário da tela como qualquer outro, com a origem "API". As regras de horário (expediente, feriados, capacidade, antecedência mínima e limite de dias) são as mesmas da tela.
Para ser avisado quando algo muda na agenda, veja Webhooks. Para quem não programa, veja Integrações da agenda.
Antes de começar
- O endereço base é
https://konversia.com.br/api/v1/agenda, com o cabeçalhoAuthorization: Bearer <sua-chave>. Veja Autenticação. - Existem dois escopos:
agenda:read(os quatroGET) eagenda:write(todoPOSTe oDELETE). Sem o escopo, a resposta é403 forbidden_scope. Veja Permissões para o que mais cada um libera. - A Agenda é um módulo à parte. Com o módulo desligado na empresa, todo endpoint desta página devolve
403 module_disabled, comerror.details.moduleigual aagenda. - Um id (de agendamento, serviço ou contato) de outra empresa ou inexistente devolve
404 not_found. A exceção são os filtrosservice_idecontact_idda listagem de agendamentos: ali o id só não encontra nada, e a resposta é200comdatavazio. Um id malformado (abc, por exemplo) só devolve404 not_foundquando é o id do agendamento na URL. Umservice_idoucontact_idmalformado no corpo ou na consulta devolve422 validation_failed. - O limite é de 120 requisições por minuto por chave, o mesmo da API toda.
| Método e caminho | Escopo | O que faz |
|---|---|---|
GET /v1/agenda/services | agenda:read | Lista os serviços ativos |
GET /v1/agenda/availability | agenda:read | Horários livres de um serviço |
GET /v1/agenda/appointments | agenda:read | Lista agendamentos, com filtros |
GET /v1/agenda/appointments/{id} | agenda:read | Um agendamento |
POST /v1/agenda/appointments | agenda:write | Cria um agendamento |
POST /v1/agenda/appointments/{id}/reschedule | agenda:write | Remarca |
POST /v1/agenda/appointments/{id}/cancel | agenda:write | Cancela |
POST /v1/agenda/appointments/{id}/confirm | agenda:write | Marca como confirmado |
POST /v1/agenda/appointments/{id}/complete | agenda:write | Marca como concluído |
POST /v1/agenda/appointments/{id}/no-show | agenda:write | Marca como não compareceu |
POST /v1/agenda/appointments/{id}/payment | agenda:write | Registra o pagamento |
DELETE /v1/agenda/appointments/{id}/payment | agenda:write | Desfaz o registro de pagamento |
Objeto agendamento
Todo endpoint que devolve um agendamento (detalhe, criar, remarcar, cancelar, confirmar, concluir, falta e pagamento), cada item da lista e os webhooks appointment.* usam exatamente este formato. Campos novos podem ser acrescentados no futuro; nenhum é renomeado ou removido.
json
{
"id": 128,
"status": "scheduled",
"starts_at": "2026-10-06T17:00:00+00:00",
"ends_at": "2026-10-06T18:00:00+00:00",
"timezone": "America/Sao_Paulo",
"date": "2026-10-06",
"start": "14:00",
"end": "15:00",
"source": "api",
"notes": "Primeira vez",
"price_cents": 5000,
"payment": { "status": "pending", "method": null, "paid_at": null },
"confirmed_at": null,
"canceled_at": null,
"canceled_by": null,
"cancel_reason": null,
"reservation_url": "https://konversia.com.br/reserva/Xk3pQ9vL2mZr7TbN4wYc8HsD1fGj6AeU5oRiKtVy",
"service": { "id": 3, "name": "Corte", "duration_minutes": 60 },
"contact": { "id": 331, "name": "Maria Souza", "phone_number": "5511977770000" },
"conversation_id": 918,
"responsible": null,
"created_at": "2026-10-05T10:00:00+00:00",
"updated_at": "2026-10-05T10:00:00+00:00"
}| Campo | Tipo | Descrição |
|---|---|---|
id | integer | Identificador do agendamento |
status | string | scheduled (agendado), confirmed (confirmado), completed (concluído), no_show (não compareceu) ou canceled (cancelado) |
starts_at | string | Início, ISO 8601 em UTC |
ends_at | string | Fim, ISO 8601 em UTC |
timezone | string | Fuso da empresa, por exemplo America/Sao_Paulo |
date | string | Dia do atendimento no fuso da empresa, AAAA-MM-DD |
start | string | Hora de início no fuso da empresa, HH:MM |
end | string | Hora de fim no fuso da empresa, HH:MM |
source | string | Como o agendamento nasceu: manual (equipe, pela tela), workflow, public_link (link público) ou api |
notes | string ou null | Observação interna |
price_cents | integer ou null | Valor em centavos |
payment.status | string | pending ou paid |
payment.method | string ou null | pix, credit_card, debit_card, cash, bank_transfer ou other |
payment.paid_at | string ou null | Quando foi pago, ISO 8601 em UTC |
confirmed_at | string ou null | Quando foi confirmado |
canceled_at | string ou null | Quando foi cancelado |
canceled_by | string ou null | team (a empresa) ou contact (o cliente) |
cancel_reason | string ou null | Motivo informado no cancelamento |
reservation_url | string ou null | Página da reserva. Quem tem este endereço vê, remarca e cancela o agendamento, sem login: trate como segredo. Só vem preenchido para chave com agenda:write; com só agenda:read vem null. Veja Permissões |
service | object | id, name e duration_minutes do serviço |
contact | object | id, name e phone_number do cliente |
conversation_id | integer ou null | Conversa de WhatsApp ligada ao agendamento. null quando o contato ainda não tem conversa |
responsible | object ou null | id e name do responsável pelo atendimento |
created_at, updated_at | string | Criação e última alteração, ISO 8601 em UTC |
Permissões
| Para | A chave precisa de |
|---|---|
| Ler serviços, horários livres e agendamentos | agenda:read |
Receber o reservation_url preenchido | agenda:write |
| Criar, remarcar, cancelar, confirmar, concluir, marcar falta e registrar pagamento | agenda:write |
Avisar o cliente na hora, com notify_contact: true em criar ou remarcar | agenda:write e messages:send |
- O endereço da reserva é poder de escrita. A página da reserva deixa quem a abre remarcar e cancelar o agendamento, sem login. Por isso uma chave só com
agenda:readrecebe o camporeservation_urlcomnull, na lista e no detalhe. O campo continua existindo no objeto. - Guarde o
reservation_urlcomo guarda uma senha. Envie só para o próprio cliente. Não coloque em planilha compartilhada, em evento de calendário que outras pessoas veem, nem em registro de log. notify_contact: trueé envio de mensagem. A linha da empresa manda uma mensagem para o telefone informado, então a chave precisa também demessages:send. Sem ele, a resposta é403 forbidden_scope, comerror.details.required_scopeigual amessages:send, e nada é criado nem remarcado.- Lembretes não dependem da chave. Um agendamento criado pela API recebe os lembretes e a mensagem após o atendimento configurados na Agenda, como qualquer outro agendamento da empresa, mesmo que a chave não tenha
messages:send. Quem decide essas mensagens é a configuração da Agenda, não o integrador.
Datas e fusos
- Entrada (
starts_atem criar e remarcar,paid_atno pagamento): ISO 8601 com fuso obrigatório. São aceitos2026-10-06T14:00:00-03:00,2026-10-06T14:00-03:00,2026-10-06T17:00:00Ze as variantes com milissegundos (2026-10-06T17:00:00.000Z, o formato dotoISOString()do JavaScript). Sem fuso (2026-10-06T14:00:00,2026-10-06 14:00) é recusado comvalidation_failedemstarts_at. - A hora vai de
00a23e os minutos e segundos de00a59.T24:00e:60são recusados comvalidation_failed. - Qualquer fuso serve: o instante é convertido. Segundos são ignorados, porque a agenda trabalha em minutos.
- Saída:
starts_ateends_atvêm sempre em UTC (+00:00).timezone,date,starteendtrazem o horário local da empresa pronto para mostrar, sem conta de fuso do seu lado. - Os parâmetros de dia (
from,to) são dias do calendário da empresa, no formatoAAAA-MM-DD.
Listar serviços
Devolve só os serviços ativos, na ordem definida na tela, sem paginação. public_bookable diz se o serviço aparece no link público de agendamento. min_notice_minutes é a antecedência mínima e max_days_ahead o limite de dias para agendar; os dois já estão aplicados nos horários livres.
bash
curl https://konversia.com.br/api/v1/agenda/services \
-H "Authorization: Bearer $KONVERSIA_API_KEY"json
{
"data": [
{
"id": 3,
"name": "Corte",
"description": "Corte simples",
"duration_minutes": 60,
"price_cents": 5000,
"min_notice_minutes": 60,
"max_days_ahead": 30,
"public_bookable": true
}
]
}Consultar horários livres
Parâmetros, na query string:
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
service_id | integer | sim | Serviço consultado |
from | string | não | Primeiro dia, AAAA-MM-DD. Padrão: hoje |
to | string | não | Último dia, AAAA-MM-DD. Padrão: 14 dias depois de from |
- A janela máxima é de 31 dias:
topode ser até 31 dias depois defrom. Passou disso, outoantes defrom:422 validation_failed, com o motivo emerror.details.to. Para olhar mais longe, faça mais de uma chamada. dayssó traz os dias com pelo menos um horário livre. Dia fechado, feriado ou lotado não aparece.- Cada horário traz
starteendlocais,starts_atem UTC (é o valor a enviar em criar e remarcar) eremaining, quantos agendamentos ainda cabem naquele horário. - Serviço inativo, apagado ou de outra empresa:
404 not_found. - Horário livre não é reserva: outro agendamento pode ocupar o horário entre a consulta e a criação, e aí a criação devolve
409 slot_unavailable.
bash
curl "https://konversia.com.br/api/v1/agenda/availability?service_id=3&from=2026-10-06&to=2026-10-07" \
-H "Authorization: Bearer $KONVERSIA_API_KEY"json
{
"timezone": "America/Sao_Paulo",
"days": [
{
"date": "2026-10-06",
"slots": [
{ "start": "08:00", "end": "09:00", "starts_at": "2026-10-06T11:00:00+00:00", "remaining": 1 },
{ "start": "14:00", "end": "15:00", "starts_at": "2026-10-06T17:00:00+00:00", "remaining": 1 }
]
},
{
"date": "2026-10-07",
"slots": [
{ "start": "10:00", "end": "11:00", "starts_at": "2026-10-07T13:00:00+00:00", "remaining": 2 }
]
}
]
}Listar agendamentos
Todos os filtros são opcionais e podem ser combinados:
| Filtro | Descrição |
|---|---|
from, to | AAAA-MM-DD, pelo dia local do atendimento, os dois inclusivos |
status | Um dos cinco valores de status |
service_id | Serviço |
contact_id | Contato |
phone | Telefone do cliente, só dígitos, com ou sem + |
source | manual, workflow, public_link ou api |
per_page | De 1 a 100. Padrão 25 |
page | Página. Padrão 1 |
- A ordem é do mais cedo para o mais tarde (
starts_at). - A resposta traz
data(a lista de agendamentos) emeta(current_page,per_page,last_page,total). per_pagefora da faixa não é erro: é ajustado para o limite mais próximo. Umapageinválida cai na primeira.- Filtro com valor inválido (status desconhecido, data em outro formato):
422 validation_failed. - Sem
frometo, vem tudo, inclusive o passado e os cancelados. Filtre.
bash
curl "https://konversia.com.br/api/v1/agenda/appointments?from=2026-10-06&to=2026-10-06&status=scheduled&per_page=50" \
-H "Authorization: Bearer $KONVERSIA_API_KEY"json
{
"data": [
{ "id": 128, "status": "scheduled", "starts_at": "2026-10-06T17:00:00+00:00", "...": "os demais campos do objeto agendamento" }
],
"meta": { "current_page": 1, "per_page": 50, "last_page": 1, "total": 1 }
}Cada item traz o objeto agendamento completo; o exemplo está abreviado.
Ver um agendamento
Devolve o objeto agendamento direto, sem envelope data. Um id de outra empresa ou inexistente devolve 404 not_found.
bash
curl https://konversia.com.br/api/v1/agenda/appointments/128 \
-H "Authorization: Bearer $KONVERSIA_API_KEY"Criar um agendamento
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
service_id | integer | sim | Serviço ativo da empresa |
starts_at | string | sim | Início, ISO 8601 com fuso. Use um starts_at devolvido em Consultar horários livres |
contact_id | integer | um dos dois | Contato que já existe na empresa |
to | string | um dos dois | Telefone do cliente, com ou sem + e DDI. O contato e a conversa são criados se ainda não existirem |
contact_name | string | não | Nome do cliente, usado só quando o contato é criado agora |
channel_id | integer | não | Linha de WhatsApp do contato, só com to. Mesma regra de Para onde a mensagem vai |
notes | string | não | Observação interna, até 2000 caracteres |
responsible_user_id | integer | não | Usuário ativo da empresa responsável pelo atendimento |
notify_contact | boolean | não | Envia ao cliente a mensagem "Ao agendar" da Agenda. Com true, a chave precisa também do escopo messages:send. Padrão false |
- O cabeçalho
Idempotency-Keyé obrigatório (ausente:422 validation_failed). A resposta é201com o objeto agendamento, comsourceigual aapi. - Informe o cliente por
contact_idou porto. Os dois juntos:422 validation_failed. Nenhum dos dois:422 contact_required. - Com
to, o canal precisa estar conectado e ter setor padrão. Os erros sãochannel_not_found,channel_disconnected,channel_without_default_department,invalid_phone_numberecontact_blocked, os mesmos do envio de mensagens. Se o contato não existe, ele e a conversa só são criados quando o horário é aceito: um pedido recusado não deixa contato nem conversa para trás. A conversa nova nasce como não iniciada, então não entra na fila de pendentes. Uma conversa que já existe não é alterada: status, setor e atendente ficam como estão. - Com
contact_id, o agendamento usa a conversa de WhatsApp mais recente daquele contato. Se ele não tem nenhuma,conversation_idvemnulle as mensagens automáticas da Agenda não têm por onde sair (aparecem na tela como não enviadas, com o motivo "Contato sem conversa"). Para um cliente que nunca conversou com a empresa, prefirato. - Horário ocupado, fora do expediente, em feriado, antes da antecedência mínima, além do limite de dias ou no passado:
409 slot_unavailable. Consulte os horários livres de novo. 409 agenda_busyquer dizer que a agenda estava ocupada naquele instante e nada foi decidido sobre o horário. Repita a mesma chamada, com a mesmaIdempotency-Key, depois de um ou dois segundos.- Um
responsible_user_idque não é um usuário ativo da empresa:422 validation_failedemresponsible_user_id. - Com
notify_contact: true, sai a mensagem Ao agendar configurada nas mensagens da Agenda, se ela estiver ativa. Isso exige que a chave tenha tambémmessages:send: sem ele,403 forbidden_scopee nenhum agendamento é criado. Lembretes e mensagens após o atendimento seguem as regras da Agenda nos dois casos, com ou semnotify_contact, e não dependem dos escopos da chave. Essas mensagens contam para o limite mensal de envios da empresa. - Workflows com o disparo Evento da agenda, evento Agendamento criado, origem Qualquer ou Pela API, começam para este agendamento, desde que ele tenha uma conversa de WhatsApp e não haja outro workflow em andamento nela.
bash
curl -X POST https://konversia.com.br/api/v1/agenda/appointments \
-H "Authorization: Bearer $KONVERSIA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: pedido-8842" \
-d '{
"service_id": 3,
"starts_at": "2026-10-06T14:00:00-03:00",
"to": "5511977770000",
"contact_name": "Maria Souza",
"notes": "Primeira vez",
"notify_contact": true
}'A resposta 201 é o objeto agendamento do exemplo de Objeto agendamento. Por contato que já existe:
bash
curl -X POST https://konversia.com.br/api/v1/agenda/appointments \
-H "Authorization: Bearer $KONVERSIA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: pedido-8843" \
-d '{ "service_id": 3, "starts_at": "2026-10-07T13:00:00Z", "contact_id": 331 }'Exemplo de recusa:
json
{
"error": {
"code": "slot_unavailable",
"message": "Esse horário não está disponível: ocupado, fora do expediente, antes da antecedência mínima ou além do limite de dias do serviço. Consulte os horários livres.",
"details": {},
"docs_url": "https://docs.konversia.com.br/api/erros/slot_unavailable"
}
}Idempotência
- A regra é a mesma do envio de mensagens (veja Cabeçalho obrigatório: Idempotency-Key). Escolha um valor único por pedido de negócio, como o id da reserva no seu sistema, e não um valor sorteado a cada tentativa.
- Mesma chave e mesmo corpo: devolve a resposta da primeira chamada, com
201de novo, sem criar outro agendamento. Essa resposta é o retrato de quando o agendamento foi criado. Para o estado atual, useGET /v1/agenda/appointments/{id}. - Mesma chave e corpo diferente:
409 idempotency_key_reused. - Duas chamadas simultâneas com a mesma chave: a segunda espera a primeira terminar e devolve a mesma resposta. Só se essa espera estourar o tempo ela recebe
409 request_in_progress; aí basta repetir. - Um pedido recusado (
slot_unavailable,validation_failede os demais erros) não gasta a chave: você pode repetir com a mesma chave depois de corrigir a causa. - A chave vale por 24 horas.
- Os demais endpoints desta página não usam
Idempotency-Key.
Remarcar
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
starts_at | string | sim | Novo início, ISO 8601 com fuso |
notify_contact | boolean | não | Avisa o cliente do novo horário com a mensagem da Agenda. Com true, a chave precisa também do escopo messages:send. Padrão false |
- Só vale para agendamento
scheduledouconfirmed. Concluído, com falta ou cancelado:422 invalid_appointment_state. - O agendamento volta para
scheduled(uma confirmação anterior deixa de valer) e os lembretes são reprogramados para o novo horário. - Remarcar para o mesmo instante que o agendamento já tem devolve
200com o estado atual e não muda nada: a confirmação continua valendo e o cliente não é avisado. - Horário novo indisponível:
409 slot_unavailable, e o agendamento fica como estava. notify_contact: truecom uma chave semmessages:send:403 forbidden_scope, e o agendamento fica como estava.- A resposta é
200com o objeto agendamento.
bash
curl -X POST https://konversia.com.br/api/v1/agenda/appointments/128/reschedule \
-H "Authorization: Bearer $KONVERSIA_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "starts_at": "2026-10-07T10:00:00-03:00", "notify_contact": true }'Cancelar
O corpo é opcional: reason (string, até 255 caracteres) e canceled_by (team, o padrão, ou contact).
- Cancelar libera o horário e interrompe os lembretes pendentes. Não tem como desfazer: para voltar, crie outro agendamento.
- Use
canceled_by: "contact"quando o seu sistema age em nome do cliente (ele cancelou no seu site, por exemplo). A equipe é avisada, como em qualquer cancelamento feito pelo cliente, e os workflows com o evento Cliente cancelou começam. Comteam, ninguém é avisado. - Repetir a chamada num agendamento já cancelado devolve
200com o estado atual, sem erro e sem alterar quem cancelou nem o motivo. É seguro repetir, inclusive com duas chamadas ao mesmo tempo. - Agendamento concluído ou com falta:
422 invalid_appointment_state.
bash
curl -X POST https://konversia.com.br/api/v1/agenda/appointments/128/cancel \
-H "Authorization: Bearer $KONVERSIA_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "reason": "Cliente pediu pelo site", "canceled_by": "contact" }'Trecho da resposta:
json
{
"id": 128,
"status": "canceled",
"canceled_at": "2026-10-05T10:00:00+00:00",
"canceled_by": "contact",
"cancel_reason": "Cliente pediu pelo site"
}Confirmar, concluir e marcar falta
Os três endpoints não têm corpo e respondem 200 com o objeto agendamento.
| Endpoint | Vale para | Resultado |
|---|---|---|
POST /v1/agenda/appointments/{id}/confirm | scheduled | confirmed, com confirmed_at preenchido |
POST /v1/agenda/appointments/{id}/complete | scheduled, confirmed ou no_show | completed |
POST /v1/agenda/appointments/{id}/no-show | scheduled, confirmed ou completed | no_show |
- Fora dessas situações, a resposta é
422 invalid_appointment_state. Confirmar um agendamento já confirmado também cai aqui: leia ostatusantes, ou trate esse erro como "já estava feito". - Confirmar pela API avisa a equipe de que o cliente confirmou, igual a quando o cliente confirma pelo lembrete.
completeeno-showcorrigem um ao outro: um agendamento marcado como falta por engano pode ser concluído, e vice-versa.- A mensagem após o atendimento da Agenda só sai para agendamento concluído.
bash
curl -X POST https://konversia.com.br/api/v1/agenda/appointments/128/confirm \
-H "Authorization: Bearer $KONVERSIA_API_KEY"Pagamento
Corpo do POST .../payment:
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
method | string | sim | pix, credit_card, debit_card, cash, bank_transfer ou other |
paid_at | string | não | Quando foi pago, ISO 8601 com fuso. Padrão: agora |
amount_cents | integer | não | Valor em centavos, maior ou igual a zero. Quando vem, passa a ser o price_cents do agendamento |
- É só um registro para o resumo financeiro da Agenda: nenhuma cobrança é feita.
- O registro não muda o
statusdo agendamento. - Agendamento cancelado:
422 invalid_appointment_state. DELETE .../paymentvoltapaymentparapending(método e datanull) e mantém oprice_cents.- Os dois respondem
200com o objeto agendamento. - Registrar ou desfazer pagamento não gera webhook.
bash
curl -X POST https://konversia.com.br/api/v1/agenda/appointments/128/payment \
-H "Authorization: Bearer $KONVERSIA_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "method": "pix", "paid_at": "2026-10-06T15:05:00-03:00", "amount_cents": 5000 }'json
{
"id": 128,
"status": "completed",
"price_cents": 5000,
"payment": { "status": "paid", "method": "pix", "paid_at": "2026-10-06T18:05:00+00:00" }
}bash
curl -X DELETE https://konversia.com.br/api/v1/agenda/appointments/128/payment \
-H "Authorization: Bearer $KONVERSIA_API_KEY"Erros
Todo erro segue o envelope descrito em Erros. Os códigos que esta página pode devolver:
| Código | Status HTTP | Quando |
|---|---|---|
module_disabled | 403 | O módulo Agenda não está ativo na empresa (error.details.module) |
forbidden_scope | 403 | A chave não tem agenda:read ou agenda:write, ou pediu notify_contact: true sem messages:send (error.details.required_scope diz qual falta) |
not_found | 404 | Agendamento, serviço ou contato inexistente, de outra empresa, ou serviço inativo |
slot_unavailable | 409 | Horário ocupado, fora do expediente, antes da antecedência mínima ou além do limite de dias |
agenda_busy | 409 | A agenda estava ocupada naquele instante. Repita a chamada |
idempotency_key_reused | 409 | Mesma Idempotency-Key com corpo diferente |
request_in_progress | 409 | Outra chamada com a mesma Idempotency-Key ainda está em andamento e a espera por ela estourou o tempo |
invalid_appointment_state | 422 | A situação atual do agendamento não permite a ação |
contact_required | 422 | Faltou informar o cliente: contact_id ou to |
validation_failed | 422 | Campo ausente ou inválido (error.details diz qual), starts_at sem fuso ou com hora impossível, service_id ou contact_id malformado, janela maior que 31 dias, Idempotency-Key ausente |
invalid_phone_number | 422 | to não é um telefone reconhecível |
contact_blocked | 422 | O contato do telefone informado está bloqueado |
channel_not_found | 422 | Não foi possível escolher o canal (error.details.available_channels) |
channel_without_default_department | 422 | O canal não tem setor padrão |
channel_disconnected | 400 | O canal está desconectado |
rate_limited | 429 | Limite de chamadas por minuto atingido |
Passo a passo: consultar horários e agendar
Liste os serviços e guarde o
iddo que o cliente quer (aqui,3).bashcurl https://konversia.com.br/api/v1/agenda/services \ -H "Authorization: Bearer $KONVERSIA_API_KEY"Consulte os horários livres da semana, mostre ao cliente o
datee ostartde cada horário e guarde ostarts_atdo escolhido.bashcurl "https://konversia.com.br/api/v1/agenda/availability?service_id=3&from=2026-10-06&to=2026-10-12" \ -H "Authorization: Bearer $KONVERSIA_API_KEY"Crie o agendamento com o
starts_atguardado e use o id da reserva no seu sistema comoIdempotency-Key. Guarde oiddevolvido. O exemplo avisa o cliente na hora (notify_contact), então a chave precisa deagenda:writeemessages:send.bashcurl -X POST https://konversia.com.br/api/v1/agenda/appointments \ -H "Authorization: Bearer $KONVERSIA_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: pedido-8842" \ -d '{ "service_id": 3, "starts_at": "2026-10-06T17:00:00+00:00", "to": "5511977770000", "contact_name": "Maria Souza", "notify_contact": true }'Se vier
409 slot_unavailable, alguém ocupou o horário entre o passo 2 e o 3: volte ao passo 2 e ofereça outro horário. Se vier409 agenda_busy, repita o passo 3 com a mesma chave.
Para acompanhar o que acontece depois (o cliente confirmou pelo lembrete, cancelou pela página da reserva, a equipe remarcou na tela), cadastre um webhook com os eventos appointment.* em vez de consultar de tempos em tempos.
Relacionado
- Autenticação
- Erros
- Webhooks
- MCP
- Integrações da agenda (guia do produto)
