Skip to content

Portal do Cliente ​

O portal é onde o cliente se serve sozinho: cria acesso, navega pelo catálogo, escolhe um horário livre e agenda — sem ligar para a unidade. Ele também consulta e cancela os próprios agendamentos, dentro do prazo definido pela unidade.

Todo o fluxo exige cliente autenticado. O cliente que a recepcionista cadastrou por telefone não fica de fora: o registro assume o cadastro existente em vez de criar um duplicado.

Headers obrigatórios

Todas as requisições devem incluir o header X-Booking-Id (UUID) com o identificador da instância. Endpoints privados exigem também Authorization: Bearer {token} com o token do cliente (guard bookingCustomer). Os únicos endpoints públicos são o registro e o login. Cliente bloqueado recebe 403 em qualquer rota privada.


Conta ​

Criar Conta ​

Registra o cliente no portal. O comportamento depende do que já existe para o e-mail na instância:

SituaçãoResultado
E-mail inexistenteCria o cadastro com senha (exige name).
Cadastro existe sem senha (criado pelo staff)Assume o cadastro: define a senha e completa os dados enviados.
Cadastro existe com senha422 orientando o login.

Por que "assumir" em vez de duplicar?

A recepcionista cadastra clientes por telefone o dia inteiro — sem senha. Quando esse cliente resolve usar o portal, o histórico dele (agendamentos, contadores, notas) já existe. O registro reconhece o e-mail e entrega o acesso sobre o mesmo cadastro: nada de cliente duplicado, nada de histórico órfão.

http
POST /v1/booking/customer/customers/register

Payload (Body) ​

AtributoTipoObrigatórioDescrição
emailstringSimE-mail do cliente (válido, máx. 250 caracteres).
passwordstringSimSenha de acesso (8 a 32 caracteres).
namestringCondicionalNome completo (máx. 150 caracteres) — obrigatório apenas para cadastro novo.
phonestringNãoTelefone (máx. 50 caracteres).
documentstringNãoDocumento (máx. 30 caracteres).
birthDatestringNãoData de nascimento (YYYY-MM-DD).
isMarketingOptInbooleanNãoAceite de marketing.

Exemplo de Requisição ​

bash
curl -X POST "https://api.us.basis.tavares.in/v1/booking/customer/customers/register" \
  -H "X-Booking-Id: 3fa85f64-5717-4562-b3fc-2c963f66afa6" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Maria Silva",
    "email": "maria.silva@email.com",
    "password": "password123"
  }'

Respostas ​

201 Created

Retorna o ID do cadastro (novo ou assumido). Em seguida, faça login para obter o token.

json
{
  "id": 1
}

422 Unprocessable Entity

Ocorre quando o e-mail já possui acesso ("Este e-mail já possui acesso. Faça login.") ou falta o nome para um cadastro novo.

json
{
  "errors": [{ "message": "Este e-mail já possui acesso. Faça login." }]
}

Login ​

Autentica o cliente e retorna o token de acesso (30 dias).

http
POST /v1/booking/customer/customers/login

Payload (Body) ​

AtributoTipoObrigatórioDescrição
emailstringSimE-mail do cliente.
passwordstringSimSenha do cliente.

Respostas ​

200 OK

Retorna o token Bearer da sessão.

json
{
  "type": "bearer",
  "token": "oat_MQ.aXJjMFNEbFc1V3AxTzVydFctQi0xQXU5NXVKNkhuYzZaaDA5bks2bTYzNjg1MDMwNA",
  "abilities": ["*"],
  "lastUsedAt": null,
  "expiresAt": "2026-10-13T01:16:25.436Z"
}

422 Unprocessable Entity

Credenciais erradas, cadastro inexistente, cadastro sem senha ("crie seu acesso no registro") ou cliente bloqueado.

json
{
  "errors": [{ "message": "Este cadastro ainda não possui acesso. Crie seu acesso no registro." }]
}

Perfil, Atualização, Senha e Logout ​

Espelham os endpoints do staff, no contexto do cliente:

