OctoSolveAjuda

Agendamentos

Liste, consulte, crie e atualize agendamentos pela API pública v1 da OctoSolve.

Agendamentos

O recurso /appointments permite ler, criar e atualizar agendamentos da própria conta. Não existe DELETE na v1. Para cancelar, envie PATCH com status: "cancelado".

Campos

CampoTipoLeituraEscritaRegras
iduuidSimNãoIdentificador do agendamento
contact_iduuidSimApenas na criaçãoObrigatório e precisa identificar um contato da mesma conta
servico_iduuid ou nullSimApenas na criaçãoObrigatório ao criar. Não pode ser trocado pela API
profissional_iduuid ou nullSimCriação e atualizaçãoPrecisa estar ativo, com agenda ativa e atender ao serviço. No PATCH, null explícito é recusado
data_horadatetimeSimCriação e atualizaçãoNa requisição, aceita ISO 8601 com fuso, sem fuso ou em UTC. Sem fuso, a API assume BRT, UTC-3. Na resposta, vem em UTC e termina em Z
duracao_minutosinteiro ou nullSimCriação e atualizaçãoDe 5 a 600. Na criação, o padrão é a duração do serviço. No PATCH, null explícito é recusado
statusenum ou nullSimApenas na atualizaçãoSegue a máquina de estados desta página
valornúmero ou nullSimCriação e atualizaçãoNa criação, o padrão é o preço do serviço
pagobooleano ou nullSimNãoAlterado pelo fluxo de pagamento
forma_pagamentostring ou nullSimNãoForma registrada pelo fluxo de pagamento
motivo_cancelamentostring ou nullSimApenas na atualizaçãoMáximo de 500 caracteres e somente junto de status: "cancelado"
notasstring ou nullSimCriação e atualizaçãoMáximo de 2.000 caracteres
meet_linkstring ou nullSimNãoLink de reunião, quando existir
contact_package_iduuid ou nullSimNãoPacote usado pelo agendamento
recurrence_iduuid ou nullSimNãoQuando preenchido, indica uma ocorrência de série
agendado_porenum ou nullSimNãoagent ou human. A API cria como human
created_atdatetime ou nullSimNãoData de criação
notificar_whatsappbooleanoNãoApenas na criaçãoPadrão false. Com true, envia a confirmação e consome a cota de mensagens

Como toda data de resposta da API, data_hora vem em UTC e termina em Z. Ao exibir para o cliente final, converta o valor para o fuso local. Sem essa conversão, no horário de Brasília a hora aparece 3 horas adiantada.

Nos exemplos de requisição desta página, o valor com -03:00 é mantido para mostrar uma entrada no horário de Brasília.

Agendamento de serviço online criado pela API nasce sem link de reunião. O campo meet_link vem null. Hoje somente o agente gera o link, portanto sua integração não deve prometer um link de Google Meet ao criar pela API.

Endpoints

MétodoCaminhoEscopoResultado
GET/appointmentsread ou writeLista paginada em ordem cronológica
GET/appointments/{id}read ou writeUm agendamento
POST/appointmentswriteCria e responde 201
PATCH/appointments/{id}writeAtualiza os campos enviados

Listar agendamentos

Filtros disponíveis:

FiltroRegra
contact_idAgendamentos de um contato
profissional_idAgendamentos de um profissional
servico_idAgendamentos de um serviço
statusRepetível, como status=agendado&status=confirmado
deData ou datetime ISO 8601, inclusive
ateData ou datetime ISO 8601, exclusivo
limitDe 1 a 100, padrão 50
cursorValor opaco retornado pela página anterior

Sem de e ate, a consulta começa 30 dias antes do momento atual e segue para o futuro. Isso evita percorrer anos de histórico por engano. A ordem é data_hora crescente, com id como desempate. O cursor depende dos filtros e responde 400 invalid_cursor se for reutilizado com outra consulta. A janela resolvida na primeira página fica congelada no cursor durante toda a paginação, então é seguro continuar somente com o cursor, mesmo sem informar de. O parâmetro de continua opcional. Se de for posterior a ate, a resposta é 422 validation_error.

curl --request GET \
  --url "https://api.octosolve.com.br/api/v1/appointments?status=agendado&status=confirmado&de=2026-08-20&ate=2026-08-27&limit=50" \
  --header "Authorization: Bearer osk_live_exemplo_ficticio_00000000000000000000000000" \
  --header "Accept: application/json"

Consultar um agendamento

curl --request GET \
  --url "https://api.octosolve.com.br/api/v1/appointments/11111111-1111-4111-8111-111111111111" \
  --header "Authorization: Bearer osk_live_exemplo_ficticio_00000000000000000000000000" \
  --header "Accept: application/json"

Um UUID inexistente ou pertencente a outra conta responde o mesmo 404 not_found.

Criar um agendamento

contact_id, servico_id e data_hora são obrigatórios. profissional_id, duracao_minutos, valor, notas e notificar_whatsapp são opcionais.