EndpointDescrição
GET /v1/booking/customer/customers/meDados do próprio cadastro (incluindo contadores e aceite de marketing).
PUT /v1/booking/customer/customers/meAtualiza nome, telefone, documento, nascimento e isMarketingOptIn.
PATCH /v1/booking/customer/customers/change-passwordTroca a senha (8 a 32 caracteres).
POST /v1/booking/customer/customers/logoutInvalida o token atual.

Sucesso em 204 No Content para as escritas; 200 OK com o cadastro no me.


O menu público da unidade — apenas o que está ativo e agendável online.

Categorias com Serviços ​

Retorna as categorias ativas com os serviços agendáveis aninhados, prontos para montar a tela de agendamento em uma única chamada. Serviços sem categoria vêm em uncategorizedServices.

http
GET /v1/booking/customer/catalog/categories

Exemplo de Requisição ​

bash
curl -X GET "https://api.us.basis.tavares.in/v1/booking/customer/catalog/categories" \
  -H "X-Booking-Id: 3fa85f64-5717-4562-b3fc-2c963f66afa6" \
  -H "Authorization: Bearer {token}" \
  -H "Accept: application/json"

Respostas ​

200 OK

Retorna as categorias com seus serviços e os serviços sem categoria.

json
{
  "categories": [
    {
      "id": 1,
      "name": "Cabelo",
      "slug": "cabelo",
      "sortOrder": 0,
      "services": [
        {
          "id": 1,
          "bookingServiceCategoryId": 1,
          "name": "Corte Masculino",
          "slug": "corte-masculino",
          "price": "80.00",
          "durationMinutes": 45,
          "isBookableOnline": true,
          "isActive": true,
          "bookingServiceCategory": { "id": 1, "name": "Cabelo" }
        }
      ]
    }
  ],
  "uncategorizedServices": []
}

Detalhe do Serviço ​

http
GET /v1/booking/customer/catalog/services/:id

Retorna o serviço completo (descrição, duração, preço). Responde 404 quando o serviço não existe, está inativo ou não é agendável online — o portal não vaza serviços internos.

Profissionais do Serviço ​

Retorna os profissionais ativos e agendáveis online que executam o serviço — para a etapa "com quem?" do fluxo.

http
GET /v1/booking/customer/catalog/professionals

Parâmetros de Query ​

NomeTipoObrigatórioDescrição
bookingServiceIdnumberSimServiço (deve existir na instância).

Respostas ​

200 OK

Retorna o array de profissionais.

json
[
  {
    "id": 1,
    "name": "Ana Souza",
    "slug": "ana-souza",
    "avatarUrl": null,
    "colorCode": "#EC4899"
  }
]

Horários Disponíveis (Slots) ​

Os slots são os horários livres calculados em tempo real: a escala do profissional no dia da semana, menos as exceções da data, menos o que já está ocupado (incluindo buffers), na grade de slotIntervalMinutes onde cabe a duração do serviço. Também respeitam a antecedência mínima (minAdvanceMinutes) e máxima (maxAdvanceDays) da instância.

http
GET /v1/booking/customer/slots

Parâmetros de Query ​

NomeTipoObrigatórioDescrição
bookingServiceIdnumberSimServiço (deve existir, estar ativo e ser agendável online — senão 404).
datestringSimO dia desejado (YYYY-MM-DD).
bookingProfessionalIdnumberNãoRestringe a um profissional; omitindo, agrega todos os que executam o serviço.

Campos da Resposta ​

CampoTipoDescrição
startAtStringInício do slot, ISO 8601 com o fuso da instância.
endAtStringFim do slot (início + duração do serviço).
bookingProfessionalIdNumberO profissional dono do slot.
professionalNameStringNome do profissional — pronto para exibição no seletor de horários.

Exemplo de Requisição ​

bash
curl -X GET "https://api.us.basis.tavares.in/v1/booking/customer/slots?bookingServiceId=1&date=2026-09-20&bookingProfessionalId=1" \
  -H "X-Booking-Id: 3fa85f64-5717-4562-b3fc-2c963f66afa6" \
  -H "Authorization: Bearer {token}" \
  -H "Accept: application/json"

Respostas ​

200 OK

Retorna o array de slots livres. Um dia bloqueado (exceção, feriado) retorna um array vazio.

json
[
  {
    "startAt": "2026-09-20T09:00:00.000-03:00",
    "endAt": "2026-09-20T09:45:00.000-03:00",
    "bookingProfessionalId": 1,
    "professionalName": "João Silva"
  },
  {
    "startAt": "2026-09-20T09:15:00.000-03:00",
    "endAt": "2026-09-20T10:00:00.000-03:00",
    "bookingProfessionalId": 1,
    "professionalName": "João Silva"
  }
]

Agendamentos do Cliente ​

Meus Agendamentos ​

Lista apenas os agendamentos do cliente autenticado, com filtros de período e status.

http
GET /v1/booking/customer/appointments

Parâmetros de Query ​

NomeTipoObrigatórioDescrição
page / perPagenumberNãoPaginação (máx. 100 por página).
fromstringNãoInício do período (YYYY-MM-DD).
tostringNãoFim do período (YYYY-MM-DD).
statusenumNãopending, confirmed, canceled, completed ou no_show.

Criar Agendamento ​

Agenda um ou mais serviços em uma única chamada — a identidade é sempre a do cliente autenticado (não há bookingCustomerId no payload). Somente serviços ativos e agendáveis online são aceitos; o horário é validado contra conflitos como no fluxo do staff.

http
POST /v1/booking/customer/appointments

Payload (Body) ​

AtributoTipoObrigatórioDescrição
itemsarraySimPelo menos um item (ver abaixo).
items[].bookingServiceIdnumberSimServiço (deve existir e ser agendável online).
items[].bookingProfessionalIdnumberSimProfissional (deve executar o serviço).
items[].startAtstringSimInício, ISO 8601 com fuso (2026-09-20T14:00:00.000-03:00).
notesstringNãoObservações para a unidade.

Exemplo de Requisição ​

bash
curl -X POST "https://api.us.basis.tavares.in/v1/booking/customer/appointments" \
  -H "X-Booking-Id: 3fa85f64-5717-4562-b3fc-2c963f66afa6" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      {
        "bookingServiceId": 1,
        "bookingProfessionalId": 1,
        "startAt": "2026-09-20T14:00:00.000-03:00"
      }
    ]
  }'

Respostas ​

201 Created

Retorna o ID e o código legível do agendamento.

json
{
  "id": 3,
  "code": "M4T8QW"
}

422 Unprocessable Entity

Horário em conflito (SLOT_UNAVAILABLE), serviço indisponível online ou cliente bloqueado (CUSTOMER_BLOCKED).

Detalhe do Agendamento ​

http
GET /v1/booking/customer/appointments/:id

Retorna o agendamento completo (itens, eventos). Responde 404 quando o agendamento não existe ou pertence a outro cliente — o portal não vaza a existência de agendamentos alheios.

Cancelar Agendamento ​

Cancela o próprio agendamento, respeitando o prazo cancellationDeadlineMinutes da instância.

http
PATCH /v1/booking/customer/appointments/:id/cancel

Payload (Body) ​

AtributoTipoObrigatórioDescrição
reasonstringNãoMotivo do cancelamento (máx. 255 caracteres).

Exemplo de Requisição ​

bash
curl -X PATCH "https://api.us.basis.tavares.in/v1/booking/customer/appointments/3/cancel" \
  -H "X-Booking-Id: 3fa85f64-5717-4562-b3fc-2c963f66afa6" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{ "reason": "Imprevisto, não poderei comparecer" }'

Respostas ​

204 No Content

Cancelamento concluído — a agenda e os recursos são liberados e a unidade é notificada.

422 Unprocessable Entity

Ocorre quando o prazo de cancelamento já encerrou (code: CANCELLATION_DEADLINE_EXCEEDED) — a partir daí, só o staff cancela.

json
{
  "message": "O prazo para cancelamento deste agendamento já encerrou",
  "code": "CANCELLATION_DEADLINE_EXCEEDED"
}