curl --request POST \
  --url "https://api.octosolve.com.br/api/v1/appointments" \
  --header "Authorization: Bearer osk_live_exemplo_ficticio_00000000000000000000000000" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: agenda_site_pedido_8472" \
  --data '{
    "contact_id": "22222222-2222-4222-8222-222222222222",
    "servico_id": "33333333-3333-4333-8333-333333333333",
    "profissional_id": "44444444-4444-4444-8444-444444444444",
    "data_hora": "2026-08-20T09:00:00-03:00",
    "duracao_minutos": 30,
    "valor": 150.00,
    "notas": "Primeira consulta.",
    "notificar_whatsapp": false
  }'

Data no passado é aceita. Isso permite importar histórico de outro sistema. A proteção contra horários sobrepostos continua valendo.

A criação recusa com 422 validation_error:

  • Serviço inativo.
  • Serviço que exige pagamento antecipado. Esse fluxo precisa continuar no agente ou no painel.
  • Contato, serviço ou profissional de outra conta ou inexistente.
  • Profissional inativo, sem agenda ativa ou que não atende ao serviço.

GET /availability ajuda a escolher um horário, mas não reserva nada. A confirmação acontece somente no POST /appointments. Se outra pessoa ocupar o intervalo antes da criação, a resposta será 409 slot_conflict.

Use Idempotency-Key para repetir com segurança o mesmo pedido após timeout. Uma tentativa que falha libera a chave. Se o horário estiver ocupado, escolha outro horário e repita o pedido com a mesma chave ou com outra chave estável para a nova operação.

Se o Google Calendar falhar durante a criação, o agendamento ainda é criado na agenda da OctoSolve. A API não expõe o estado de sincronização nesta versão.

Atualizar um agendamento

curl --request PATCH \
  --url "https://api.octosolve.com.br/api/v1/appointments/11111111-1111-4111-8111-111111111111" \
  --header "Authorization: Bearer osk_live_exemplo_ficticio_00000000000000000000000000" \
  --header "Content-Type: application/json" \
  --data '{
    "data_hora": "2026-08-20T10:30:00-03:00",
    "status": "confirmado"
  }'

No PATCH, campo ausente não muda. null explícito limpa valor, motivo_cancelamento ou notas, mas profissional_id: null e duracao_minutos: null respondem 422 validation_error.

Ocorrência com recurrence_id preenchido pode ser consultada, mas não atualizada pela API. O PATCH responde 409 conflict e a série deve ser editada pelo painel.

Trocar servico_id também não faz parte do PATCH. Trocar o serviço altera preço, duração, agente e título no Google, portanto o caminho seguro é cancelar e criar outro agendamento.

Remarcar por data_hora só é permitido quando o estado final da chamada é agendado ou confirmado. Ao enviar status e data_hora juntos, a API valida primeiro a transição de status e depois a remarcação. Atualizações concorrentes seguem a última gravação, sem bloqueio otimista e sem updated_at. Use webhooks para acompanhar mudanças.

Máquina de estados

A API é mais rígida que a tela, de propósito. A tela é operada por pessoas e continua permitindo correções manuais. A API bloqueia regressões que poderiam fazer a agenda mentir.

Estado atualPróximos estados permitidos pela API
agendadoconfirmado, realizado, no_show, cancelado
confirmadorealizado, no_show, cancelado
realizadoNenhum, estado final
no_showNenhum, estado final
canceladoNenhum, estado final
aguardando_pagamentoNenhum pela API, o fluxo de cobrança controla a transição
cancelado_por_nao_pagamentoNenhum, estado final
cancelado_estornadoNenhum, estado final
cancelado_lgpdNenhum, estado final

Enviar o mesmo status atual é uma operação sem mudança e responde 200. Transição fora da tabela responde 409 invalid_transition, com status_atual em error.details[0].

{
  "error": {
    "code": "invalid_transition",
    "message": "Transição de status não permitida pela API.",
    "details": [
      {
        "field": "status",
        "status_atual": "realizado"
      }
    ]
  }
}

Erros próprios

SituaçãoHTTPCódigoAção recomendada
Horário ocupado409slot_conflictConsulte a disponibilidade novamente e peça outro horário
Transição de status não permitida409invalid_transitionLeia details[0].status_atual e aplique a máquina de estados

Receita para Make ou n8n

  1. Liste serviços ativos em GET /services e escolha um que não exija pagamento antecipado.
  2. Liste profissionais com GET /professionals?servico_id=ID_DO_SERVICO.
  3. Consulte GET /availability com serviço, data e, se necessário, profissional.
  4. Guarde o inicio do slot exatamente como veio, inclusive o Z.
  5. Envie POST /appointments com chave write, contact_id, servico_id, profissional_id e o slot em data_hora.
  6. Use uma Idempotency-Key estável para a mesma tentativa de origem.
  7. Se receber slot_conflict, consulte a disponibilidade outra vez e apresente outro horário. Não repita o mesmo horário em loop.
  8. Para remarcar ou mudar status, envie apenas os campos necessários em PATCH /appointments/{id}.
  9. Em invalid_transition, use details[0].status_atual para decidir o próximo passo ou encaminhar para revisão humana.

On this page