API Reference
Integre o Viagilize com seus sistemas através da nossa API RESTful.
https://{tenant}.viagilize.com.br/api/v1
Autenticação
A API utiliza autenticação via Bearer Token. Você pode gerar tokens de acesso no painel administrativo em
Configurações → API.
Importante
Mantenha seu token seguro. Nunca compartilhe ou exponha em código público. Cada token tem permissões específicas (scopes) definidas no momento da criação.
Exemplo de requisição
curl -X GET 'https://{tenant}.viagilize.com.br/api/v1/excursoes' \
-H 'Authorization: Bearer seu_token_aqui' \
-H 'Accept: application/json'
Escopos (Scopes)
Cada token pode ter permissões específicas. Ao criar um token, selecione apenas os escopos necessários.
excursoes:read
Visualizar excursões
excursoes:write
Criar e editar excursões
excursoes:delete
Excluir excursões
passageiros:read
Visualizar passageiros
passageiros:write
Gerenciar passageiros
clientes:read
Visualizar clientes
clientes:write
Criar e editar clientes
clientes:delete
Excluir clientes
financeiro:read
Visualizar dados financeiros
financeiro:write
Registrar pagamentos
checkin:write
Realizar check-in
guias:read
Visualizar guias
guias:write
Gerenciar guias
veiculos:read
Visualizar veículos
veiculos:write
Gerenciar veículos
transportes:read
Visualizar transportes
transportes:write
Gerenciar transportes
webhooks:manage
Configurar webhooks (CRUD via API)
Excursões
Gerenciamento de excursões e pacotes de viagem
Retorna uma lista paginada de excursões/pacotes com filtros.
excursoes:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
page
|
integer | query | Número da página |
per_page
|
integer | query | Itens por página (max: 100) |
status
|
string | query | rascunho, publicada, cancelada, finalizada |
tipo_excursao
|
string | query | excursao ou pacote_viagem |
categoria_id
|
integer | query | Filtrar por categoria |
search
|
string | query | Busca por nome, cidade ou destino |
data_inicio_de
|
date | query | Data de início mínima (Y-m-d) |
data_inicio_ate
|
date | query | Data de início máxima (Y-m-d) |
Resposta de exemplo
{
"success": true,
"data": [
{
"id": 45,
"nome": "Gramado - Natal Luz 2025",
"slug": "gramado-natal-luz-2025",
"tipo_excursao": "excursao",
"cidade": "Gramado",
"estado": "RS",
"pais": "Brasil",
"local": "Gramado\/RS",
"data_inicio": "2025-12-20",
"data_fim": "2025-12-24",
"hora_inicio": "06:00",
"hora_fim": "22:00",
"status": "publicada",
"vagas_maximas": 46,
"imagem": "https:\/\/...\/gramado.jpg",
"categorias": [
{
"id": 1,
"nome": "Adulto"
}
],
"embarques": [
{
"id": 12,
"nome": "Terminal Tietê",
"cidade": "São Paulo",
"hora_embarque": "06:00"
}
]
}
],
"meta": {
"current_page": 1,
"per_page": 20,
"total": 45,
"last_page": 3
}
}
Retorna a excursão/pacote com categorias, embarques, preços, guias, transportes, paradas. Use include=... para carregar relações adicionais (voos, cruzeiro, componentes, itinerario, cotacoes, allotments, vouchers).
excursoes:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da excursão |
include
|
string | query | CSV: voos,cruzeiro,componentes,itinerario,cotacoes,allotments,vouchers |
Resposta de exemplo
{
"success": true,
"data": {
"id": 45,
"nome": "Gramado - Natal Luz 2025",
"slug": "gramado-natal-luz-2025",
"tipo_excursao": "excursao",
"descricao": "Viagem completa com hospedagem...",
"pais": "Brasil",
"estado": "RS",
"cidade": "Gramado",
"data_inicio": "2025-12-20",
"data_fim": "2025-12-24",
"hora_inicio": "06:00",
"hora_fim": "22:00",
"status": "publicada",
"vagas_maximas": 46,
"permitir_escolha_assento": true,
"escolha_assento_dias_antes": 30,
"parcelas_max": 10,
"acrescimo_tipo": "percentual",
"acrescimo_parcela": 2.99,
"duracao_noites": 4,
"destino_cidade": "Gramado",
"destino_estado": "RS",
"destino_pais": "Brasil",
"regime_hospedagem": "meia_pensao",
"categoria_hotel": "4_estrelas",
"nome_hotel": "Hotel Laghetto",
"incluso": [
"Hospedagem",
"Café da manhã",
"Transfer",
"Passeios"
],
"nao_incluso": [
"Passeios opcionais",
"Refeições extras"
],
"documentos_necessarios": "RG ou CNH original",
"categorias": [
{
"id": 1,
"nome": "Adulto"
},
{
"id": 2,
"nome": "Criança (6-11)"
}
],
"embarques": [
{
"id": 12,
"nome": "Terminal Tietê",
"endereco": "Av. Cruzeiro do Sul, 1800",
"cidade": "São Paulo",
"estado": "SP",
"hora_embarque": "06:00",
"vagas_max": 46
}
],
"precos": [
{
"id": 77,
"categoria_id": 1,
"embarque_id": 12,
"valor": 1450,
"ativo": true
}
],
"transportes": [
{
"id": 9,
"veiculo_id": 5,
"nome": "Ônibus 1",
"tipo": "onibus_leito",
"vagas_total": 46,
"veiculo": {
"id": 5,
"modelo": "Paradiso 1600",
"placa": "ABC-1234",
"capacidade_total": 46
}
}
],
"paradas": [
{
"id": 3,
"nome": "Café da manhã",
"latitude": -26.9,
"longitude": -49.07
}
],
"created_at": "2024-10-05T14:32:00Z",
"updated_at": "2024-11-20T09:14:22Z"
}
}
Retorna estatísticas agregadas: vagas, valores, confirmações.
excursoes:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da excursão |
Resposta de exemplo
{
"success": true,
"data": {
"total_passageiros": 45,
"passageiros_confirmados": 38,
"vagas_total": 46,
"vagas_ocupadas": 38,
"vagas_disponiveis": 8,
"preco_minimo": 1450,
"preco_maximo": 1650
}
}
Cria uma excursão (rodoviária) ou pacote de viagem. Pode receber arrays aninhados (transportes, embarques, precos) para criar tudo em uma única chamada, similar ao wizard do admin.
excursoes:write
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
nome
*
|
string | Nome da excursão/pacote |
slug
|
string | Slug (gerado automaticamente se omitido) |
tipo_excursao
|
string | excursao (default) ou pacote_viagem |
descricao
|
string | Descrição longa |
imagem
|
string | URL da imagem principal |
galeria
|
array | Array de URLs de imagens |
pais
|
string | País |
estado
|
string | Estado/UF |
cidade
|
string | Cidade |
local
|
string | Local/destino |
data_inicio
*
|
date | Data de início (Y-m-d) |
data_fim
|
date | Data de fim (Y-m-d) |
hora_inicio
|
string | Hora de início (H:i) |
hora_fim
|
string | Hora de fim (H:i) |
vagas_maximas
|
integer | Limite total de vagas |
permitir_escolha_assento
|
boolean | Cliente escolhe assento |
escolha_assento_dias_antes
|
integer | Dias antes do embarque para liberar escolha |
permitir_troca_transporte
|
boolean | Permite trocar de transporte |
status
|
string | rascunho (default), publicada, cancelada, finalizada |
categoria_ids
|
array | Array de IDs de categorias de passageiro |
parcelas_max
|
integer | Máximo de parcelas no checkout |
acrescimo_tipo
|
string | percentual ou fixo |
acrescimo_parcela
|
number | Taxa de parcelamento |
observacoes
|
string | Observações gerais |
duracao_noites
|
integer | Pacote: duração em noites |
destino_cidade
|
string | Pacote: cidade destino |
destino_estado
|
string | Pacote: estado destino |
destino_pais
|
string | Pacote: país destino |
regime_hospedagem
|
string | Pacote: cafe_da_manha, meia_pensao, all_inclusive... |
categoria_hotel
|
string | Pacote: 3_estrelas, 4_estrelas, 5_estrelas |
nome_hotel
|
string | Pacote: nome do hotel |
incluso
|
array | Pacote: itens inclusos (array de strings) |
nao_incluso
|
array | Pacote: itens não inclusos |
documentos_necessarios
|
string | Pacote: documentos para embarque |
observacoes_pacote
|
string | Pacote: observações específicas |
mostrar_site
|
boolean | Publicar na vitrine pública |
mostrar_vagas_disponiveis
|
boolean | Mostrar "X vagas restantes" no público |
vagas_alerta_poucas
|
integer | Alerta amarelo "últimas N" (gatilho urgência) |
vagas_alerta_ultimas
|
integer | Alerta vermelho "últimas N" (urgência crítica) |
vagas_reservadas
|
integer | Vagas pré-reservadas (debitam de vagas_maximas) |
desativar_vendas_dias_antes
|
integer | Dias antes da viagem para fechar vendas |
prazo_pagamento_minutos
|
integer | Minutos para expirar reserva sem pagamento |
observacoes_internas
|
string | Observações privadas (não vão pro cliente) |
exigir_contrato
|
boolean | Forçar aceite de contrato no checkout |
exigir_documentos
|
boolean | Exigir upload de documentos antes do embarque |
incluir_observacoes_no_cartao
|
boolean | Incluir observações no cartão de embarque |
duracao_dias
|
integer | Duração em dias (display) |
recorrencia_config
|
object | Config de série semanal/mensal |
recorrencia_ativa
|
boolean | Toggle de geração automática da série |
endereco
|
string | Endereço completo |
latitude
|
number | Latitude (-90..90) |
longitude
|
number | Longitude (-180..180) |
video
|
string | URL de vídeo (YouTube/Vimeo) |
contrato_template_id
|
integer | ID do template de contrato a usar |
whatsapp
|
string | Número WhatsApp para esta excursão (ex: 5511999999999) |
mostrar_whatsapp
|
boolean | Exibir botão WhatsApp na página pública |
modo_venda
|
string | Modo de venda (ex: aberta, b2b, fechada) |
modo_preco
|
string | fixo (mostra preço), sob_consulta (esconde), hibrido |
preco_display_modo
|
string | Como exibir o preço público (a_partir_de, fixo, ate) |
preco_display_intervalo
|
boolean | Exibir intervalo mín-máx no público |
escolha_assento_a_partir_de
|
date | Data a partir da qual cliente pode escolher assento |
guias_contam_vaga
|
boolean | Guias ocupam vaga no transporte |
publicar_em
|
date | Publicar automaticamente nesta data |
despublicar_em
|
date | Despublicar automaticamente nesta data |
seguro_link
|
string | URL do seguro viagem (afiliado) |
seguro_label
|
string | Texto do botão de seguro |
external_ref
|
string | ID/código do seu sistema origem (ex: iBus-123) |
external_source
|
string | Nome do sistema origem (ex: ibus, sagtur) |
categorias
|
array | Lista de categorias a criar: [{nome*, descricao, idade_min, idade_max, ordem, ref}] — use `ref` como rótulo para referenciar em precos |
transportes
|
array | Lista de transportes a criar: [{veiculo_id*, nome, numero, tipo, vagas_total}] |
embarques
|
array | Lista de embarques: [{nome*, endereco, cidade, estado, hora_embarque, vagas_max, ref}] — use `ref` para referenciar em precos |
precos
|
array | Lista de preços: [{categoria_id|categoria_ref*, embarque_id|embarque_ref, valor*}] — pode usar ref das categorias/embarques criados na mesma chamada |
conteudo
|
object | Conteúdo da vitrine pública (page builder). Aceita: titulo, subtitulo, resumo, descricao_completa, atracoes[], o_que_esperar (string) ou o_que_esperar_items[], regras/regras_items[], o_que_levar/o_que_levar_items[], inclusos/inclusos_items[], nao_inclusos/nao_inclusos_items[], videos[], links[{titulo,url}], capa_url, banner_display_mode (hero|vitrine|split|minimal), meta_title, meta_description, status (rascunho|publicado). Detalhes em /excursoes/{id}/conteudo |
Resposta de exemplo
{
"success": true,
"message": "Excursão criada com sucesso.",
"data": {
"id": 123,
"nome": "Nova Excursão",
"slug": "nova-excursao-xyz123",
"tipo_excursao": "excursao",
"status": "rascunho",
"data_inicio": "2026-05-10",
"vagas_maximas": 46,
"categorias": [
{
"id": 1,
"nome": "Adulto"
}
],
"transportes": [
{
"id": 101,
"veiculo_id": 5,
"vagas_total": 46
}
],
"embarques": [
{
"id": 210,
"nome": "Terminal Tietê",
"hora_embarque": "06:00"
}
],
"precos": [
{
"id": 305,
"categoria_id": 1,
"valor": 1450
}
]
}
}
Atualiza parcialmente uma excursão. **Aceita todos os campos do POST** (todos opcionais). Envie só os que deseja alterar. Também aceita `conteudo` inline pra atualizar a vitrine pública na mesma chamada.
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da excursão |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
nome
|
string | Nome |
slug
|
string | Slug |
tipo_excursao
|
string | excursao ou pacote_viagem |
descricao
|
string | Descrição |
imagem
|
string | URL da imagem principal |
galeria
|
array | Array de URLs |
pais
|
string | País |
estado
|
string | Estado |
cidade
|
string | Cidade |
local
|
string | Local |
endereco
|
string | Endereço |
latitude
|
number | Latitude |
longitude
|
number | Longitude |
data_inicio
|
date | Data início |
data_fim
|
date | Data fim |
hora_inicio
|
string | Hora início |
hora_fim
|
string | Hora fim |
status
|
string | rascunho, publicada, cancelada, finalizada |
publicar_em
|
date | Publicar nesta data |
despublicar_em
|
date | Despublicar nesta data |
vagas_maximas
|
integer | Vagas máximas |
vagas_reservadas
|
integer | Vagas pré-reservadas |
mostrar_site
|
boolean | Publicar na vitrine |
mostrar_vagas_disponiveis
|
boolean | Mostrar contador de vagas |
vagas_alerta_poucas
|
integer | Alerta urgência (amarelo) |
vagas_alerta_ultimas
|
integer | Alerta urgência (vermelho) |
observacoes
|
string | Observações públicas |
observacoes_internas
|
string | Observações internas |
incluir_observacoes_no_cartao
|
boolean | Imprimir no cartão |
exigir_contrato
|
boolean | Forçar aceite contrato |
exigir_documentos
|
boolean | Forçar upload docs |
contrato_template_id
|
integer | Template do contrato |
desativar_vendas_dias_antes
|
integer | Dias para fechar vendas |
prazo_pagamento_minutos
|
integer | Minutos pra expirar reserva |
duracao_dias
|
integer | Duração em dias |
recorrencia_config
|
object | Config série |
recorrencia_ativa
|
boolean | Toggle série |
permitir_escolha_assento
|
boolean | Cliente escolhe |
escolha_assento_dias_antes
|
integer | Dias antes pra liberar |
escolha_assento_a_partir_de
|
date | Data específica |
permitir_troca_transporte
|
boolean | Troca de transporte |
guias_contam_vaga
|
boolean | Guia ocupa vaga |
parcelas_max
|
integer | Parcelas máx |
acrescimo_tipo
|
string | percentual ou fixo |
acrescimo_parcela
|
number | Taxa parcelamento |
modo_preco
|
string | fixo, sob_consulta, hibrido |
preco_display_modo
|
string | Display preço |
preco_display_intervalo
|
boolean | Intervalo público |
video
|
string | URL vídeo |
whatsapp
|
string | WhatsApp da viagem |
mostrar_whatsapp
|
boolean | Botão WhatsApp |
duracao_noites
|
integer | Pacote: noites |
destino_cidade
|
string | Pacote: cidade destino |
destino_estado
|
string | Pacote: estado |
destino_pais
|
string | Pacote: país |
regime_hospedagem
|
string | Pacote: regime |
categoria_hotel
|
string | Pacote: estrelas |
nome_hotel
|
string | Pacote: hotel |
incluso
|
array | Pacote: inclusos |
nao_incluso
|
array | Pacote: não inclusos |
documentos_necessarios
|
string | Pacote: documentos |
observacoes_pacote
|
string | Pacote: observações |
seguro_link
|
string | URL seguro |
seguro_label
|
string | Texto botão seguro |
categoria_ids
|
array | IDs de categorias (sync) |
external_ref
|
string | Ref do sistema origem |
external_source
|
string | Nome sistema origem |
conteudo
|
object | Conteúdo da vitrine pública (page builder). Ver schema completo em /excursoes/{id}/conteudo |
Resposta de exemplo
{
"success": true,
"message": "Excursão atualizada com sucesso.",
"data": {
"id": 45,
"nome": "Excursão Atualizada",
"status": "publicada"
}
}
Remove uma excursão. Apenas excursões sem passageiros podem ser excluídas.
excursoes:delete
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da excursão |
Resposta de exemplo
{
"success": true,
"message": "Excursão excluída com sucesso."
}
Conteúdo (Excursão)
Página de conteúdo público da excursão (atrações, inclusos, regras, etc) que renderiza a vitrine. 1:1 com excursão.
Retorna o conteúdo público da excursão (página da vitrine). Se ainda não foi criado, retorna estrutura vazia com defaults.
excursoes:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
Resposta de exemplo
{
"success": true,
"data": {
"id": 22,
"excursao_id": 45,
"status": "publicado",
"modo": "estruturado",
"titulo": "Gramado Natal Luz 2026",
"subtitulo": "5 dias de magia entre luzes e chocolate",
"resumo": "Excursão completa com hospedagem, traslados e shows do Natal Luz.",
"descricao_completa": "HTML longo descritivo...<\/p>",
"atracoes": [
"Show Natal Luz",
"Mini Mundo",
"Lago Negro",
"Rua Coberta"
],
"o_que_esperar": "Hospedagem 4 noites\nCafé incluso\nGuia bilíngue",
"o_que_esperar_array": [
"Hospedagem 4 noites",
"Café incluso",
"Guia bilíngue"
],
"regras": "Idade mínima 0 anos\nMenores acompanhados\nNão fumar no ônibus",
"regras_array": [
"Idade mínima 0 anos",
"Menores acompanhados",
"Não fumar no ônibus"
],
"o_que_levar": "Documento RG\nAgasalho\nMedicamentos pessoais",
"o_que_levar_array": [
"Documento RG",
"Agasalho",
"Medicamentos pessoais"
],
"inclusos": "Transporte ida e volta\nHospedagem 4 diárias\nCafé da manhã",
"inclusos_array": [
"Transporte ida e volta",
"Hospedagem 4 diárias",
"Café da manhã"
],
"nao_inclusos": "Almoço e jantar\nBebidas\nDespesas extras",
"nao_inclusos_array": [
"Almoço e jantar",
"Bebidas",
"Despesas extras"
],
"videos": [
"https:\/\/youtu.be\/abc123"
],
"links": [
{
"titulo": "Mapa do roteiro",
"url": "https:\/\/google.com\/maps\/..."
}
],
"capa_url": "https:\/\/cdn...\/gramado-capa.jpg",
"banner_display_mode": "hero",
"meta_title": "Gramado Natal Luz 2026 — 5 dias inesquecíveis",
"meta_description": "Venha viver a magia do Natal Luz com a melhor agência.",
"meta_keywords": "gramado, natal luz, excursão"
}
}
Cria ou atualiza o conteúdo público (upsert por excursao_id). **Os 5 campos de lista** (`o_que_esperar`, `regras`, `o_que_levar`, `inclusos`, `nao_inclusos`) aceitam 2 formatos: string com `\n` separador OU array via `{campo}_items[]` (será convertido automaticamente).
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
modo
|
string | estruturado (default) ou livre (HTML único) |
conteudo_livre
|
string | HTML completo (só se modo=livre) |
titulo
|
string | Título do bloco principal |
subtitulo
|
string | Subtítulo |
resumo
|
string | Resumo curto |
descricao_completa
|
string | Descrição longa (HTML permitido) |
atracoes
|
array | Lista de atrações: ["Praia X", "Centro Y"] |
legenda_atracoes
|
string | Texto acima da lista de atrações |
o_que_esperar
|
string | Texto multilinha (1 item por linha) |
o_que_esperar_items
|
array | Alternativa: array de strings |
legenda_o_que_esperar
|
string | Texto acima |
regras
|
string | Regras e normas (multilinha) |
regras_items
|
array | Alternativa array |
legenda_regras
|
string | Texto acima |
o_que_levar
|
string | Itens a levar (multilinha) |
o_que_levar_items
|
array | Alternativa array |
inclusos
|
string | Itens inclusos (multilinha) |
inclusos_items
|
array | Alternativa array |
nao_inclusos
|
string | Itens não inclusos (multilinha) |
nao_inclusos_items
|
array | Alternativa array |
videos
|
array | URLs YouTube/Vimeo |
legenda_videos
|
string | Texto acima dos vídeos |
links
|
array | Links: [{titulo, url}] |
titulo_galeria
|
string | Título da galeria |
legenda_galeria
|
string | Texto acima da galeria |
ingressos_ids
|
array | IDs de ingressos do tenant a exibir |
legenda_ingressos
|
string | Texto acima |
capa_url
|
string | URL da imagem de capa |
banner_display_mode
|
string | hero | vitrine | split | minimal |
meta_title
|
string | SEO: título da página |
meta_description
|
string | SEO: meta description (até 500 chars) |
meta_keywords
|
string | SEO: keywords |
status
|
string | rascunho (default) ou publicado |
Resposta de exemplo
{
"success": true,
"message": "Conteúdo salvo com sucesso.",
"data": {
"id": 22,
"excursao_id": 45,
"status": "publicado",
"titulo": "Gramado Natal Luz 2026",
"atracoes": [
"Show Natal Luz",
"Mini Mundo",
"Lago Negro"
],
"inclusos_array": [
"Transporte",
"Hospedagem",
"Café"
]
}
}
Marca o conteúdo como `publicado`. Necessário pra aparecer na vitrine pública.
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
Resposta de exemplo
{
"success": true,
"message": "Conteúdo publicado."
}
Volta o status para `rascunho` — o conteúdo deixa de aparecer na vitrine pública (mas a excursão pode continuar publicada).
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
Resposta de exemplo
{
"success": true,
"message": "Conteúdo despublicado."
}
Fotos & Capa (Excursão)
Galeria pública da excursão (até 10 fotos) + capa. Upload via multipart/form-data ou URL externa com validações de segurança (mime real via finfo, magic bytes, anti-SSRF, dimensões máx, sem SVG).
Retorna as fotos da galeria ordenadas. Inclui URL pública, thumbnail, legenda e flag de destaque.
excursoes:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
Resposta de exemplo
{
"success": true,
"data": [
{
"id": 12,
"excursao_id": 45,
"url": "https:\/\/...\/storage\/tenants\/X\/excursoes\/45\/foto1.webp",
"thumbnail_url": "https:\/\/...\/storage\/tenants\/X\/excursoes\/45\/foto1_thumb.webp",
"legenda": "Vista da praia",
"alt_text": "Praia ao pôr do sol",
"destaque": false,
"ordem": 1,
"largura": 1920,
"altura": 1280,
"tamanho": 245000
}
]
}
Aceita 2 caminhos: **(a)** multipart/form-data com campo `foto` (arquivo binário) **OU (b)** application/json com campo `url` (URL externa que será baixada e re-hospedada). Limite: 10 fotos por excursão. Validações de segurança: extensão whitelist (jpg/jpeg/png/webp/gif), MIME real via finfo, magic bytes via getimagesize, dimensões máx 8000x8000, anti-SSRF na URL externa (bloqueia IPs privados).
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
foto
|
file | Arquivo da foto (jpg/png/webp/gif, máx 10MB). multipart/form-data. Use ESTE ou `url`, não os dois. |
url
|
string | URL pública da imagem (será baixada e re-hospedada). Apenas HTTP/HTTPS, IPs privados bloqueados. |
legenda
|
string | Legenda visível na vitrine |
alt_text
|
string | Texto alternativo (SEO/acessibilidade) |
destaque
|
boolean | Marcar como destaque |
Resposta de exemplo
{
"success": true,
"message": "Foto adicionada.",
"data": {
"id": 12,
"url": "https:\/\/...\/foto.webp",
"thumbnail_url": "https:\/\/...\/foto_thumb.webp",
"ordem": 3
}
}
Edita legenda, alt_text, destaque ou ordem de uma foto existente.
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
id
*
|
integer | path | ID da foto |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
legenda
|
string | Legenda |
alt_text
|
string | Texto alternativo |
destaque
|
boolean | Destaque |
ordem
|
integer | Posição na galeria (1-N) |
Resposta de exemplo
{
"success": true,
"message": "Foto atualizada."
}
Remove a foto da galeria e apaga os arquivos do storage.
excursoes:delete
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
id
*
|
integer | path | ID da foto |
Resposta de exemplo
{
"success": true,
"message": "Foto removida."
}
Atualiza a ordem de exibição das fotos. Envie o array `ordem` com os IDs na sequência desejada (índice 0 = primeira posição).
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
ordem
*
|
array | Array de IDs na ordem desejada: [42, 41, 43, ...] |
Resposta de exemplo
{
"success": true,
"message": "Ordem atualizada."
}
Define a imagem de capa da excursão (renderizada como banner). Aceita multipart (`capa`) OU URL externa (`url`). A URL externa não é re-hospedada (fica como apontamento), mas passa por validação anti-SSRF e content-type. Para garantia de disponibilidade, prefira upload multipart.
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
capa
|
file | Arquivo da capa (jpg/png/webp/gif, máx 5MB) |
url
|
string | URL pública da capa (alternativa ao upload) |
Resposta de exemplo
{
"success": true,
"message": "Capa atualizada.",
"data": {
"capa_url": "https:\/\/...\/storage\/...\/capa.jpg"
}
}
Categorias (Excursão)
Sub-recurso de excursão: categorias de passageiro (Adulto, Criança, etc)
Retorna as categorias cadastradas para a excursão.
excursoes:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
Resposta de exemplo
{
"success": true,
"data": [
{
"id": 197,
"excursao_id": 70,
"nome": "Adulto",
"descricao": "Passageiro adulto",
"idade_min": 18,
"idade_max": null,
"ordem": 1,
"vagas_max_categoria": null,
"qtd_passageiros": 1,
"requer_documento": false,
"documento_tipo": null,
"ativo": true,
"vagas_ocupadas": 0,
"vagas_disponiveis": null,
"created_at": "2026-04-21T20:44:47.000000Z"
}
]
}
Retorna uma categoria específica.
excursoes:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
id
*
|
integer | path | ID da categoria |
Resposta de exemplo
{
"success": true,
"data": {
"id": 197,
"excursao_id": 70,
"nome": "Adulto",
"descricao": "Passageiro adulto",
"idade_min": 18,
"idade_max": null,
"ordem": 1,
"vagas_max_categoria": null,
"qtd_passageiros": 1,
"requer_documento": false,
"documento_tipo": null,
"ativo": true,
"vagas_ocupadas": 0,
"vagas_disponiveis": null,
"created_at": "2026-04-21T20:44:47.000000Z"
}
}
Cria uma nova categoria vinculada à excursão.
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
nome
*
|
string | Nome da categoria (ex: Adulto, Criança, Idoso) |
descricao
|
string | Descrição da categoria |
idade_min
|
integer | Idade mínima |
idade_max
|
integer | Idade máxima |
ordem
|
integer | Ordem de exibição (1, 2, 3...) |
vagas_max_categoria
|
integer | Limite de vagas para esta categoria |
qtd_passageiros
|
integer | Quantos passageiros ocupam (default 1; use 0 para bebê de colo) |
requer_documento
|
boolean | Exige documento específico |
documento_tipo
|
string | Tipo do documento exigido |
ativo
|
boolean | Categoria ativa |
Resposta de exemplo
{
"success": true,
"message": "Categoria criada com sucesso.",
"data": {
"id": 197,
"excursao_id": 70,
"nome": "Adulto",
"descricao": "Passageiro adulto",
"idade_min": 18,
"idade_max": null,
"ordem": 1,
"vagas_max_categoria": null,
"qtd_passageiros": 1,
"requer_documento": false,
"documento_tipo": null,
"ativo": true,
"vagas_ocupadas": 0,
"vagas_disponiveis": null,
"created_at": "2026-04-21T20:44:47.000000Z"
}
}
Atualiza parcialmente uma categoria.
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
id
*
|
integer | path | ID da categoria |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
nome
|
string | Nome da categoria (ex: Adulto, Criança, Idoso) |
descricao
|
string | Descrição da categoria |
idade_min
|
integer | Idade mínima |
idade_max
|
integer | Idade máxima |
ordem
|
integer | Ordem de exibição (1, 2, 3...) |
vagas_max_categoria
|
integer | Limite de vagas para esta categoria |
qtd_passageiros
|
integer | Quantos passageiros ocupam (default 1; use 0 para bebê de colo) |
requer_documento
|
boolean | Exige documento específico |
documento_tipo
|
string | Tipo do documento exigido |
ativo
|
boolean | Categoria ativa |
Resposta de exemplo
{
"success": true,
"message": "Categoria atualizada.",
"data": {
"id": 197,
"excursao_id": 70,
"nome": "Adulto",
"descricao": "Passageiro adulto",
"idade_min": 18,
"idade_max": null,
"ordem": 1,
"vagas_max_categoria": null,
"qtd_passageiros": 1,
"requer_documento": false,
"documento_tipo": null,
"ativo": true,
"vagas_ocupadas": 0,
"vagas_disponiveis": null,
"created_at": "2026-04-21T20:44:47.000000Z"
}
}
Remove uma categoria.
excursoes:delete
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
id
*
|
integer | path | ID da categoria |
Resposta de exemplo
{
"success": true,
"message": "Categoria excluída."
}
Reordena a exibição das categorias.
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
ordem
*
|
array | Array de IDs na nova ordem: [id1, id2, id3] |
Resposta de exemplo
{
"success": true,
"message": "Categorias reordenadas."
}
Embarques (Excursão)
Sub-recurso de excursão: pontos de embarque/retorno
Retorna todos os pontos de embarque da excursão.
excursoes:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
Resposta de exemplo
{
"success": true,
"data": [
{
"id": 188,
"excursao_id": 70,
"nome": "Terminal Tietê",
"endereco": "Av. Cruzeiro do Sul, 1800",
"cidade": "São Paulo",
"estado": "SP",
"cep": "02036-100",
"referencia": "Plataforma 35",
"hora_embarque": "05:00",
"hora_retorno": "23:00",
"data_embarque": "2026-11-15",
"tolerancia_minutos": 15,
"latitude": null,
"longitude": null,
"transporte_id": null,
"permite_reserva_online": true,
"vagas_max": null,
"ordem": 1,
"ativo": true,
"created_at": "2026-04-21T20:44:17.000000Z"
}
]
}
Retorna um ponto de embarque.
excursoes:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
id
*
|
integer | path | ID do embarque |
Resposta de exemplo
{
"success": true,
"data": {
"id": 188,
"excursao_id": 70,
"nome": "Terminal Tietê",
"endereco": "Av. Cruzeiro do Sul, 1800",
"cidade": "São Paulo",
"estado": "SP",
"cep": "02036-100",
"referencia": "Plataforma 35",
"hora_embarque": "05:00",
"hora_retorno": "23:00",
"data_embarque": "2026-11-15",
"tolerancia_minutos": 15,
"latitude": null,
"longitude": null,
"transporte_id": null,
"permite_reserva_online": true,
"vagas_max": null,
"ordem": 1,
"ativo": true,
"created_at": "2026-04-21T20:44:17.000000Z"
}
}
Cadastra um novo ponto de embarque.
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
nome
*
|
string | Nome do ponto (ex: Terminal Tietê) |
endereco
|
string | Endereço completo |
cidade
|
string | Cidade |
estado
|
string | UF |
cep
|
string | CEP |
referencia
|
string | Ponto de referência |
hora_embarque
|
string | Horário de embarque (H:i) |
hora_retorno
|
string | Horário de retorno (H:i) |
data_embarque
|
date | Data específica (sobrescreve data_inicio da excursão) |
tolerancia_minutos
|
integer | Tolerância de atraso em minutos |
latitude
|
number | Latitude do ponto |
longitude
|
number | Longitude do ponto |
transporte_id
|
integer | ID do transporte específico (se múltiplos) |
permite_reserva_online
|
boolean | Permite reserva online (default true) |
vagas_max
|
integer | Limite de vagas por este embarque |
ordem
|
integer | Ordem de exibição |
ativo
|
boolean | Embarque ativo |
Resposta de exemplo
{
"success": true,
"message": "Embarque criado.",
"data": {
"id": 188,
"excursao_id": 70,
"nome": "Terminal Tietê",
"endereco": "Av. Cruzeiro do Sul, 1800",
"cidade": "São Paulo",
"estado": "SP",
"cep": "02036-100",
"referencia": "Plataforma 35",
"hora_embarque": "05:00",
"hora_retorno": "23:00",
"data_embarque": "2026-11-15",
"tolerancia_minutos": 15,
"latitude": null,
"longitude": null,
"transporte_id": null,
"permite_reserva_online": true,
"vagas_max": null,
"ordem": 1,
"ativo": true,
"created_at": "2026-04-21T20:44:17.000000Z"
}
}
Atualiza parcialmente um ponto de embarque.
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
id
*
|
integer | path | ID do embarque |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
nome
|
string | Nome do ponto (ex: Terminal Tietê) |
endereco
|
string | Endereço completo |
cidade
|
string | Cidade |
estado
|
string | UF |
cep
|
string | CEP |
referencia
|
string | Ponto de referência |
hora_embarque
|
string | Horário de embarque (H:i) |
hora_retorno
|
string | Horário de retorno (H:i) |
data_embarque
|
date | Data específica (sobrescreve data_inicio da excursão) |
tolerancia_minutos
|
integer | Tolerância de atraso em minutos |
latitude
|
number | Latitude do ponto |
longitude
|
number | Longitude do ponto |
transporte_id
|
integer | ID do transporte específico (se múltiplos) |
permite_reserva_online
|
boolean | Permite reserva online (default true) |
vagas_max
|
integer | Limite de vagas por este embarque |
ordem
|
integer | Ordem de exibição |
ativo
|
boolean | Embarque ativo |
Resposta de exemplo
{
"success": true,
"message": "Embarque atualizado.",
"data": {
"id": 188,
"excursao_id": 70,
"nome": "Terminal Tietê",
"endereco": "Av. Cruzeiro do Sul, 1800",
"cidade": "São Paulo",
"estado": "SP",
"cep": "02036-100",
"referencia": "Plataforma 35",
"hora_embarque": "05:00",
"hora_retorno": "23:00",
"data_embarque": "2026-11-15",
"tolerancia_minutos": 15,
"latitude": null,
"longitude": null,
"transporte_id": null,
"permite_reserva_online": true,
"vagas_max": null,
"ordem": 1,
"ativo": true,
"created_at": "2026-04-21T20:44:17.000000Z"
}
}
Remove um ponto de embarque.
excursoes:delete
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
id
*
|
integer | path | ID do embarque |
Resposta de exemplo
{
"success": true,
"message": "Embarque excluído."
}
Reordena a exibição dos embarques.
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
ordem
*
|
array | Array de IDs na nova ordem |
Resposta de exemplo
{
"success": true,
"message": "Embarques reordenados."
}
Preços (Excursão)
Sub-recurso de excursão: valores por categoria × embarque
Retorna todos os preços (categoria × embarque) da excursão.
excursoes:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
Resposta de exemplo
{
"success": true,
"data": [
{
"id": 371,
"excursao_id": 70,
"categoria_id": 197,
"embarque_id": 188,
"valor": 250,
"valor_ate": null,
"valor_aumenta_em": null,
"permite_reserva_online": true,
"ativo": true,
"categoria": {
"id": 197,
"nome": "Adulto"
},
"embarque": {
"id": 188,
"nome": "Terminal Tietê"
},
"created_at": "2026-04-21T20:44:57.000000Z"
}
]
}
Retorna um preço específico.
excursoes:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
id
*
|
integer | path | ID do preço |
Resposta de exemplo
{
"success": true,
"data": {
"id": 371,
"excursao_id": 70,
"categoria_id": 197,
"embarque_id": 188,
"valor": 250,
"valor_ate": null,
"valor_aumenta_em": null,
"permite_reserva_online": true,
"ativo": true,
"categoria": {
"id": 197,
"nome": "Adulto"
},
"embarque": {
"id": 188,
"nome": "Terminal Tietê"
},
"created_at": "2026-04-21T20:44:57.000000Z"
}
}
Cadastra um preço vinculado a uma categoria (e opcionalmente a um embarque).
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
categoria_id
*
|
integer | ID da categoria (Adulto, Criança, etc) |
embarque_id
|
integer | ID do embarque (permite preço diferente por ponto) |
valor
*
|
number | Valor atual cobrado (R$) |
valor_ate
|
number | Valor limite quando há reajuste progressivo |
valor_aumenta_em
|
date | Data em que o valor passa para valor_ate |
permite_reserva_online
|
boolean | Permite reserva online (default true) |
ativo
|
boolean | Preço ativo |
Resposta de exemplo
{
"success": true,
"message": "Preço criado.",
"data": {
"id": 371,
"excursao_id": 70,
"categoria_id": 197,
"embarque_id": 188,
"valor": 250,
"valor_ate": null,
"valor_aumenta_em": null,
"permite_reserva_online": true,
"ativo": true,
"categoria": {
"id": 197,
"nome": "Adulto"
},
"embarque": {
"id": 188,
"nome": "Terminal Tietê"
},
"created_at": "2026-04-21T20:44:57.000000Z"
}
}
Atualiza parcialmente um preço.
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
id
*
|
integer | path | ID do preço |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
categoria_id
|
integer | ID da categoria (Adulto, Criança, etc) |
embarque_id
|
integer | ID do embarque (permite preço diferente por ponto) |
valor
|
number | Valor atual cobrado (R$) |
valor_ate
|
number | Valor limite quando há reajuste progressivo |
valor_aumenta_em
|
date | Data em que o valor passa para valor_ate |
permite_reserva_online
|
boolean | Permite reserva online (default true) |
ativo
|
boolean | Preço ativo |
Resposta de exemplo
{
"success": true,
"message": "Preço atualizado.",
"data": {
"id": 371,
"excursao_id": 70,
"categoria_id": 197,
"embarque_id": 188,
"valor": 250,
"valor_ate": null,
"valor_aumenta_em": null,
"permite_reserva_online": true,
"ativo": true,
"categoria": {
"id": 197,
"nome": "Adulto"
},
"embarque": {
"id": 188,
"nome": "Terminal Tietê"
},
"created_at": "2026-04-21T20:44:57.000000Z"
}
}
Remove um preço.
excursoes:delete
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
id
*
|
integer | path | ID do preço |
Resposta de exemplo
{
"success": true,
"message": "Preço excluído."
}
Atualiza múltiplos preços em uma única chamada. Útil para reajustes.
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
precos
*
|
array | Lista: [{id*, valor?, valor_ate?, valor_aumenta_em?, ativo?}] |
Resposta de exemplo
{
"success": true,
"message": "Preços atualizados.",
"data": {
"atualizados": 4
}
}
Variações
Opções de preço de um pacote de viagem (Leito, Semi-leito, tipo de quarto). Cada item de "precos" da excursão traz excursao_variacao_id; é aqui que se descobre o nome por trás desse id. Só existem em excursões com tipo_excursao=pacote_viagem.
Retorna as variações da excursão, na ordem definida no painel, com a faixa de preço e a ocupação de cada uma. Em excursão que não é pacote de viagem a lista volta vazia.
excursoes:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
ativas
|
boolean | query | Quando 1, retorna apenas as variações ativas |
Resposta de exemplo
{
"success": true,
"data": [
{
"id": 82,
"excursao_id": 39,
"nome": "Quarto DUPLO + Bike Mecânica",
"descricao": null,
"tipo": "generica",
"tipo_label": "Genérica",
"codigo": null,
"ordem": 4,
"ativa": true,
"vagas_maximas": null,
"vagas_ocupadas": 6,
"vagas_disponiveis": null,
"fornecedor_id": null,
"precos": {
"quantidade": 1,
"menor": 1990,
"maior": 1990
}
}
]
}
Retorna uma variação específica da excursão.
excursoes:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
id
*
|
integer | path | ID da variação |
Resposta de exemplo
{
"success": true,
"data": {
"id": 82,
"excursao_id": 39,
"nome": "Quarto DUPLO + Bike Mecânica",
"descricao": null,
"tipo": "generica",
"tipo_label": "Genérica",
"codigo": null,
"ordem": 4,
"ativa": true,
"vagas_maximas": null,
"vagas_ocupadas": 6,
"vagas_disponiveis": null,
"fornecedor_id": null,
"precos": {
"quantidade": 1,
"menor": 1990,
"maior": 1990
}
}
}
Cria uma variação na excursão. Entra no fim da lista. Recusa com 422 quando a excursão não é pacote de viagem (TIPO_NAO_SUPORTA_VARIACAO) ou quando o código já existe na mesma excursão (DUPLICATE_CODE).
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
nome
*
|
string | Nome exibido ao cliente (ex: Leito, Semi-leito, Quarto DUPLO + Bike Mecânica) |
tipo
*
|
string | hospedagem, acomodacao, refeicao, transporte ou generica |
descricao
|
string | Detalhamento do que está incluído |
codigo
|
string | Código interno. Deve ser único dentro da excursão |
ativa
|
boolean | Disponível para venda (default true) |
vagas_maximas
|
integer | Limite de vagas desta variação. Nulo = sem limite |
fornecedor_id
|
integer | Fornecedor responsável por esta variação |
metadata
|
object | Campos livres do integrador |
Resposta de exemplo
{
"success": true,
"message": "Variação criada com sucesso",
"data": {
"id": 82,
"excursao_id": 39,
"nome": "Quarto DUPLO + Bike Mecânica",
"descricao": null,
"tipo": "generica",
"tipo_label": "Genérica",
"codigo": null,
"ordem": 4,
"ativa": true,
"vagas_maximas": null,
"vagas_ocupadas": 6,
"vagas_disponiveis": null,
"fornecedor_id": null,
"precos": {
"quantidade": 1,
"menor": 1990,
"maior": 1990
}
}
}
Atualização parcial: envie apenas os campos que quer mudar. Recusa com 422 ao reduzir vagas_maximas abaixo do que já foi vendido (LIMITE_ABAIXO_DO_VENDIDO). Para tirar da venda sem apagar histórico, envie ativa=false.
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
id
*
|
integer | path | ID da variação |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
nome
|
string | Nome exibido ao cliente (ex: Leito, Semi-leito, Quarto DUPLO + Bike Mecânica) |
tipo
|
string | hospedagem, acomodacao, refeicao, transporte ou generica |
descricao
|
string | Detalhamento do que está incluído |
codigo
|
string | Código interno. Deve ser único dentro da excursão |
ativa
|
boolean | Disponível para venda (default true) |
vagas_maximas
|
integer | Limite de vagas desta variação. Nulo = sem limite |
fornecedor_id
|
integer | Fornecedor responsável por esta variação |
metadata
|
object | Campos livres do integrador |
Resposta de exemplo
{
"success": true,
"message": "Variação atualizada com sucesso",
"data": {
"id": 82,
"excursao_id": 39,
"nome": "Quarto DUPLO + Bike Mecânica",
"descricao": null,
"tipo": "generica",
"tipo_label": "Genérica",
"codigo": null,
"ordem": 4,
"ativa": true,
"vagas_maximas": null,
"vagas_ocupadas": 6,
"vagas_disponiveis": null,
"fornecedor_id": null,
"precos": {
"quantidade": 1,
"menor": 1990,
"maior": 1990
}
}
}
Remove a variação e os preços ligados a ela. Bloqueado com 422 quando já há passageiros na variação (VARIACAO_COM_PASSAGEIROS); nesse caso use ativa=false.
excursoes:delete
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
id
*
|
integer | path | ID da variação |
Resposta de exemplo
{
"success": true,
"message": "Variação removida com sucesso"
}
Pacote de Viagem
Sub-recursos da aba "Editar Viagem > Pacote": dados gerais, roteiro dia-a-dia, componentes, voos, cruzeiro, allotment, cotações com opções e vouchers. Exige excursão com `tipo_excursao=pacote_viagem` (exceto cotações, que aceitam qualquer tipo). Para gestão de quartos/rooming, use o módulo de Hospedagem (addon).
Retorna dados gerais do pacote (país, cidade, hotel, regime, observações).
excursoes:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
Resposta de exemplo
{
"success": true,
"data": {
"pais": "Argentina",
"estado": "Buenos Aires",
"cidade": "Buenos Aires",
"nome_hotel": "Hotel Madero",
"categoria_hotel": "5 estrelas",
"regime_hospedagem": "Café da manhã",
"documentos_necessarios": "Passaporte ou RG válido",
"observacoes_pacote": "Reembolso integral até 30 dias antes.",
"duracao_noites": 5
}
}
`duracao_noites` é calculada automaticamente pelas datas da excursão.
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
pais
|
string | Max 100 |
estado
|
string | Max 100 |
cidade
|
string | Max 100 |
nome_hotel
|
string | Max 255 |
categoria_hotel
|
string | Ex: 5 estrelas, Pousada |
regime_hospedagem
|
string | Café, Meia pensão, All inclusive |
documentos_necessarios
|
string | Texto multilinha |
observacoes_pacote
|
string | Texto multilinha |
Resposta de exemplo
{
"success": true,
"message": "Dados do pacote atualizados."
}
Listar dias do roteiro
excursoes:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
Resposta de exemplo
{
"success": true,
"data": [
{
"id": 10,
"dia": 1,
"titulo": "Chegada em Buenos Aires",
"cidade": "Buenos Aires",
"pernoite": "Hotel Madero",
"regime": "Café da manhã",
"atividades": [
"Traslado",
"City tour"
]
}
]
}
Adicionar dia ao roteiro
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
dia
*
|
integer | Número sequencial do dia (1, 2, 3...) |
titulo
*
|
string | Max 255 |
descricao
|
string | |
cidade
|
string | |
pernoite
|
string | |
regime
|
string | Café, almoço, jantar |
atividades
|
array | Lista de atividades do dia |
imagem
|
string | Path retornado por POST /roteiro/upload-imagem |
Resposta de exemplo
{
"success": true,
"data": {
"id": 11,
"dia": 2,
"titulo": "Tour pela cidade"
}
}
Atualizar dia do roteiro
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
itinerarioId
*
|
integer | path |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
dia
*
|
integer | |
titulo
*
|
string | |
descricao
|
string | |
imagem
|
string |
Resposta de exemplo
{
"success": true
}
Remover dia do roteiro
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
itinerarioId
*
|
integer | path |
Resposta de exemplo
{
"success": true,
"message": "Dia removido do roteiro."
}
Reordenar dias
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
items
*
|
array | Lista de {id, dia} com a nova ordem |
Resposta de exemplo
{
"success": true,
"message": "Roteiro reordenado."
}
Faz upload de uma imagem para usar em um dia do roteiro. Retorna `path` que deve ser informado no campo `imagem` ao criar ou atualizar o dia.
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
imagem
*
|
file | multipart/form-data — jpg/jpeg/png/webp, max 5MB |
Resposta de exemplo
{
"success": true,
"data": {
"path": "excursoes\/123\/roteiro\/abcd1234.jpg"
}
}
Retorna lista de componentes + agregados (custo_total, preco_venda, margem, confirmados).
excursoes:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
Resposta de exemplo
{
"success": true,
"data": {
"componentes": [
{
"id": 25,
"tipo": "hospedagem",
"nome": "Hotel Madero - 5 noites",
"custo_unitario": 350,
"moeda_custo": "USD",
"confirmacao_status": "pendente"
}
],
"dashboard": {
"custo_total": 1820,
"preco_venda": 2500,
"margem": 680,
"margem_percentual": 27.2,
"confirmados": 0,
"total": 1
}
}
}
Adicionar componente
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
tipo
*
|
string | hospedagem, refeicao, ingresso, transfer, voo, seguro, etc |
nome
*
|
string | |
descricao
|
string | |
fornecedor_nome
|
string | |
fornecedor_email
|
string | |
fornecedor_telefone
|
string | |
confirmacao_status
|
string | pendente | confirmado | negado |
confirmacao_codigo
|
string | |
custo_unitario
|
number | |
custo_fixo
|
number | |
tipo_custo
|
string | por_pessoa | por_quarto | fixo | por_diaria |
moeda_custo
|
string | BRL, USD, EUR... (default BRL) |
taxa_cambio
|
number | Se moeda != BRL |
taxa_cambio_data
|
string | YYYY-MM-DD |
incluso
|
boolean | |
obrigatorio
|
boolean | |
valor_adicional
|
number | Se não incluso |
Resposta de exemplo
{
"success": true,
"data": {
"id": 25
}
}
Atualizar componente
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
componenteId
*
|
integer | path |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
tipo
*
|
string | |
nome
*
|
string | |
confirmacao_status
|
string | |
custo_unitario
|
number | |
ativo
|
boolean |
Resposta de exemplo
{
"success": true
}
Remover componente
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
componenteId
*
|
integer | path |
Resposta de exemplo
{
"success": true,
"message": "Componente removido."
}
Listar voos
excursoes:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
Resposta de exemplo
{
"success": true,
"data": []
}
Adicionar voo
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
tipo
*
|
string | ida | volta | conexao |
cia_aerea
|
string | |
numero_voo
|
string | |
aeroporto_origem
|
string | IATA (3 letras) |
aeroporto_destino
|
string | IATA (3 letras) |
data_voo
|
string | YYYY-MM-DD |
horario_partida
|
string | HH:MM |
horario_chegada
|
string | HH:MM |
classe
|
string | economica | executiva | primeira |
bagagem
|
string | |
observacoes
|
string |
Resposta de exemplo
{
"success": true,
"data": {
"id": 5
}
}
Atualizar voo
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
vooId
*
|
integer | path |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
tipo
*
|
string | |
cia_aerea
|
string | |
numero_voo
|
string |
Resposta de exemplo
{
"success": true
}
Remover voo
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
vooId
*
|
integer | path |
Resposta de exemplo
{
"success": true,
"message": "Voo removido."
}
1:1 com a excursão. Retorna null se não houver.
excursoes:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
Resposta de exemplo
{
"success": true,
"data": null
}
Cria ou atualiza (uma única operação).
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
companhia
|
string | Ex: MSC, Costa, Royal Caribbean |
navio
|
string | |
porto_embarque
|
string | |
porto_retorno
|
string | |
partida
|
string | YYYY-MM-DD |
chegada
|
string | YYYY-MM-DD |
itinerario
|
string | Texto livre |
observacoes
|
string |
Resposta de exemplo
{
"success": true
}
Remover cruzeiro
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
Resposta de exemplo
{
"success": true,
"message": "Cruzeiro removido."
}
Quartos pré-reservados com deadline de liberação.
excursoes:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
Resposta de exemplo
{
"success": true,
"data": []
}
Criar allotment
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
tipo
*
|
string | Ex: quarto, cabine, assento |
descricao
*
|
string | |
quantidade_total
*
|
integer | |
componente_id
|
integer | |
deadline
|
string | YYYY-MM-DD |
custo_unitario
|
number | |
observacoes
|
string |
Resposta de exemplo
{
"success": true,
"data": {
"id": 9
}
}
Atualizar allotment
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
allotmentId
*
|
integer | path |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
tipo
*
|
string | |
descricao
*
|
string | |
quantidade_total
*
|
integer | |
status
|
string | ativo | esgotado | expirado | cancelado |
Resposta de exemplo
{
"success": true
}
Remover allotment
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
allotmentId
*
|
integer | path |
Resposta de exemplo
{
"success": true,
"message": "Allotment removido."
}
Disponível para qualquer excursão (não exige tipo_excursao=pacote_viagem).
excursoes:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
Resposta de exemplo
{
"success": true,
"data": []
}
Criar cotação
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
cliente_id
*
|
integer | |
mensagem_personalizada
|
string | |
validade
|
string | YYYY-MM-DD |
Resposta de exemplo
{
"success": true,
"data": {
"id": 12
}
}
Atualizar cotação
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
cotacaoId
*
|
integer | path |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
cliente_id
*
|
integer | |
status
|
string | rascunho | enviada | visualizada | aceita | recusada | expirada |
Resposta de exemplo
{
"success": true
}
Remover cotação
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
cotacaoId
*
|
integer | path |
Resposta de exemplo
{
"success": true,
"message": "Cotacao removida."
}
Adicionar opção à cotação
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
cotacaoId
*
|
integer | path |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
nome
*
|
string | Ex: Pacote Premium |
descricao
|
string | |
valor_total
*
|
number | |
custo_total
|
number | |
componentes_inclusos
|
array | Lista de strings com o que inclui |
detalhes
|
object | JSON livre |
destaque
|
boolean | Marcar como recomendada |
Resposta de exemplo
{
"success": true,
"data": {
"id": 33
}
}
Atualizar opção da cotação
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
cotacaoId
*
|
integer | path | |
opcaoId
*
|
integer | path |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
nome
*
|
string | |
valor_total
*
|
number |
Resposta de exemplo
{
"success": true
}
Remover opção da cotação
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
cotacaoId
*
|
integer | path | |
opcaoId
*
|
integer | path |
Resposta de exemplo
{
"success": true,
"message": "Opção removida."
}
Listar vouchers de fornecedor
excursoes:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
Resposta de exemplo
{
"success": true,
"data": []
}
Criar voucher
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
tipo
*
|
string | Ex: ingresso, transfer, hospedagem |
fornecedor_nome
*
|
string | |
fornecedor_contato
|
string | |
componente_id
|
integer | |
codigo_reserva
|
string | |
data_servico
|
string | YYYY-MM-DD |
horario
|
string | HH:MM |
detalhes
|
string | |
observacoes_internas
|
string | |
passageiros
|
array | IDs de passageiros vinculados |
status
|
string | pendente | confirmado | cancelado |
Resposta de exemplo
{
"success": true,
"data": {
"id": 18
}
}
Atualizar voucher
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
voucherId
*
|
integer | path |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
tipo
*
|
string | |
fornecedor_nome
*
|
string | |
status
|
string |
Resposta de exemplo
{
"success": true
}
Remover voucher
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
voucherId
*
|
integer | path |
Resposta de exemplo
{
"success": true,
"message": "Voucher removido."
}
Custo unitário total, custo fixo total, custo total por pessoa, preço de venda, margem, receita estimada, lucro estimado e quebra por tipo de componente.
excursoes:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão (precisa ser tipo_excursao=pacote_viagem) |
Resposta de exemplo
{
"success": true,
"data": {
"custo_unitario_total": 1820,
"custo_fixo_total": 500,
"custo_total_por_pessoa": 1845,
"preco_venda": 2500,
"margem_por_pessoa": 655,
"margem_percentual": 26.2,
"passageiros_ativos": 20,
"receita_estimada": 50000,
"custo_estimado": 36900,
"lucro_estimado": 13100,
"componentes_confirmados": 5,
"componentes_total": 8
}
}
Custeio da Viagem
Custos operacionais da excursão (ônibus, guia, hospedagem, pedágio, alimentação, ingressos), precificação com composição de valores (overhead, lucro, comissão, taxas), cenários por ocupação, ponto de equilíbrio e rentabilidade real. Espelha a aba **Custeio** da edição da viagem. Requer addon `gestao-financeira` (custos vivem em `fin_contas_pagar`).
Retorna TUDO em uma chamada: custos fixos e variáveis listados, totais agregados, custo por pax, capacidade, passageiros vendidos, receita real, configuração de precificação, cenários por ocupação, ponto de equilíbrio (break-even em pax), rentabilidade real e comissões por vendedor.
excursoes:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
Resposta de exemplo
{
"success": true,
"data": {
"custos_fixos": [],
"custos_variaveis": [],
"variacoes": [],
"pax_por_variacao": [],
"total_fixo": 5000,
"total_variavel": 150,
"custo_por_pax": 250,
"capacidade": 40,
"passageiros_vendidos": 28,
"receita_real": 11200,
"precificacao": {
"overhead_percentual": 10,
"lucro_desejado_percentual": 20
},
"preco_sugerido": 380,
"break_even_pax": 18,
"cenarios": [],
"rentabilidade": {
"margem_real": 30.5,
"lucro_real": 3416
},
"comissoes": []
}
}
Cria um custo da viagem (entra como `fin_conta_pagar` vinculada à excursão). `tipo_custo=fixo` é rateado entre todos os pax; `tipo_custo=variavel` é por pax (ou por variação se informar `excursao_variacao_id`).
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
fornecedor
|
string | Ex: Viação São Paulo, Hotel Madero |
descricao
|
string | Descrição do custo |
categoria_id
|
integer | ID de fin_categorias |
valor
*
|
number | Min 0.01 |
tipo_custo
*
|
string | fixo (rateado entre pax) | variavel (por pax) |
excursao_variacao_id
|
integer | Quando o custo variável aplica só a uma variação (ex: hospedagem camping vs alojamento) |
data_vencimento
|
string | YYYY-MM-DD |
forma_pagamento
|
string | dinheiro | pix | cartao_credito | cartao_debito | transferencia | boleto | cheque |
observacao
|
string | |
desconto_crianca
|
number | % de desconto pra criança (0-100) |
desconto_idoso
|
number | % de desconto pra idoso (0-100) |
desconto_bebe
|
number | % de desconto pra bebê (0-100) |
Resposta de exemplo
{
"success": true,
"message": "Custo adicionado com sucesso!",
"data": {
"custo": {
"id": 42
}
}
}
Atualizar custo
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
custoId
*
|
integer | path | ID do custo (FinContaPagar) |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
valor
*
|
number | |
tipo_custo
*
|
string | fixo | variavel |
fornecedor
|
string | |
descricao
|
string | |
categoria_id
|
integer | |
data_vencimento
|
string | |
forma_pagamento
|
string |
Resposta de exemplo
{
"success": true,
"message": "Custo atualizado com sucesso!"
}
Soft delete. Custo deixa de impactar nos totais.
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
custoId
*
|
integer | path | ID do custo (FinContaPagar) |
Resposta de exemplo
{
"success": true,
"message": "Custo removido com sucesso!"
}
Define `status=pago`, `valor_pago=valor`, `data_pagamento=now()`, `pago_por=usuário corrente`. Retorna 422 se já está pago.
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
custoId
*
|
integer | path | ID do custo (FinContaPagar) |
Resposta de exemplo
{
"success": true,
"message": "Custo marcado como pago!"
}
Volta para `pendente` (ou `vencido` se passou da data). Retorna 422 se não estava pago.
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
custoId
*
|
integer | path | ID do custo (FinContaPagar) |
Resposta de exemplo
{
"success": true,
"message": "Pagamento revertido."
}
Define a **composição de valores** que entra no cálculo do preço sugerido: overhead, lucro desejado, comissão de vendedor, taxas financeiras, ocupação estimada e mix de meios de pagamento. Persiste em `excursao_precificacao` (1:1 com excursão).
excursoes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
overhead_percentual
|
number | % de overhead (admin, marketing, infra) |
lucro_desejado_percentual
|
number | % de lucro alvo |
comissao_vendedor_percentual
|
number | % de comissão |
comissao_base
|
string | bruto | liquido | preco_venda | custo |
taxa_financeira_media
|
number | % médio das taxas de gateway |
ocupacao_estimada
|
integer | % de ocupação alvo (1-100) |
passageiros_estimados
|
integer | Nº absoluto de pax (alternativa a ocupacao_estimada) |
mix_financeiro
|
array | Array de {percentual, taxa} por meio de pagamento |
taxas_financeiras
|
array | Array de {percentual, taxa} alternativo |
Resposta de exemplo
{
"success": true,
"message": "Precificação salva com sucesso!",
"data": {
"precificacao": {
"preco_sugerido": 380
}
}
}
Calcula cenários (margem, lucro, break-even) para um `preco_venda` arbitrário SEM persistir. Se `preco_venda` for omitido, usa o `preco_sugerido` da precificação salva. Retorna 422 se nem o preço foi informado nem há precificação salva.
excursoes:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
preco_venda
|
number | Preço de venda a testar. Se omitido, usa o preco_sugerido salvo. |
Resposta de exemplo
{
"success": true,
"data": {
"cenarios": [
{
"ocupacao_pct": 50,
"pax": 20,
"receita": 7600,
"custo": 6000,
"lucro": 1600,
"margem_pct": 21
},
{
"ocupacao_pct": 100,
"pax": 40,
"receita": 15200,
"custo": 11000,
"lucro": 4200,
"margem_pct": 27.6
}
],
"break_even_pax": 18,
"capacidade": 40,
"preco_venda": 380
}
}
Passageiros
Gerenciamento de passageiros individuais das excursões
Lista passageiros de uma excursão específica.
passageiros:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
status
|
string | query | pendente, confirmado, cancelado, embarcado |
search
|
string | query | Busca por nome ou CPF |
per_page
|
integer | query | Itens por página |
Resposta de exemplo
{
"success": true,
"data": [
{
"id": 1001,
"excursao_id": 45,
"cliente_id": 123,
"comprador_id": 123,
"preco_id": 77,
"embarque_id": 12,
"transporte_id": 9,
"categoria_id": 1,
"valor_cobrado": 1450,
"status": "confirmado",
"codigo_reserva": "VGABC12345",
"qr_code": "550e8400-e29b-41d4-a716-446655440000",
"assento": "A-10",
"observacao": null,
"cadastrado_via": "api",
"cliente": {
"id": 123,
"nome": "Maria Silva Santos",
"cpf": "12345678901",
"telefone": "11999998888"
},
"preco": {
"id": 77,
"valor": 1450,
"categoria_id": 1,
"embarque_id": 12
},
"embarque": {
"id": 12,
"nome": "Terminal Tietê",
"hora_embarque": "06:00"
},
"transporte": {
"id": 9,
"nome": "Ônibus 1",
"tipo": "onibus_leito"
},
"categoria": {
"id": 1,
"nome": "Adulto"
},
"checkin_at": null,
"created_at": "2024-01-20T11:30:00Z"
}
],
"meta": {
"current_page": 1,
"per_page": 20,
"total": 45
}
}
Retorna passageiro com cliente, preço, embarque, transporte.
passageiros:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
id
*
|
integer | path | ID do passageiro |
Resposta de exemplo
{
"success": true,
"data": {
"id": 1001,
"excursao_id": 45,
"cliente_id": 123,
"comprador_id": 123,
"preco_id": 77,
"embarque_id": 12,
"transporte_id": 9,
"categoria_id": 1,
"valor_cobrado": 1450,
"status": "confirmado",
"codigo_reserva": "VGABC12345",
"qr_code": "550e8400-e29b-41d4-a716-446655440000",
"assento": "A-10",
"observacao": null,
"cadastrado_via": "api",
"cliente": {
"id": 123,
"nome": "Maria Silva Santos",
"cpf": "12345678901",
"telefone": "11999998888"
},
"preco": {
"id": 77,
"valor": 1450,
"categoria_id": 1,
"embarque_id": 12
},
"embarque": {
"id": 12,
"nome": "Terminal Tietê",
"hora_embarque": "06:00"
},
"transporte": {
"id": 9,
"nome": "Ônibus 1",
"tipo": "onibus_leito"
},
"categoria": {
"id": 1,
"nome": "Adulto"
},
"checkin_at": null,
"created_at": "2024-01-20T11:30:00Z"
}
}
Adiciona um passageiro (cliente novo ou existente). Para múltiplos passageiros em uma order, prefira POST /reservas.
passageiros:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
cliente_id
|
integer | ID do cliente existente (ou enviar cliente inline) |
cliente
|
object | Dados do cliente inline: {nome*, cpf, email, telefone} |
preco_id
*
|
integer | ID do preço escolhido |
categoria_id
|
integer | ID da categoria (inferido do preço se omitido) |
embarque_id
|
integer | ID do ponto de embarque (opcional para pacote sem transporte) |
transporte_id
|
integer | ID do transporte (opcional para pacote sem transporte) |
valor_cobrado
|
number | Valor específico (default = valor do preço) |
assento
|
string | Identificador do assento (ex: A-10) |
observacao
|
string | Observações |
status
|
string | pendente (default), confirmado |
Resposta de exemplo
{
"success": true,
"message": "Passageiro adicionado com sucesso.",
"data": {
"id": 1001,
"excursao_id": 45,
"cliente_id": 123,
"comprador_id": 123,
"preco_id": 77,
"embarque_id": 12,
"transporte_id": 9,
"categoria_id": 1,
"valor_cobrado": 1450,
"status": "confirmado",
"codigo_reserva": "VGABC12345",
"qr_code": "550e8400-e29b-41d4-a716-446655440000",
"assento": "A-10",
"observacao": null,
"cadastrado_via": "api",
"cliente": {
"id": 123,
"nome": "Maria Silva Santos",
"cpf": "12345678901",
"telefone": "11999998888"
},
"preco": {
"id": 77,
"valor": 1450,
"categoria_id": 1,
"embarque_id": 12
},
"embarque": {
"id": 12,
"nome": "Terminal Tietê",
"hora_embarque": "06:00"
},
"transporte": {
"id": 9,
"nome": "Ônibus 1",
"tipo": "onibus_leito"
},
"categoria": {
"id": 1,
"nome": "Adulto"
},
"checkin_at": null,
"created_at": "2024-01-20T11:30:00Z"
}
}
Atualiza um passageiro (dados, embarque, assento, status).
passageiros:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
id
*
|
integer | path | ID do passageiro |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
embarque_id
|
integer | Trocar embarque |
transporte_id
|
integer | Trocar transporte |
assento
|
string | Novo assento |
valor_cobrado
|
number | Ajustar valor |
status
|
string | pendente, confirmado, cancelado, embarcado |
observacao
|
string | Observações |
Resposta de exemplo
{
"success": true,
"message": "Passageiro atualizado.",
"data": {
"id": 1001,
"excursao_id": 45,
"cliente_id": 123,
"comprador_id": 123,
"preco_id": 77,
"embarque_id": 12,
"transporte_id": 9,
"categoria_id": 1,
"valor_cobrado": 1450,
"status": "confirmado",
"codigo_reserva": "VGABC12345",
"qr_code": "550e8400-e29b-41d4-a716-446655440000",
"assento": "A-10",
"observacao": null,
"cadastrado_via": "api",
"cliente": {
"id": 123,
"nome": "Maria Silva Santos",
"cpf": "12345678901",
"telefone": "11999998888"
},
"preco": {
"id": 77,
"valor": 1450,
"categoria_id": 1,
"embarque_id": 12
},
"embarque": {
"id": 12,
"nome": "Terminal Tietê",
"hora_embarque": "06:00"
},
"transporte": {
"id": 9,
"nome": "Ônibus 1",
"tipo": "onibus_leito"
},
"categoria": {
"id": 1,
"nome": "Adulto"
},
"checkin_at": null,
"created_at": "2024-01-20T11:30:00Z"
}
}
Cancela (soft delete) o passageiro e libera a vaga.
passageiros:delete
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
id
*
|
integer | path | ID do passageiro |
Resposta de exemplo
{
"success": true,
"message": "Passageiro cancelado."
}
Marca passageiro como embarcado (checkin).
checkin:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
id
*
|
integer | path | ID do passageiro |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
latitude
|
number | Latitude do ponto de check-in |
longitude
|
number | Longitude |
observacao
|
string | Observação |
Resposta de exemplo
{
"success": true,
"message": "Check-in realizado.",
"data": {
"id": 1001,
"excursao_id": 45,
"cliente_id": 123,
"comprador_id": 123,
"preco_id": 77,
"embarque_id": 12,
"transporte_id": 9,
"categoria_id": 1,
"valor_cobrado": 1450,
"status": "confirmado",
"codigo_reserva": "VGABC12345",
"qr_code": "550e8400-e29b-41d4-a716-446655440000",
"assento": "A-10",
"observacao": null,
"cadastrado_via": "api",
"cliente": {
"id": 123,
"nome": "Maria Silva Santos",
"cpf": "12345678901",
"telefone": "11999998888"
},
"preco": {
"id": 77,
"valor": 1450,
"categoria_id": 1,
"embarque_id": 12
},
"embarque": {
"id": 12,
"nome": "Terminal Tietê",
"hora_embarque": "06:00"
},
"transporte": {
"id": 9,
"nome": "Ônibus 1",
"tipo": "onibus_leito"
},
"categoria": {
"id": 1,
"nome": "Adulto"
},
"checkin_at": null,
"created_at": "2024-01-20T11:30:00Z"
}
}
Retorna o cartão de embarque do passageiro. O parâmetro `format` define o formato: `pdf` (default, stream binário application/pdf), `base64` (JSON com PDF em base64) ou `link` (JSON com URL pública assinada via token). O parâmetro `grupo` aplica-se a TODOS os formatos: quando true (ou auto-detectado), retorna o cartão consolidado de todo o grupo (titular + dependentes), uma página por passageiro no PDF.
passageiros:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
id
*
|
integer | path | ID do passageiro |
format
|
string | query | Formato de retorno: pdf | base64 | link (default: pdf) |
grupo
|
boolean | query | Se true, retorna o cartão de embarque do grupo todo (titular + dependentes). Default: auto — true quando o passageiro tem dependentes ativos, false para individual. Vale para todos os formatos (pdf/base64/link). |
Resposta de exemplo
{
"success": true,
"data": {
"filename": "cartao-embarque-ABCD1234.pdf",
"content_type": "application\/pdf",
"content_base64": "JVBERi0xLjQK...",
"size_bytes": 142536
}
}
Clientes
Cadastro de clientes, dependentes e histórico de reservas
Lista paginada de clientes com filtros.
clientes:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
page
|
integer | query | Página |
per_page
|
integer | query | Itens (max 100) |
search
|
string | query | Busca por nome, email, CPF, celular ou telefone. Termos com 5+ dígitos cruzam com CPF/celular/telefone normalizados. |
email
|
string | query | E-mail exato |
cpf
|
string | query | CPF (com ou sem formatação) |
celular
|
string | query | Celular/WhatsApp. Aceita com/sem DDI 55, com/sem 9, com/sem máscara. Compara últimos 10 dígitos. |
whatsapp
|
string | query | Alias de celular |
telefone
|
string | query | Filtra também pela coluna telefone (fixo). Mesma normalização. |
ativo
|
boolean | query | Filtrar por ativo/inativo |
Resposta de exemplo
{
"success": true,
"data": [
{
"id": 123,
"nome": "Maria Silva Santos",
"email": "[email protected]",
"cpf": "12345678901",
"rg": "12.345.678-9",
"passaporte": null,
"nacionalidade": "Brasileira",
"documento_estrangeiro": null,
"documento_estrangeiro_tipo": null,
"documento_estrangeiro_emissor": null,
"documento_estrangeiro_emissao": null,
"data_nascimento": "1985-03-15",
"telefone": "1133334444",
"celular": "11999998888",
"instagram": "@maria.silva",
"cep": "01310-100",
"endereco": "Av. Paulista",
"numero": "1000",
"complemento": "Apto 52",
"bairro": "Bela Vista",
"cidade": "São Paulo",
"estado": "SP",
"contato_emergencia_nome": "João Silva",
"contato_emergencia_parentesco": "Cônjuge",
"contato_emergencia_telefone": "11988887777",
"avatar_url": null,
"observacoes": null,
"ativo": true,
"origem_cadastro": "api",
"campos_personalizados": {
"profissao": "Engenheiro",
"tamanho_camiseta": "M"
},
"created_at": "2024-01-10T14:30:00Z",
"updated_at": "2024-02-05T09:15:00Z"
}
],
"meta": {
"current_page": 1,
"per_page": 20,
"total": 1250
}
}
Busca exata por CPF (11 dígitos).
clientes:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
cpf
*
|
string | query | CPF (com ou sem formatação) |
Resposta de exemplo
{
"success": true,
"data": {
"id": 123,
"nome": "Maria Silva Santos",
"email": "[email protected]",
"cpf": "12345678901",
"rg": "12.345.678-9",
"passaporte": null,
"nacionalidade": "Brasileira",
"documento_estrangeiro": null,
"documento_estrangeiro_tipo": null,
"documento_estrangeiro_emissor": null,
"documento_estrangeiro_emissao": null,
"data_nascimento": "1985-03-15",
"telefone": "1133334444",
"celular": "11999998888",
"instagram": "@maria.silva",
"cep": "01310-100",
"endereco": "Av. Paulista",
"numero": "1000",
"complemento": "Apto 52",
"bairro": "Bela Vista",
"cidade": "São Paulo",
"estado": "SP",
"contato_emergencia_nome": "João Silva",
"contato_emergencia_parentesco": "Cônjuge",
"contato_emergencia_telefone": "11988887777",
"avatar_url": null,
"observacoes": null,
"ativo": true,
"origem_cadastro": "api",
"campos_personalizados": {
"profissao": "Engenheiro",
"tamanho_camiseta": "M"
},
"created_at": "2024-01-10T14:30:00Z",
"updated_at": "2024-02-05T09:15:00Z"
}
}
Busca cliente pelo telefone com normalização tolerante a formato (DDI 55, 9 mobile, máscara). Útil para chatbots identificarem cliente recorrente a partir do número do WhatsApp.
clientes:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
celular
|
string | query | Aceita whatsapp= ou telefone= como alias. Ex: "85999281920", "(85) 99928-1920", "+5585999281920" |
whatsapp
|
string | query | Alias de celular |
telefone
|
string | query | Alias de celular |
Resposta de exemplo
{
"success": true,
"data": {
"id": 123,
"nome": "Maria Silva Santos",
"email": "[email protected]",
"cpf": "12345678901",
"rg": "12.345.678-9",
"passaporte": null,
"nacionalidade": "Brasileira",
"documento_estrangeiro": null,
"documento_estrangeiro_tipo": null,
"documento_estrangeiro_emissor": null,
"documento_estrangeiro_emissao": null,
"data_nascimento": "1985-03-15",
"telefone": "1133334444",
"celular": "11999998888",
"instagram": "@maria.silva",
"cep": "01310-100",
"endereco": "Av. Paulista",
"numero": "1000",
"complemento": "Apto 52",
"bairro": "Bela Vista",
"cidade": "São Paulo",
"estado": "SP",
"contato_emergencia_nome": "João Silva",
"contato_emergencia_parentesco": "Cônjuge",
"contato_emergencia_telefone": "11988887777",
"avatar_url": null,
"observacoes": null,
"ativo": true,
"origem_cadastro": "api",
"campos_personalizados": {
"profissao": "Engenheiro",
"tamanho_camiseta": "M"
},
"created_at": "2024-01-10T14:30:00Z",
"updated_at": "2024-02-05T09:15:00Z"
}
}
Retorna o cliente. Use include_dependentes=true para trazer os dependentes.
clientes:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do cliente |
include_dependentes
|
boolean | query | Se true, inclui array dependentes na resposta |
Resposta de exemplo
{
"success": true,
"data": {
"id": 123,
"nome": "Maria Silva Santos",
"email": "[email protected]",
"cpf": "12345678901",
"rg": "12.345.678-9",
"passaporte": null,
"nacionalidade": "Brasileira",
"documento_estrangeiro": null,
"documento_estrangeiro_tipo": null,
"documento_estrangeiro_emissor": null,
"documento_estrangeiro_emissao": null,
"data_nascimento": "1985-03-15",
"telefone": "1133334444",
"celular": "11999998888",
"instagram": "@maria.silva",
"cep": "01310-100",
"endereco": "Av. Paulista",
"numero": "1000",
"complemento": "Apto 52",
"bairro": "Bela Vista",
"cidade": "São Paulo",
"estado": "SP",
"contato_emergencia_nome": "João Silva",
"contato_emergencia_parentesco": "Cônjuge",
"contato_emergencia_telefone": "11988887777",
"avatar_url": null,
"observacoes": null,
"ativo": true,
"origem_cadastro": "api",
"campos_personalizados": {
"profissao": "Engenheiro",
"tamanho_camiseta": "M"
},
"created_at": "2024-01-10T14:30:00Z",
"updated_at": "2024-02-05T09:15:00Z",
"dependentes": []
}
}
Lista paginada dos pedidos (Orders) onde o cliente é comprador. Retorna o pedido completo com codigo, valor_total, status e passageiros aninhados (incluindo vagas pendentes com cadastrado_via=convite_pendente).
clientes:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do cliente |
status
|
string | query | Filtro CSV (ex: "pendente,confirmado") |
excursao_id
|
integer | query | Pedidos contendo passageiros desta excursão |
updated_since
|
datetime | query | Modificados a partir de (ISO 8601). Sync incremental. |
per_page
|
integer | query | Itens (max 100) |
Resposta de exemplo
{
"success": true,
"data": [
{
"id": 501,
"codigo": "VG-ABC12345",
"valor_total": 2900,
"valor_pago": 0,
"valor_pendente": 2900,
"status": "pendente",
"passageiros": [
{
"id": 1001,
"nome": "Maria Silva",
"cadastrado_via": "api",
"valor_cobrado": 1450
},
{
"id": 1002,
"nome": "Vaga 2",
"cadastrado_via": "convite_pendente",
"valor_cobrado": 1450
}
]
}
],
"meta": {
"current_page": 1,
"per_page": 20,
"total": 5
}
}
Cria um cliente. origem_cadastro é gravado automaticamente como "api". Valida unicidade de CPF e email (retorna 409 em duplicata). A resposta inclui um auto_login_url (magic link de 30 min, one-time use) pronto para redirecionar o cliente já logado no portal.
clientes:write
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
nome
*
|
string | Nome completo (required em POST) |
email
|
string | E-mail (único) |
cpf
|
string | CPF (apenas dígitos ou formatado, será normalizado) |
rg
|
string | RG |
passaporte
|
string | Número do passaporte |
nacionalidade
|
string | Nacionalidade |
documento_estrangeiro
|
string | Documento estrangeiro (para não-brasileiros) |
documento_estrangeiro_tipo
|
string | Tipo do documento estrangeiro |
documento_estrangeiro_emissor
|
string | Órgão emissor |
documento_estrangeiro_emissao
|
date | Data de emissão (Y-m-d) |
data_nascimento
|
date | Data de nascimento (Y-m-d) |
telefone
|
string | Telefone fixo |
celular
|
string | Celular/WhatsApp |
instagram
|
string | @usuario do Instagram |
cep
|
string | CEP |
endereco
|
string | Logradouro |
numero
|
string | Número |
complemento
|
string | Complemento |
bairro
|
string | Bairro |
cidade
|
string | Cidade |
estado
|
string | UF (2 letras) |
contato_emergencia_nome
|
string | Nome do contato de emergência |
contato_emergencia_parentesco
|
string | Parentesco do contato |
contato_emergencia_telefone
|
string | Telefone do contato |
avatar_url
|
string | URL da foto |
ativo
|
boolean | Cliente ativo (default true) |
observacoes
|
string | Observações livres |
campos_personalizados
|
object | Campos personalizados de cliente. Objeto { field_key: valor }. Os field_keys variam por empresa (veja os campos ativos em Configurações > Formulários > Clientes). Em campos de seleção aceita o value da opção OU o rótulo (mapeado para o value); multi-seleção por lista separada por vírgula. field_key inexistente ou valor de seleção inválido retornam 422 com as opções válidas. |
Resposta de exemplo
{
"success": true,
"message": "Cliente criado com sucesso.",
"data": {
"id": 123,
"nome": "Maria Silva Santos",
"email": "[email protected]",
"cpf": "12345678901",
"rg": "12.345.678-9",
"passaporte": null,
"nacionalidade": "Brasileira",
"documento_estrangeiro": null,
"documento_estrangeiro_tipo": null,
"documento_estrangeiro_emissor": null,
"documento_estrangeiro_emissao": null,
"data_nascimento": "1985-03-15",
"telefone": "1133334444",
"celular": "11999998888",
"instagram": "@maria.silva",
"cep": "01310-100",
"endereco": "Av. Paulista",
"numero": "1000",
"complemento": "Apto 52",
"bairro": "Bela Vista",
"cidade": "São Paulo",
"estado": "SP",
"contato_emergencia_nome": "João Silva",
"contato_emergencia_parentesco": "Cônjuge",
"contato_emergencia_telefone": "11988887777",
"avatar_url": null,
"observacoes": null,
"ativo": true,
"origem_cadastro": "api",
"campos_personalizados": {
"profissao": "Engenheiro",
"tamanho_camiseta": "M"
},
"created_at": "2024-01-10T14:30:00Z",
"updated_at": "2024-02-05T09:15:00Z",
"auto_login_url": "https:\/\/seu-tenant.viagilize.com.br\/auth\/magic\/abc123...",
"auto_login_expires_at": "2026-04-21T22:15:00+00:00",
"auto_login_single_use": true
}
}
Atualiza parcialmente um cliente. Todos os campos são opcionais.
clientes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do cliente |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
nome
|
string | Nome completo (required em POST) |
email
|
string | E-mail (único) |
cpf
|
string | CPF (apenas dígitos ou formatado, será normalizado) |
rg
|
string | RG |
passaporte
|
string | Número do passaporte |
nacionalidade
|
string | Nacionalidade |
documento_estrangeiro
|
string | Documento estrangeiro (para não-brasileiros) |
documento_estrangeiro_tipo
|
string | Tipo do documento estrangeiro |
documento_estrangeiro_emissor
|
string | Órgão emissor |
documento_estrangeiro_emissao
|
date | Data de emissão (Y-m-d) |
data_nascimento
|
date | Data de nascimento (Y-m-d) |
telefone
|
string | Telefone fixo |
celular
|
string | Celular/WhatsApp |
instagram
|
string | @usuario do Instagram |
cep
|
string | CEP |
endereco
|
string | Logradouro |
numero
|
string | Número |
complemento
|
string | Complemento |
bairro
|
string | Bairro |
cidade
|
string | Cidade |
estado
|
string | UF (2 letras) |
contato_emergencia_nome
|
string | Nome do contato de emergência |
contato_emergencia_parentesco
|
string | Parentesco do contato |
contato_emergencia_telefone
|
string | Telefone do contato |
avatar_url
|
string | URL da foto |
ativo
|
boolean | Cliente ativo (default true) |
observacoes
|
string | Observações livres |
campos_personalizados
|
object | Campos personalizados de cliente. Objeto { field_key: valor }. Os field_keys variam por empresa (veja os campos ativos em Configurações > Formulários > Clientes). Em campos de seleção aceita o value da opção OU o rótulo (mapeado para o value); multi-seleção por lista separada por vírgula. field_key inexistente ou valor de seleção inválido retornam 422 com as opções válidas. |
Resposta de exemplo
{
"success": true,
"message": "Cliente atualizado com sucesso.",
"data": {
"id": 123,
"nome": "Maria Silva Santos",
"email": "[email protected]",
"cpf": "12345678901",
"rg": "12.345.678-9",
"passaporte": null,
"nacionalidade": "Brasileira",
"documento_estrangeiro": null,
"documento_estrangeiro_tipo": null,
"documento_estrangeiro_emissor": null,
"documento_estrangeiro_emissao": null,
"data_nascimento": "1985-03-15",
"telefone": "1133334444",
"celular": "11999998888",
"instagram": "@maria.silva",
"cep": "01310-100",
"endereco": "Av. Paulista",
"numero": "1000",
"complemento": "Apto 52",
"bairro": "Bela Vista",
"cidade": "São Paulo",
"estado": "SP",
"contato_emergencia_nome": "João Silva",
"contato_emergencia_parentesco": "Cônjuge",
"contato_emergencia_telefone": "11988887777",
"avatar_url": null,
"observacoes": null,
"ativo": true,
"origem_cadastro": "api",
"campos_personalizados": {
"profissao": "Engenheiro",
"tamanho_camiseta": "M"
},
"created_at": "2024-01-10T14:30:00Z",
"updated_at": "2024-02-05T09:15:00Z"
}
}
Remove o cliente (soft delete).
clientes:delete
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID |
Resposta de exemplo
{
"success": true,
"message": "Cliente excluído com sucesso."
}
Gera um novo token de auto-login para um cliente existente. O token é válido por 30 minutos, one-time use (invalida após primeiro clique) e invalida qualquer token anterior. Use para SSO: parceiro envia o URL por WhatsApp/email e o cliente cai já logado em /minha-conta.
clientes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do cliente |
Resposta de exemplo
{
"success": true,
"message": "Link de login automático gerado.",
"data": {
"cliente_id": 86,
"auto_login_url": "https:\/\/seu-tenant.viagilize.com.br\/auth\/magic\/abc123...",
"auto_login_expires_at": "2026-04-21T22:15:00+00:00",
"auto_login_single_use": true
}
}
Invalida o token atual do cliente (equivalente a "logout forçado" dos links pendentes). Use em caso de token comprometido.
clientes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do cliente |
Resposta de exemplo
{
"success": true,
"message": "Token de auto-login revogado."
}
Lista os dependentes (filhos, cônjuges, etc) do cliente.
clientes:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do cliente |
Resposta de exemplo
{
"success": true,
"data": [
{
"id": 301,
"cliente_id": 123,
"nome": "Lucas Silva",
"cpf": "98765432100",
"data_nascimento": "2012-06-20",
"parentesco": "filho",
"created_at": "2024-03-12T10:00:00Z"
}
]
}
Cria um dependente vinculado ao cliente.
clientes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do cliente |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
nome
*
|
string | Nome completo |
cpf
|
string | CPF |
rg
|
string | RG |
passaporte
|
string | Passaporte |
nacionalidade
|
string | Nacionalidade |
documento_estrangeiro
|
string | Documento estrangeiro |
documento_estrangeiro_tipo
|
string | Tipo |
documento_estrangeiro_emissor
|
string | Emissor |
documento_estrangeiro_emissao
|
date | Emissão |
data_nascimento
|
date | Nascimento |
parentesco
|
string | filho, cônjuge, pai, mãe... |
telefone
|
string | Telefone |
email
|
string | |
observacoes
|
string | Observações |
Resposta de exemplo
{
"success": true,
"message": "Dependente criado com sucesso.",
"data": {
"id": 301,
"cliente_id": 123,
"nome": "Lucas Silva",
"parentesco": "filho"
}
}
Atualiza um dependente. Todos os campos são opcionais.
clientes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do cliente |
dependenteId
*
|
integer | path | ID do dependente |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
nome
|
string | Nome completo |
cpf
|
string | CPF |
rg
|
string | RG |
passaporte
|
string | Passaporte |
nacionalidade
|
string | Nacionalidade |
documento_estrangeiro
|
string | Documento estrangeiro |
documento_estrangeiro_tipo
|
string | Tipo |
documento_estrangeiro_emissor
|
string | Emissor |
documento_estrangeiro_emissao
|
date | Emissão |
data_nascimento
|
date | Nascimento |
parentesco
|
string | filho, cônjuge, pai, mãe... |
telefone
|
string | Telefone |
email
|
string | |
observacoes
|
string | Observações |
Resposta de exemplo
{
"success": true,
"message": "Dependente atualizado com sucesso.",
"data": {
"id": 301,
"nome": "Lucas Silva Atualizado"
}
}
Remove o dependente.
clientes:delete
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do cliente |
dependenteId
*
|
integer | path | ID do dependente |
Resposta de exemplo
{
"success": true,
"message": "Dependente excluído com sucesso."
}
Reservas
Orders de reservas com geração de link de pagamento
Lista paginada de orders/reservas com filtros.
reservas:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
page
|
integer | query | Página |
per_page
|
integer | query | Itens (max 100) |
status
|
string | query | pendente, parcial, pago, cancelado, reembolsado |
cliente_id
|
integer | query | Filtrar por comprador |
excursao_id
|
integer | query | Filtrar por excursão |
data_de
|
date | query | Criadas a partir de (Y-m-d) |
data_ate
|
date | query | Criadas até (Y-m-d) |
updated_since
|
datetime | query | Modificadas a partir de (ISO 8601). Útil para sync incremental. |
search
|
string | query | Busca por código da order, nome ou email do comprador |
Resposta de exemplo
{
"success": true,
"data": [
{
"id": 501,
"codigo": "VG-ABC12345",
"comprador_id": 123,
"status": "pendente",
"valor_original": 2900,
"valor_total": 2900,
"valor_pago": 0,
"valor_pendente": 2900,
"pagamento_expira_em": "2026-04-26T18:30:42-03:00",
"forma_pagamento": "pix",
"parcelas": 1,
"origem": "api",
"gateway_preference_id": null,
"comprador": {
"id": 123,
"nome": "Maria Silva Santos",
"email": "[email protected]",
"cpf": "12345678901"
},
"passageiros": [
{
"id": 1001,
"excursao_id": 45,
"cliente_id": 123,
"preco_id": 77,
"embarque_id": 12,
"transporte_id": 9,
"categoria_id": 1,
"valor_cobrado": 1450,
"status": "pendente",
"codigo_reserva": "VGABC12345",
"qr_code": "550e8400-e29b-41d4-a716-446655440000",
"excursao": {
"id": 45,
"nome": "Gramado - Natal Luz 2025"
}
},
{
"id": 1002,
"excursao_id": 45,
"cliente_id": 124,
"preco_id": 77,
"valor_cobrado": 1450,
"status": "pendente",
"codigo_reserva": "VGDEF67890"
}
],
"payments": [],
"created_at": "2024-10-15T11:30:00Z"
}
],
"meta": {
"current_page": 1,
"per_page": 20,
"total": 32
}
}
Reserva completa com passageiros, preços, embarques, transportes, pagamentos e financeiro. Inclui também `total_pendentes` (vagas aguardando preenchimento), `passageiros_completos` e `passageiros_total` — use pra decidir liberação de cartão de embarque sem precisar chamar /passageiros-pendentes.
reservas:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da reserva (order) |
Resposta de exemplo
{
"success": true,
"data": {
"id": 501,
"codigo": "VG-ABC12345",
"comprador_id": 123,
"status": "pendente",
"valor_original": 2900,
"valor_total": 2900,
"valor_pago": 0,
"valor_pendente": 2900,
"pagamento_expira_em": "2026-04-26T18:30:42-03:00",
"forma_pagamento": "pix",
"parcelas": 1,
"origem": "api",
"gateway_preference_id": null,
"comprador": {
"id": 123,
"nome": "Maria Silva Santos",
"email": "[email protected]",
"cpf": "12345678901"
},
"passageiros": [
{
"id": 1001,
"excursao_id": 45,
"cliente_id": 123,
"preco_id": 77,
"embarque_id": 12,
"transporte_id": 9,
"categoria_id": 1,
"valor_cobrado": 1450,
"status": "pendente",
"codigo_reserva": "VGABC12345",
"qr_code": "550e8400-e29b-41d4-a716-446655440000",
"excursao": {
"id": 45,
"nome": "Gramado - Natal Luz 2025"
}
},
{
"id": 1002,
"excursao_id": 45,
"cliente_id": 124,
"preco_id": 77,
"valor_cobrado": 1450,
"status": "pendente",
"codigo_reserva": "VGDEF67890"
}
],
"payments": [],
"created_at": "2024-10-15T11:30:00Z",
"total_pendentes": 0,
"passageiros_completos": 3,
"passageiros_total": 3
}
}
Cria uma order com um ou mais passageiros em transação. Aceita cliente_id existente ou objeto cliente inline (auto-cria por CPF/email). Se gerar_link_pagamento=true, retorna também `payment_url` do gateway ativo. Se a geração falhar (sem gateway, excursão sem preço, etc), a reserva ainda é criada e a resposta inclui `payment_link_error: { code, message }` em vez de `payment_url`.
reservas:write
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
excursao_id
*
|
integer | ID da excursão/pacote |
cliente_id
|
integer | ID do comprador (ou enviar cliente inline) |
cliente
|
object | Dados do comprador inline: {nome*, email, cpf, telefone, celular, cep, endereco, numero, bairro, cidade, estado, forcar_novo?}. Dedupe LGPD: CPF first, e-mail só reusa se cliente existente nao tiver CPF. Use forcar_novo=true para pular dedupe. |
passageiros
*
|
array | Lista (1-20): {cliente_id|cliente|pendente, preco_id*, categoria_id?, embarque_id?, transporte_id?, valor_cobrado?, observacao?}. Use pendente:true (sem cliente_id/cliente) pra criar vaga aguardando dados — o comprador preenche depois (portal /minha-conta/convites, API POST .../preencher, ou link público de convite retornado). |
forma_pagamento
|
string | pix, cartao, boleto, dinheiro, transferencia |
parcelas
|
integer | Número de parcelas (1-24) |
observacoes
|
string | Observações livres |
gerar_link_pagamento
|
boolean | Se true, retorna payment_url junto |
Resposta de exemplo
{
"success": true,
"message": "Reserva criada com sucesso.",
"data": {
"id": 501,
"codigo": "VG-ABC12345",
"comprador_id": 123,
"status": "pendente",
"valor_original": 2900,
"valor_total": 2900,
"valor_pago": 0,
"valor_pendente": 2900,
"pagamento_expira_em": "2026-04-26T18:30:42-03:00",
"forma_pagamento": "pix",
"parcelas": 1,
"origem": "api",
"gateway_preference_id": null,
"comprador": {
"id": 123,
"nome": "Maria Silva Santos",
"email": "[email protected]",
"cpf": "12345678901"
},
"passageiros": [
{
"id": 1001,
"excursao_id": 45,
"cliente_id": 123,
"preco_id": 77,
"embarque_id": 12,
"transporte_id": 9,
"categoria_id": 1,
"valor_cobrado": 1450,
"status": "pendente",
"codigo_reserva": "VGABC12345",
"qr_code": "550e8400-e29b-41d4-a716-446655440000",
"excursao": {
"id": 45,
"nome": "Gramado - Natal Luz 2025"
}
},
{
"id": 1002,
"excursao_id": 45,
"cliente_id": 124,
"preco_id": 77,
"valor_cobrado": 1450,
"status": "pendente",
"codigo_reserva": "VGDEF67890"
}
],
"payments": [],
"created_at": "2024-10-15T11:30:00Z",
"payment_url": "https:\/\/mpago.la\/abc123",
"payment_gateway": "Mercado Pago"
}
}
Gera uma URL de pagamento no gateway ativo do tenant (Mercado Pago, Asaas, Pagar.me, Infinite Pay, PagSeguro, ValePay). Requer que o tenant tenha ao menos um gateway configurado e habilitado.
reservas:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da reserva |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
valor
|
number | Valor a cobrar (default = valor_pendente da reserva) |
Resposta de exemplo
{
"success": true,
"data": {
"url": "https:\/\/mpago.la\/abc123",
"gateway": "Mercado Pago",
"valor": 2900,
"order_id": 501
}
}
Registra um pagamento manual (dinheiro, transferência, PIX confirmado fora do gateway, etc). Cria OrderPayment, propaga para o financeiro de cada passageiro proporcionalmente ao valor cobrado, confirma passageiros automaticamente se o valor total for atingido e envia e-mail de confirmação.
reservas:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da reserva |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
valor
*
|
number | Valor pago (não pode exceder valor_pendente) |
forma_pagamento
*
|
string | pix, cartao, boleto, dinheiro, transferencia, cheque |
gateway
|
string | Nome do gateway se aplicável (mercadopago, asaas, pagarme, infinitipay...) |
gateway_payment_id
|
string | ID externo do pagamento no gateway |
observacao
|
string | Observação livre |
Resposta de exemplo
{
"success": true,
"message": "Pagamento registrado com sucesso.",
"data": {
"payment": {
"id": 42,
"order_id": 501,
"valor": 1450,
"forma_pagamento": "pix",
"status": "aprovado",
"pago_em": "2024-10-25T10:15:00Z"
},
"order": {
"id": 501,
"codigo": "VG-ABC12345",
"valor_total": 2900,
"valor_pago": 1450,
"valor_pendente": 1450,
"status": "parcial"
}
}
}
Cancela a reserva e todos os passageiros associados. Dispara webhook reserva.cancelada.
reservas:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da reserva |
Resposta de exemplo
{
"success": true,
"message": "Reserva cancelada.",
"data": {
"id": 501,
"status": "cancelado"
}
}
Gera URL única (válida 30 minutos, single-use) que loga o comprador e redireciona para a página da reserva no portal cliente. Útil para enviar via WhatsApp/email pós-pagamento e pedir que o cliente complete documentos/contrato.
reservas:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da reserva |
Resposta de exemplo
{
"success": true,
"message": "Magic link da reserva gerado.",
"data": {
"reserva_id": 501,
"codigo": "VG-ABC12345",
"cliente_id": 123,
"magic_link_url": "https:\/\/tenant.viagilize.com.br\/auth\/magic\/abc123def456?redirect=%2Fminha-conta%2Freservas%2FVG-ABC12345",
"expires_at": "2026-04-25T22:00:00-03:00",
"single_use": true
}
}
Retorna o status do aceite eletrônico do contrato por passageiro da reserva. Inclui referência ao SignatureAgreement ativo (se houver). O fluxo recomendado é: pagar primeiro (via payment-link) → gerar magic-link → cliente assina pelo portal.
reservas:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da reserva |
Resposta de exemplo
{
"success": true,
"data": {
"reserva_id": 501,
"codigo": "VG-ABC12345",
"exige_contrato": true,
"passageiros": [
{
"passageiro_id": 1001,
"codigo_reserva": "VGABC12345",
"cliente_id": 123,
"nome": "Maria Silva Santos",
"aceite_status": false,
"aceite_data": null,
"aceite_ip": null,
"agreement": {
"id": 891,
"status": "pending",
"created_at": "2026-04-25T19:15:00-03:00",
"signed_at": null
}
}
],
"fluxo": "O aceite acontece pelo portal do cliente apos o pagamento, via magic link em \/minha-conta\/excursao\/{id}\/contrato. Use POST \/reservas\/{id}\/magic-link para gerar."
}
}
Lista as vagas pendentes (passageiros placeholder aguardando preenchimento). Cada vaga retorna o link_convite — URL pública do formulário que pode ser copiada e enviada via WhatsApp/email para o convidado preencher, ou usada pelo comprador no portal. **Auto-renovação:** se o token de uma vaga ainda pendente estiver expirado/usado, este endpoint regenera automaticamente um token novo (24h de validade) antes de retornar. Não é necessário chamar o endpoint dedicado de reenviar-convite — basta consultar este GET periodicamente.
reservas:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da reserva |
Resposta de exemplo
{
"success": true,
"data": {
"reserva_id": 501,
"codigo": "VG-ABC12345",
"total_pendentes": 2,
"vagas_pendentes": [
{
"pendente_id": 10,
"posicao": 2,
"valor": 1450,
"status": "pendente",
"preco_id": 77,
"transporte_id": 9,
"transporte_nome": "Ônibus 01",
"embarque_id": 12,
"embarque_nome": "Terminal Tietê",
"expira_em": "2026-05-26T18:30:42-03:00",
"link_convite": "https:\/\/tenant.viagilize.com.br\/convite\/abc123def456...",
"created_at": "2026-05-19T10:00:00-03:00"
}
]
}
}
Preenche os dados de uma vaga pendente em nome do comprador. Atualiza o ExcursaoPassageiro placeholder com os dados reais. Aceita 1 de 3 formas: (a) cliente_id de cliente existente, (b) dependente_id do comprador, ou (c) dados crus (nome+cpf+...) que cria/reusa cliente por CPF (LGPD).
reservas:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da reserva |
pendenteId
*
|
integer | path | ID da vaga pendente |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
cliente_id
|
integer | Forma A: usa cliente já cadastrado |
dependente_id
|
integer | Forma B: usa dependente do comprador |
nome
|
string | Forma C (com cpf): cria/reusa cliente |
cpf
|
string | Forma C (com nome): aceita com/sem formatação |
rg
|
string | RG do passageiro (opcional) |
telefone
|
string | Telefone/celular do passageiro (opcional) |
email
|
string | E-mail do passageiro (opcional) |
data_nascimento
|
date | Data de nascimento (YYYY-MM-DD, opcional) |
Resposta de exemplo
{
"success": true,
"message": "Vaga preenchida com sucesso.",
"data": {
"passageiro": {
"id": 1002,
"nome": "João Silva",
"cpf": "12345678901",
"cliente_id": 245,
"cadastrado_via": "preenchido_comprador"
},
"pendente_id": 10
}
}
Invalida o token atual e gera um novo (validade padrão 24h). Use para recuperar vaga com link_convite expirado. Não dispara envio por canal — quem decide se reencaminha por WhatsApp/email é o integrador.
reservas:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da reserva |
pendenteId
*
|
integer | path | ID da vaga pendente |
Resposta de exemplo
{
"success": true,
"message": "Convite regenerado.",
"data": {
"pendente_id": 10,
"link_convite": "https:\/\/tenant.viagilize.com.br\/convite\/abc123token",
"expira_em": "2026-05-20T13:00:00-03:00"
}
}
Cancela uma vaga pendente não preenchida. O valor da vaga é subtraído de valor_total/valor_pendente do pedido. Token de convite associado é invalidado.
reservas:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da reserva |
pendenteId
*
|
integer | path | ID da vaga pendente |
Resposta de exemplo
{
"success": true,
"message": "Vaga pendente cancelada."
}
Remove permanentemente uma reserva e todos os passageiros, financeiros, pagamentos e vagas pendentes vinculados. Só funciona com status=cancelado — use POST /reservas/{id}/cancel primeiro para reservas ativas.
reservas:delete
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da reserva |
Resposta de exemplo
{
"success": true,
"message": "Reserva removida permanentemente.",
"data": {
"codigo": "A8CA1475"
}
}
Lista de Espera
Fila de espera por excursão. Quando uma vaga abre, o sistema notifica o primeiro da fila com janela de oferta limitada.
Lista paginada das entradas em lista de espera, com filtros.
reservas:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
page
|
integer | query | Página |
per_page
|
integer | query | Itens (max 100) |
excursao_id
|
integer | query | Filtrar por excursão |
status
|
string | query | aguardando, notificado, expirado, cancelado, convertido |
cliente_id
|
integer | query | Filtrar por cliente |
Resposta de exemplo
{
"success": true,
"data": [
{
"id": 17,
"excursao_id": 45,
"cliente_id": 123,
"nome": "Maria Silva Santos",
"email": "[email protected]",
"celular": "85988887777",
"cpf": "12345678901",
"quantidade": 2,
"observacoes": "Aceita troca de embarque se houver",
"posicao": 3,
"status": "aguardando",
"origem": "api",
"created_at": "2026-04-25T15:00:00-03:00"
}
],
"meta": {
"current_page": 1,
"per_page": 20,
"total": 7
}
}
Retorna a entrada com cliente e excursão carregados.
reservas:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da entrada |
Resposta de exemplo
{
"success": true,
"data": {
"id": 17,
"excursao_id": 45,
"cliente_id": 123,
"nome": "Maria Silva Santos",
"email": "[email protected]",
"celular": "85988887777",
"cpf": "12345678901",
"quantidade": 2,
"observacoes": "Aceita troca de embarque se houver",
"posicao": 3,
"status": "aguardando",
"origem": "api",
"created_at": "2026-04-25T15:00:00-03:00"
}
}
Adiciona uma pessoa na fila. Posição é calculada automaticamente (ultima da fila para essa excursão).
reservas:write
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
excursao_id
*
|
integer | ID da excursão |
cliente_id
|
integer | ID de cliente existente (alternativa a passar nome/email/celular) |
nome
|
string | Obrigatorio se cliente_id nao for informado |
email
|
string | Email para notificacao quando vaga abrir |
celular
|
string | Celular para notificacao via WhatsApp |
cpf
|
string | CPF (opcional) |
quantidade
|
integer | Quantas vagas reservar (1-20, default 1) |
observacoes
|
string | Observacoes livres |
Resposta de exemplo
{
"success": true,
"message": "Entrada criada na lista de espera.",
"data": {
"id": 17,
"excursao_id": 45,
"cliente_id": 123,
"nome": "Maria Silva Santos",
"email": "[email protected]",
"celular": "85988887777",
"cpf": "12345678901",
"quantidade": 2,
"observacoes": "Aceita troca de embarque se houver",
"posicao": 3,
"status": "aguardando",
"origem": "api",
"created_at": "2026-04-25T15:00:00-03:00"
}
}
Marca a entrada como cancelada. Posicoes seguintes nao sao reordenadas automaticamente.
reservas:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da entrada |
Resposta de exemplo
{
"success": true,
"message": "Entrada removida da lista de espera."
}
Financeiro
Pagamentos e dados financeiros dos passageiros
Resumo financeiro: valor total, pago, pendente, status.
financeiro:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
passageiroId
*
|
integer | path | ID do passageiro |
Resposta de exemplo
{
"success": true,
"data": {
"id": 301,
"passageiro_id": 1001,
"valor_original": 1450,
"valor_desconto": 0,
"valor_total": 1450,
"valor_pago": 725,
"valor_pendente": 725,
"percentual_pago": 50,
"forma_pagamento": "pix",
"parcelas": 2,
"status": "parcial",
"ultimo_pagamento_em": "2024-10-20T14:22:00Z"
}
}
Lista todos os pagamentos registrados para um passageiro.
financeiro:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
passageiroId
*
|
integer | path | ID do passageiro |
Resposta de exemplo
{
"success": true,
"data": [
{
"id": 501,
"passageiro_id": 1001,
"valor": 725,
"forma": "pix",
"gateway": "mercado_pago",
"gateway_payment_id": "mp_12345",
"data_pagamento": "2024-10-20",
"observacao": null,
"created_at": "2024-10-20T14:22:00Z"
}
]
}
Registra um pagamento manual (ex: recebido em dinheiro, transferência). Atualiza valor_pago do passageiro/order.
financeiro:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
passageiroId
*
|
integer | path | ID do passageiro |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
valor
*
|
number | Valor pago (>= 0.01) |
forma
*
|
string | pix, cartao, boleto, dinheiro, transferencia, cheque |
data_pagamento
|
date | Data do pagamento (default: hoje) |
observacao
|
string | Observações |
Resposta de exemplo
{
"success": true,
"message": "Pagamento registrado.",
"data": {
"id": 502,
"valor": 725,
"forma": "pix",
"data_pagamento": "2024-10-25"
}
}
Agrega valores de todos os passageiros da excursão.
financeiro:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
Resposta de exemplo
{
"success": true,
"data": {
"totais": {
"passageiros": 45,
"com_financeiro": 45,
"valor_total": 65250,
"valor_pago": 32625,
"valor_pendente": 32625,
"percentual_pago": 50
},
"por_status": {
"pendente": 10,
"parcial": 25,
"pago": 10,
"cancelado": 0,
"reembolsado": 0
}
}
}
Cupons
Cupons de desconto: CRUD, validação e aplicação em reservas.
Lista paginada de cupons com filtros opcionais.
cupons:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
search
|
string | query | Busca por código ou nome |
ativo
|
boolean | query | Filtra por status ativo |
tipo
|
string | query | publico | unico | cliente | primeira_compra | indicacao |
apenas_principais
|
boolean | query | Se true, omite cupons filhos de lotes |
per_page
|
integer | query | Itens por página (default 50, máx 100) |
Resposta de exemplo
{
"success": true,
"data": [
{
"id": 42,
"codigo": "VERAO50",
"nome": "Promoção Verão 2026",
"descricao": "Desconto de 15% nas excursões de janeiro e fevereiro",
"tipo": "publico",
"tipo_label": "Público",
"tipo_desconto": "percentual",
"tipo_desconto_label": "Percentual",
"valor_desconto": 15,
"desconto_formatado": "15%",
"valor_maximo_desconto": 300,
"valor_minimo_pedido": 500,
"limite_uso_total": 100,
"limite_uso_por_cliente": 1,
"usos": 27,
"usos_disponiveis": 73,
"usos_progresso": "27\/100",
"data_inicio": "2026-01-01T00:00:00Z",
"data_expiracao": "2026-02-28T23:59:59Z",
"excursoes_permitidas": null,
"excursoes_excluidas": null,
"categorias_permitidas": null,
"apenas_primeira_compra": false,
"clientes_permitidos": null,
"clientes_bloqueados": null,
"cupom_pai_id": null,
"lote_nome": null,
"is_lote": false,
"is_filho_lote": false,
"ativo": true,
"status": "Ativo",
"status_color": "green",
"valido": true,
"created_at": "2025-12-15T10:00:00Z",
"updated_at": "2026-01-10T14:30:00Z"
}
]
}
Retorna todos os campos do cupom + contagem de usos e status calculado.
cupons:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do cupom |
Resposta de exemplo
{
"success": true,
"data": {
"id": 42,
"codigo": "VERAO50",
"nome": "Promoção Verão 2026",
"descricao": "Desconto de 15% nas excursões de janeiro e fevereiro",
"tipo": "publico",
"tipo_label": "Público",
"tipo_desconto": "percentual",
"tipo_desconto_label": "Percentual",
"valor_desconto": 15,
"desconto_formatado": "15%",
"valor_maximo_desconto": 300,
"valor_minimo_pedido": 500,
"limite_uso_total": 100,
"limite_uso_por_cliente": 1,
"usos": 27,
"usos_disponiveis": 73,
"usos_progresso": "27\/100",
"data_inicio": "2026-01-01T00:00:00Z",
"data_expiracao": "2026-02-28T23:59:59Z",
"excursoes_permitidas": null,
"excursoes_excluidas": null,
"categorias_permitidas": null,
"apenas_primeira_compra": false,
"clientes_permitidos": null,
"clientes_bloqueados": null,
"cupom_pai_id": null,
"lote_nome": null,
"is_lote": false,
"is_filho_lote": false,
"ativo": true,
"status": "Ativo",
"status_color": "green",
"valido": true,
"created_at": "2025-12-15T10:00:00Z",
"updated_at": "2026-01-10T14:30:00Z"
}
}
Cria um novo cupom de desconto. O código é normalizado para uppercase. Retorna 409 se já existir.
cupons:write
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
codigo
*
|
string | Código que o cliente digita no checkout (case-insensitive, hífens/espaços ignorados). Ex: VERAO50 |
nome
*
|
string | Nome interno do cupom (visível no admin) |
descricao
|
string | Descrição opcional |
tipo
*
|
string | publico | unico | cliente | primeira_compra | indicacao |
tipo_desconto
*
|
string | percentual | valor_fixo | valor_por_passageiro | frete_gratis |
valor_desconto
|
number | Valor do desconto. Em percentual: 0-100. Em valor_fixo: R$. Em valor_por_passageiro: R$ por pax |
valor_maximo_desconto
|
number | Teto do desconto em R$ (útil para percentuais) |
limite_uso_total
|
integer | Quantas vezes o cupom pode ser usado no total (null = ilimitado) |
limite_uso_por_cliente
|
integer | Quantas vezes cada cliente pode usar (null = ilimitado) |
valor_minimo_pedido
|
number | Valor mínimo do pedido para o cupom valer |
data_inicio
|
string | Início da vigência (ISO 8601). null = vale desde já |
data_expiracao
|
string | Fim da vigência (ISO 8601). null = sem expiração |
excursoes_permitidas
|
array | IDs de excursões em que o cupom é válido (null = todas) |
excursoes_excluidas
|
array | IDs de excursões em que o cupom NÃO vale |
categorias_permitidas
|
array | IDs de categorias de passageiro permitidas |
apenas_primeira_compra
|
boolean | Se true, só vale para clientes sem compra anterior |
clientes_permitidos
|
array | IDs de clientes que podem usar (null = todos) |
clientes_bloqueados
|
array | IDs de clientes que NÃO podem usar |
ativo
|
boolean | Cupom ativo (default true) |
Resposta de exemplo
{
"success": true,
"message": "Cupom criado com sucesso.",
"data": {
"id": 42,
"codigo": "VERAO50",
"nome": "Promoção Verão 2026",
"descricao": "Desconto de 15% nas excursões de janeiro e fevereiro",
"tipo": "publico",
"tipo_label": "Público",
"tipo_desconto": "percentual",
"tipo_desconto_label": "Percentual",
"valor_desconto": 15,
"desconto_formatado": "15%",
"valor_maximo_desconto": 300,
"valor_minimo_pedido": 500,
"limite_uso_total": 100,
"limite_uso_por_cliente": 1,
"usos": 27,
"usos_disponiveis": 73,
"usos_progresso": "27\/100",
"data_inicio": "2026-01-01T00:00:00Z",
"data_expiracao": "2026-02-28T23:59:59Z",
"excursoes_permitidas": null,
"excursoes_excluidas": null,
"categorias_permitidas": null,
"apenas_primeira_compra": false,
"clientes_permitidos": null,
"clientes_bloqueados": null,
"cupom_pai_id": null,
"lote_nome": null,
"is_lote": false,
"is_filho_lote": false,
"ativo": true,
"status": "Ativo",
"status_color": "green",
"valido": true,
"created_at": "2025-12-15T10:00:00Z",
"updated_at": "2026-01-10T14:30:00Z"
}
}
Atualiza os campos do cupom. Todos os campos são opcionais (envie apenas os que mudaram).
cupons:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do cupom |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
codigo
|
string | Código que o cliente digita no checkout (case-insensitive, hífens/espaços ignorados). Ex: VERAO50 |
nome
|
string | Nome interno do cupom (visível no admin) |
descricao
|
string | Descrição opcional |
tipo
|
string | publico | unico | cliente | primeira_compra | indicacao |
tipo_desconto
|
string | percentual | valor_fixo | valor_por_passageiro | frete_gratis |
valor_desconto
|
number | Valor do desconto. Em percentual: 0-100. Em valor_fixo: R$. Em valor_por_passageiro: R$ por pax |
valor_maximo_desconto
|
number | Teto do desconto em R$ (útil para percentuais) |
limite_uso_total
|
integer | Quantas vezes o cupom pode ser usado no total (null = ilimitado) |
limite_uso_por_cliente
|
integer | Quantas vezes cada cliente pode usar (null = ilimitado) |
valor_minimo_pedido
|
number | Valor mínimo do pedido para o cupom valer |
data_inicio
|
string | Início da vigência (ISO 8601). null = vale desde já |
data_expiracao
|
string | Fim da vigência (ISO 8601). null = sem expiração |
excursoes_permitidas
|
array | IDs de excursões em que o cupom é válido (null = todas) |
excursoes_excluidas
|
array | IDs de excursões em que o cupom NÃO vale |
categorias_permitidas
|
array | IDs de categorias de passageiro permitidas |
apenas_primeira_compra
|
boolean | Se true, só vale para clientes sem compra anterior |
clientes_permitidos
|
array | IDs de clientes que podem usar (null = todos) |
clientes_bloqueados
|
array | IDs de clientes que NÃO podem usar |
ativo
|
boolean | Cupom ativo (default true) |
Resposta de exemplo
{
"success": true,
"message": "Cupom atualizado com sucesso.",
"data": {
"id": 42,
"codigo": "VERAO50",
"nome": "Promoção Verão 2026",
"descricao": "Desconto de 15% nas excursões de janeiro e fevereiro",
"tipo": "publico",
"tipo_label": "Público",
"tipo_desconto": "percentual",
"tipo_desconto_label": "Percentual",
"valor_desconto": 15,
"desconto_formatado": "15%",
"valor_maximo_desconto": 300,
"valor_minimo_pedido": 500,
"limite_uso_total": 100,
"limite_uso_por_cliente": 1,
"usos": 27,
"usos_disponiveis": 73,
"usos_progresso": "27\/100",
"data_inicio": "2026-01-01T00:00:00Z",
"data_expiracao": "2026-02-28T23:59:59Z",
"excursoes_permitidas": null,
"excursoes_excluidas": null,
"categorias_permitidas": null,
"apenas_primeira_compra": false,
"clientes_permitidos": null,
"clientes_bloqueados": null,
"cupom_pai_id": null,
"lote_nome": null,
"is_lote": false,
"is_filho_lote": false,
"ativo": true,
"status": "Ativo",
"status_color": "green",
"valido": true,
"created_at": "2025-12-15T10:00:00Z",
"updated_at": "2026-01-10T14:30:00Z"
}
}
Inverte o status ativo do cupom (toggle). Útil para pausar/retomar um cupom sem excluí-lo.
cupons:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do cupom |
Resposta de exemplo
{
"success": true,
"message": "Status do cupom atualizado.",
"data": {
"id": 42,
"codigo": "VERAO50",
"nome": "Promoção Verão 2026",
"descricao": "Desconto de 15% nas excursões de janeiro e fevereiro",
"tipo": "publico",
"tipo_label": "Público",
"tipo_desconto": "percentual",
"tipo_desconto_label": "Percentual",
"valor_desconto": 15,
"desconto_formatado": "15%",
"valor_maximo_desconto": 300,
"valor_minimo_pedido": 500,
"limite_uso_total": 100,
"limite_uso_por_cliente": 1,
"usos": 27,
"usos_disponiveis": 73,
"usos_progresso": "27\/100",
"data_inicio": "2026-01-01T00:00:00Z",
"data_expiracao": "2026-02-28T23:59:59Z",
"excursoes_permitidas": null,
"excursoes_excluidas": null,
"categorias_permitidas": null,
"apenas_primeira_compra": false,
"clientes_permitidos": null,
"clientes_bloqueados": null,
"cupom_pai_id": null,
"lote_nome": null,
"is_lote": false,
"is_filho_lote": false,
"ativo": false,
"status": "Ativo",
"status_color": "green",
"valido": true,
"created_at": "2025-12-15T10:00:00Z",
"updated_at": "2026-01-10T14:30:00Z"
}
}
Remove permanentemente o cupom. Retorna 400 se já foi utilizado em alguma reserva (desative-o em vez de excluir).
cupons:delete
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do cupom |
Resposta de exemplo
{
"success": true,
"message": "Cupom excluído com sucesso."
}
Verifica se o código é válido e calcula o desconto. Útil para mostrar o desconto no checkout antes de confirmar. Não consome o cupom.
cupons:validate
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
codigo
*
|
string | Código do cupom (case-insensitive) |
cliente_id
|
integer | ID do cliente (necessário para tipos cliente/primeira_compra/indicacao) |
valor_total
|
number | Valor total do pedido em R$ (para validar valor_minimo_pedido) |
excursao_id
|
integer | ID da excursão (para validar excursoes_permitidas/excluidas) |
quantidade_passageiros
|
integer | Quantidade de passageiros (necessário para tipo_desconto=valor_por_passageiro). Default: 1 |
Resposta de exemplo
{
"success": true,
"message": "Cupom válido.",
"data": {
"success": true,
"cupom": {
"id": 42,
"codigo": "VERAO50",
"nome": "Promoção Verão 2026",
"tipo_desconto": "percentual",
"desconto_formatado": "15%"
},
"desconto": 180,
"desconto_formatado": "R$ 180,00"
}
}
Aplica o cupom em uma reserva existente. Operação atômica com lock no cupom (evita race condition em limite_uso_total). Atualiza valor_total da order, registra CupomUso e incrementa o contador de usos.
cupons:validate
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
orderId
*
|
integer | path | ID da reserva (Order) |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
codigo
*
|
string | Código do cupom |
cliente_id
*
|
integer | ID do cliente comprador |
Resposta de exemplo
{
"success": true,
"message": "Cupom aplicado com sucesso.",
"data": {
"success": true,
"desconto": 180,
"desconto_formatado": "R$ 180,00",
"valor_original": 1200,
"valor_total": 1020
}
}
Remove o cupom aplicado em uma reserva, restaurando o valor_total original. Decrementa o contador de usos.
cupons:validate
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
orderId
*
|
integer | path | ID da reserva |
Resposta de exemplo
{
"success": true,
"message": "Cupom removido com sucesso.",
"data": {
"success": true,
"valor_total": 1200
}
}
Guias
Cadastro de guias e designação em excursões
Lista paginada de guias com filtros.
guias:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
search
|
string | query | Buscar por nome |
ativo
|
boolean | query | Filtrar por ativo |
per_page
|
integer | query | Itens por página |
Resposta de exemplo
{
"success": true,
"data": [
{
"id": 7,
"nome": "Carlos Santos",
"email": "[email protected]",
"cpf": "98765432100",
"telefone": "1144445555",
"celular": "11988887777",
"data_nascimento": "1985-03-20",
"banco": "Itaú",
"agencia": "0001",
"conta": "12345678",
"tipo_conta": "corrente",
"pix": "[email protected]",
"ativo": true,
"created_at": "2024-01-10T09:00:00Z"
}
]
}
Retorna todos os dados do guia.
guias:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID |
Resposta de exemplo
{
"success": true,
"data": {
"id": 7,
"nome": "Carlos Santos",
"email": "[email protected]",
"cpf": "98765432100",
"telefone": "1144445555",
"celular": "11988887777",
"data_nascimento": "1985-03-20",
"banco": "Itaú",
"agencia": "0001",
"conta": "12345678",
"tipo_conta": "corrente",
"pix": "[email protected]",
"ativo": true,
"created_at": "2024-01-10T09:00:00Z"
}
}
Cadastra um novo guia.
guias:write
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
nome
*
|
string | Nome completo |
email
|
string | |
telefone
|
string | Telefone fixo |
celular
|
string | Celular |
cpf
|
string | CPF |
rg
|
string | RG |
data_nascimento
|
date | Nascimento (Y-m-d) |
cep
|
string | CEP |
endereco
|
string | Endereço |
numero
|
string | Número |
complemento
|
string | Complemento |
bairro
|
string | Bairro |
cidade
|
string | Cidade |
estado
|
string | UF |
banco
|
string | Banco (para repasses) |
agencia
|
string | Agência |
conta
|
string | Conta |
tipo_conta
|
string | corrente, poupanca |
pix
|
string | Chave PIX |
observacoes
|
string | Observações |
ativo
|
boolean | Guia ativo (default true) |
Resposta de exemplo
{
"success": true,
"message": "Guia cadastrado com sucesso.",
"data": {
"id": 7,
"nome": "Carlos Santos",
"email": "[email protected]",
"cpf": "98765432100",
"telefone": "1144445555",
"celular": "11988887777",
"data_nascimento": "1985-03-20",
"banco": "Itaú",
"agencia": "0001",
"conta": "12345678",
"tipo_conta": "corrente",
"pix": "[email protected]",
"ativo": true,
"created_at": "2024-01-10T09:00:00Z"
}
}
Atualiza os dados do guia.
guias:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
nome
|
string | Nome completo |
email
|
string | |
telefone
|
string | Telefone fixo |
celular
|
string | Celular |
cpf
|
string | CPF |
rg
|
string | RG |
data_nascimento
|
date | Nascimento (Y-m-d) |
cep
|
string | CEP |
endereco
|
string | Endereço |
numero
|
string | Número |
complemento
|
string | Complemento |
bairro
|
string | Bairro |
cidade
|
string | Cidade |
estado
|
string | UF |
banco
|
string | Banco (para repasses) |
agencia
|
string | Agência |
conta
|
string | Conta |
tipo_conta
|
string | corrente, poupanca |
pix
|
string | Chave PIX |
observacoes
|
string | Observações |
ativo
|
boolean | Guia ativo (default true) |
Resposta de exemplo
{
"success": true,
"message": "Guia atualizado.",
"data": {
"id": 7,
"nome": "Carlos Santos",
"email": "[email protected]",
"cpf": "98765432100",
"telefone": "1144445555",
"celular": "11988887777",
"data_nascimento": "1985-03-20",
"banco": "Itaú",
"agencia": "0001",
"conta": "12345678",
"tipo_conta": "corrente",
"pix": "[email protected]",
"ativo": true,
"created_at": "2024-01-10T09:00:00Z"
}
}
Ativa ou desativa o guia.
guias:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID |
Resposta de exemplo
{
"success": true,
"message": "Status alterado.",
"data": {
"ativo": false
}
}
Remove o guia.
guias:delete
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID |
Resposta de exemplo
{
"success": true,
"message": "Guia excluído."
}
Lista os guias designados para uma excursão.
guias:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
Resposta de exemplo
{
"success": true,
"data": [
{
"id": 51,
"excursao_id": 45,
"guia_id": 7,
"funcao": "guia_principal",
"valor_pagamento": 800,
"guia": {
"id": 7,
"nome": "Carlos Santos",
"email": "[email protected]",
"cpf": "98765432100",
"telefone": "1144445555",
"celular": "11988887777",
"data_nascimento": "1985-03-20",
"banco": "Itaú",
"agencia": "0001",
"conta": "12345678",
"tipo_conta": "corrente",
"pix": "[email protected]",
"ativo": true,
"created_at": "2024-01-10T09:00:00Z"
}
}
]
}
Designa um guia para a excursão.
guias:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
guia_id
*
|
integer | ID do guia |
transporte_id
|
integer | ID do transporte específico (se múltiplos) |
embarque_id
|
integer | ID do embarque |
funcao
*
|
string | guia_principal, guia_auxiliar, monitor |
valor_pagamento
|
number | Valor a pagar ao guia |
observacao
|
string | Observação |
Resposta de exemplo
{
"success": true,
"message": "Guia designado.",
"data": {
"id": 51,
"excursao_id": 45,
"guia_id": 7,
"funcao": "guia_principal"
}
}
Veículos
Cadastro de veículos (ônibus, vans, carros)
Lista veículos com filtros.
veiculos:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
tipo
|
string | query | Tipo do veículo |
transporte_id
|
integer | query | Filtrar pela empresa dona |
ativo
|
boolean | query | Filtrar por ativo |
search
|
string | query | Busca por modelo, placa |
Resposta de exemplo
{
"success": true,
"data": [
{
"id": 5,
"transporte_id": 2,
"tipo": "onibus_leito",
"modelo": "Paradiso 1600 LD",
"placa": "ABC-1234",
"renavam": "12345678901",
"ano_fabricacao": 2019,
"capacidade_total": 46,
"ar_condicionado": true,
"wifi": true,
"banheiro": true,
"tv": true,
"tomadas": true,
"reclinavel": false,
"ativo": true,
"transporte": {
"id": 2,
"nome_fantasia": "Viagens Brasil Express",
"cnpj": "12.345.678\/0001-90"
},
"created_at": "2024-01-05T15:45:00Z"
}
]
}
Lista os tipos aceitos pelo campo tipo.
veiculos:read
Resposta de exemplo
{
"success": true,
"data": [
"van",
"micro_onibus",
"onibus",
"onibus_leito",
"onibus_semileito",
"onibus_executivo",
"onibus_double_decker",
"minivan",
"carro"
]
}
Retorna o veículo com a empresa de transporte.
veiculos:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID |
Resposta de exemplo
{
"success": true,
"data": {
"id": 5,
"transporte_id": 2,
"tipo": "onibus_leito",
"modelo": "Paradiso 1600 LD",
"placa": "ABC-1234",
"renavam": "12345678901",
"ano_fabricacao": 2019,
"capacidade_total": 46,
"ar_condicionado": true,
"wifi": true,
"banheiro": true,
"tv": true,
"tomadas": true,
"reclinavel": false,
"ativo": true,
"transporte": {
"id": 2,
"nome_fantasia": "Viagens Brasil Express",
"cnpj": "12.345.678\/0001-90"
},
"created_at": "2024-01-05T15:45:00Z"
}
}
Cadastra um veículo vinculado a uma empresa de transporte.
veiculos:write
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
transporte_id
*
|
integer | ID da empresa de transporte dona do veículo |
tipo
*
|
string | van, micro_onibus, onibus, onibus_leito, onibus_semileito, onibus_executivo, onibus_double_decker, minivan, carro |
modelo
*
|
string | Modelo (ex: Mercedes-Benz O-500) |
placa
|
string | Placa |
renavam
|
string | RENAVAM |
ano_fabricacao
|
integer | Ano de fabricação |
capacidade_total
*
|
integer | Capacidade de passageiros (>=1) |
ar_condicionado
|
boolean | Tem ar-condicionado |
wifi
|
boolean | Tem Wi-Fi |
banheiro
|
boolean | Tem banheiro |
tv
|
boolean | Tem TV |
tomadas
|
boolean | Tem tomadas |
reclinavel
|
boolean | Assentos reclináveis |
observacoes
|
string | Observações |
ativo
|
boolean | Veículo ativo |
Resposta de exemplo
{
"success": true,
"message": "Veículo criado.",
"data": {
"id": 5,
"transporte_id": 2,
"tipo": "onibus_leito",
"modelo": "Paradiso 1600 LD",
"placa": "ABC-1234",
"renavam": "12345678901",
"ano_fabricacao": 2019,
"capacidade_total": 46,
"ar_condicionado": true,
"wifi": true,
"banheiro": true,
"tv": true,
"tomadas": true,
"reclinavel": false,
"ativo": true,
"transporte": {
"id": 2,
"nome_fantasia": "Viagens Brasil Express",
"cnpj": "12.345.678\/0001-90"
},
"created_at": "2024-01-05T15:45:00Z"
}
}
Atualiza parcialmente o veículo.
veiculos:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
transporte_id
|
integer | ID da empresa de transporte dona do veículo |
tipo
|
string | van, micro_onibus, onibus, onibus_leito, onibus_semileito, onibus_executivo, onibus_double_decker, minivan, carro |
modelo
|
string | Modelo (ex: Mercedes-Benz O-500) |
placa
|
string | Placa |
renavam
|
string | RENAVAM |
ano_fabricacao
|
integer | Ano de fabricação |
capacidade_total
|
integer | Capacidade de passageiros (>=1) |
ar_condicionado
|
boolean | Tem ar-condicionado |
wifi
|
boolean | Tem Wi-Fi |
banheiro
|
boolean | Tem banheiro |
tv
|
boolean | Tem TV |
tomadas
|
boolean | Tem tomadas |
reclinavel
|
boolean | Assentos reclináveis |
observacoes
|
string | Observações |
ativo
|
boolean | Veículo ativo |
Resposta de exemplo
{
"success": true,
"message": "Veículo atualizado.",
"data": {
"id": 5,
"transporte_id": 2,
"tipo": "onibus_leito",
"modelo": "Paradiso 1600 LD",
"placa": "ABC-1234",
"renavam": "12345678901",
"ano_fabricacao": 2019,
"capacidade_total": 46,
"ar_condicionado": true,
"wifi": true,
"banheiro": true,
"tv": true,
"tomadas": true,
"reclinavel": false,
"ativo": true,
"transporte": {
"id": 2,
"nome_fantasia": "Viagens Brasil Express",
"cnpj": "12.345.678\/0001-90"
},
"created_at": "2024-01-05T15:45:00Z"
}
}
Alterna entre ativo e inativo.
veiculos:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID |
Resposta de exemplo
{
"success": true,
"data": {
"ativo": false
}
}
Remove o veículo.
veiculos:delete
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID |
Resposta de exemplo
{
"success": true,
"message": "Veículo excluído."
}
Transportes
Cadastro de empresas de transporte e atribuição em excursões
Lista paginada com filtros.
transportes:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
search
|
string | query | Buscar por nome |
ativo
|
boolean | query | Filtrar por ativo |
Resposta de exemplo
{
"success": true,
"data": [
{
"id": 2,
"nome_fantasia": "Viagens Brasil Express",
"razao_social": "Viagens Brasil Express LTDA",
"cnpj": "12.345.678\/0001-90",
"email": "[email protected]",
"telefone": "1133334444",
"whatsapp": "11999998888",
"cidade": "São Paulo",
"estado": "SP",
"contato_nome": "Pedro Oliveira",
"contato_telefone": "11988887777",
"ativo": true,
"created_at": "2024-01-05T15:45:00Z"
}
]
}
Retorna a empresa com dados completos.
transportes:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID |
Resposta de exemplo
{
"success": true,
"data": {
"id": 2,
"nome_fantasia": "Viagens Brasil Express",
"razao_social": "Viagens Brasil Express LTDA",
"cnpj": "12.345.678\/0001-90",
"email": "[email protected]",
"telefone": "1133334444",
"whatsapp": "11999998888",
"cidade": "São Paulo",
"estado": "SP",
"contato_nome": "Pedro Oliveira",
"contato_telefone": "11988887777",
"ativo": true,
"created_at": "2024-01-05T15:45:00Z"
}
}
Cadastra uma nova empresa de transporte.
transportes:write
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
nome_fantasia
*
|
string | Nome fantasia |
razao_social
|
string | Razão social |
cnpj
|
string | CNPJ |
email
|
string | |
telefone
|
string | Telefone principal |
telefone_secundario
|
string | Telefone alternativo |
whatsapp
|
string | |
site
|
string | Site oficial |
cep
|
string | CEP |
endereco
|
string | Endereço |
numero
|
string | Número |
complemento
|
string | Complemento |
bairro
|
string | Bairro |
cidade
|
string | Cidade |
estado
|
string | UF |
contato_nome
|
string | Pessoa de contato |
contato_telefone
|
string | Telefone do contato |
contato_email
|
string | E-mail do contato |
observacoes
|
string | Observações |
ativo
|
boolean | Empresa ativa |
Resposta de exemplo
{
"success": true,
"message": "Empresa cadastrada.",
"data": {
"id": 2,
"nome_fantasia": "Viagens Brasil Express",
"razao_social": "Viagens Brasil Express LTDA",
"cnpj": "12.345.678\/0001-90",
"email": "[email protected]",
"telefone": "1133334444",
"whatsapp": "11999998888",
"cidade": "São Paulo",
"estado": "SP",
"contato_nome": "Pedro Oliveira",
"contato_telefone": "11988887777",
"ativo": true,
"created_at": "2024-01-05T15:45:00Z"
}
}
Atualiza parcialmente os dados.
transportes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
nome_fantasia
|
string | Nome fantasia |
razao_social
|
string | Razão social |
cnpj
|
string | CNPJ |
email
|
string | |
telefone
|
string | Telefone principal |
telefone_secundario
|
string | Telefone alternativo |
whatsapp
|
string | |
site
|
string | Site oficial |
cep
|
string | CEP |
endereco
|
string | Endereço |
numero
|
string | Número |
complemento
|
string | Complemento |
bairro
|
string | Bairro |
cidade
|
string | Cidade |
estado
|
string | UF |
contato_nome
|
string | Pessoa de contato |
contato_telefone
|
string | Telefone do contato |
contato_email
|
string | E-mail do contato |
observacoes
|
string | Observações |
ativo
|
boolean | Empresa ativa |
Resposta de exemplo
{
"success": true,
"message": "Empresa atualizada.",
"data": {
"id": 2,
"nome_fantasia": "Viagens Brasil Express",
"razao_social": "Viagens Brasil Express LTDA",
"cnpj": "12.345.678\/0001-90",
"email": "[email protected]",
"telefone": "1133334444",
"whatsapp": "11999998888",
"cidade": "São Paulo",
"estado": "SP",
"contato_nome": "Pedro Oliveira",
"contato_telefone": "11988887777",
"ativo": true,
"created_at": "2024-01-05T15:45:00Z"
}
}
Ativa ou desativa a empresa.
transportes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID |
Resposta de exemplo
{
"success": true,
"data": {
"ativo": false
}
}
Remove a empresa.
transportes:delete
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID |
Resposta de exemplo
{
"success": true,
"message": "Empresa excluída."
}
Lista os transportes (veículos + vagas) configurados na excursão.
transportes:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
Resposta de exemplo
{
"success": true,
"data": [
{
"id": 9,
"excursao_id": 45,
"veiculo_id": 5,
"empresa_transporte_id": 2,
"nome": "Ônibus 1",
"numero": "01",
"tipo": "onibus_leito",
"vagas_total": 46,
"vagas_reserva_admin": 2,
"ordem": 0,
"ativo": true,
"veiculo": {
"id": 5,
"modelo": "Paradiso 1600 LD",
"placa": "ABC-1234"
}
}
]
}
Configura um veículo para a excursão com vagas.
transportes:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
veiculo_id
*
|
integer | ID do veículo |
empresa_transporte_id
|
integer | ID da empresa (default do veículo) |
nome
|
string | Nome exibido (ex: "Ônibus 1") |
numero
|
string | Número |
tipo
|
string | onibus, micro_onibus, van, carro, outro |
vagas_total
*
|
integer | Vagas totais (>=1) |
vagas_reserva_admin
|
integer | Vagas reservadas para venda interna |
ordem
|
integer | Ordem de exibição |
ativo
|
boolean | Ativo |
Resposta de exemplo
{
"success": true,
"data": {
"id": 9,
"excursao_id": 45,
"veiculo_id": 5
}
}
Hospedagem
Addon Hospedagem — cadastro de hotéis/pousadas, tipos de quarto, suplementos, vínculo com excursões (allotment + valores) e alocação real de quartos para passageiros e guias. Requer addon `hospedagem` ativo no tenant (403 caso contrário).
Paginada. Filtros opcionais: ativo, tipo, cidade, search.
hospedagem:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
ativo
|
boolean | query | true|false |
tipo
|
string | query | hotel|pousada|resort|hostel|chacara|camping|outro |
cidade
|
string | query | |
search
|
string | query | Busca por nome |
per_page
|
integer | query | Max 100 (default 20) |
Resposta de exemplo
{
"success": true,
"data": [],
"meta": {
"current_page": 1,
"per_page": 20,
"total": 0,
"last_page": 1
}
}
Aceita criação aninhada de `tipos_quarto[]` e `suplementos[]` no mesmo payload.
hospedagem:write
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
nome
*
|
string | |
tipo
*
|
string | hotel|pousada|resort|hostel|chacara|camping|outro |
endereco
|
string | |
cidade
|
string | |
estado
|
string | UF (2 letras) |
cep
|
string | |
telefone
|
string | |
email
|
string | |
website
|
string | URL |
descricao
|
string | |
amenidades
|
array | Ex: ["wifi","piscina","cafe_manha"] |
politica_checkin
|
string | HH:MM |
politica_checkout
|
string | HH:MM |
politica_cancelamento
|
string | |
ativo
|
boolean | |
tipos_quarto
|
array | Array de {nome, capacidade_min, capacidade_max, descricao} |
suplementos
|
array | Array de {nome, tipo, preco_padrao, cobranca} |
Resposta de exemplo
{
"success": true,
"message": "Hospedaria cadastrada com sucesso.",
"data": {
"id": 1
}
}
Detalhes da hospedaria
hospedagem:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da hospedaria |
Resposta de exemplo
{
"success": true,
"data": {
"id": 1,
"nome": "Hotel Madero",
"tipo": "hotel",
"tipos_quarto": [],
"suplementos": []
}
}
Atualizar hospedaria
hospedagem:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da hospedaria |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
nome
|
string | |
tipo
|
string | |
cidade
|
string | |
ativo
|
boolean |
Resposta de exemplo
{
"success": true,
"message": "Hospedaria atualizada."
}
Falha com 422 se houver excursões vinculadas.
hospedagem:delete
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da hospedaria |
Resposta de exemplo
{
"success": true,
"message": "Hospedaria removida."
}
Toggle ativo/inativo
hospedagem:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da hospedaria |
Resposta de exemplo
{
"success": true,
"data": {
"ativo": true
}
}
Listar tipos de quarto
hospedagem:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da hospedaria |
Resposta de exemplo
{
"success": true,
"data": []
}
Criar tipo de quarto
hospedagem:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da hospedaria |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
nome
*
|
string | Ex: Standard Duplo, Suíte Master |
capacidade_min
*
|
integer | Min 1 |
capacidade_max
*
|
integer | Min 1 |
descricao
|
string | |
amenidades
|
array | |
foto_url
|
string | URL |
ordem
|
integer | |
ativo
|
boolean |
Resposta de exemplo
{
"success": true,
"data": {
"id": 5
}
}
Atualizar tipo de quarto
hospedagem:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da hospedaria |
tipoId
*
|
integer | path | ID do tipo |
Resposta de exemplo
{
"success": true
}
Falha com 422 se houver allotment usando este tipo.
hospedagem:delete
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da hospedaria |
tipoId
*
|
integer | path |
Resposta de exemplo
{
"success": true
}
Listar suplementos
hospedagem:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da hospedaria |
Resposta de exemplo
{
"success": true,
"data": []
}
Suplementos são extras (café reforçado, upgrade vista mar, etc) com preço padrão da hospedaria.
hospedagem:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da hospedaria |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
nome
*
|
string | |
tipo
*
|
string | Tipos definidos em Suplemento::TIPOS |
preco_padrao
*
|
number | |
cobranca
*
|
string | por_pessoa|por_quarto|por_noite |
descricao
|
string | |
ativo
|
boolean |
Resposta de exemplo
{
"success": true,
"data": {
"id": 3
}
}
Atualizar suplemento
hospedagem:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da hospedaria |
suplementoId
*
|
integer | path |
Resposta de exemplo
{
"success": true
}
Remover suplemento
hospedagem:delete
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da hospedaria |
suplementoId
*
|
integer | path |
Resposta de exemplo
{
"success": true
}
Listar hospedagens da excursão
hospedagem:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
Resposta de exemplo
{
"success": true,
"data": []
}
Lista hospedarias do tenant que ainda não estão vinculadas à excursão.
hospedagem:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
Resposta de exemplo
{
"success": true,
"data": []
}
Cria o vínculo, opcionalmente com `quartos_disponiveis[]` (allotment) e `suplementos[]` configurados pra essa excursão. Sincroniza custo com módulo financeiro.
hospedagem:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
hospedaria_id
*
|
integer | |
checkin_data
*
|
string | YYYY-MM-DD |
checkout_data
*
|
string | YYYY-MM-DD (após checkin) |
checkin_hora
|
string | HH:MM |
checkout_hora
|
string | HH:MM |
custo_total
|
number | |
observacoes
|
string | |
rooming_list_prazo
|
string | YYYY-MM-DD |
status
|
string | pendente|confirmado|cancelado |
quartos_disponiveis
|
array | Array de {tipo_quarto_id, quantidade, preco_por_pessoa, preco_por_quarto, custo_por_quarto, visivel_checkout} |
suplementos
|
array | Array de {suplemento_id, preco, cobranca, visivel_checkout} |
Resposta de exemplo
{
"success": true,
"data": {
"id": 10
}
}
Atualizar vínculo
hospedagem:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
vinculoId
*
|
integer | path | ID do vínculo excursão-hospedagem |
Resposta de exemplo
{
"success": true
}
Remover vínculo
hospedagem:delete
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
vinculoId
*
|
integer | path | ID do vínculo excursão-hospedagem |
Resposta de exemplo
{
"success": true
}
Retorna os quartos criados (gerados a partir do allotment ou adicionados manualmente) com os hóspedes alocados em cada um.
hospedagem:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
vinculoId
*
|
integer | path | ID do vínculo excursão-hospedagem |
Resposta de exemplo
{
"success": true,
"data": {
"quartos": []
}
}
Adicionar quarto avulso
hospedagem:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
vinculoId
*
|
integer | path | ID do vínculo excursão-hospedagem |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
tipo_quarto_id
*
|
integer | |
numero
|
string | Identificador (ex: 101, Cabine A12) |
observacoes
|
string |
Resposta de exemplo
{
"success": true,
"message": "Quarto adicionado"
}
Atualizar quarto
hospedagem:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
vinculoId
*
|
integer | path | ID do vínculo excursão-hospedagem |
quartoId
*
|
integer | path |
Resposta de exemplo
{
"success": true
}
Falha com 422 se houver hóspedes alocados (desalocar antes).
hospedagem:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
vinculoId
*
|
integer | path | ID do vínculo excursão-hospedagem |
quartoId
*
|
integer | path |
Resposta de exemplo
{
"success": true
}
Cria quartos vazios automaticamente baseado nos `quartos_disponiveis` do vínculo.
hospedagem:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
vinculoId
*
|
integer | path | ID do vínculo excursão-hospedagem |
Resposta de exemplo
{
"success": true
}
Alocar passageiro em quarto
hospedagem:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
vinculoId
*
|
integer | path | ID do vínculo excursão-hospedagem |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
passageiro_id
*
|
integer | ID do ExcursaoPassageiro |
quarto_id
*
|
integer |
Resposta de exemplo
{
"success": true
}
Desalocar passageiro
hospedagem:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
vinculoId
*
|
integer | path | ID do vínculo excursão-hospedagem |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
passageiro_id
*
|
integer |
Resposta de exemplo
{
"success": true,
"message": "Passageiro removido do quarto"
}
Alocar guia em quarto
hospedagem:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
vinculoId
*
|
integer | path | ID do vínculo excursão-hospedagem |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
guia_id
*
|
integer | |
quarto_id
*
|
integer |
Resposta de exemplo
{
"success": true
}
Desalocar guia
hospedagem:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
vinculoId
*
|
integer | path | ID do vínculo excursão-hospedagem |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
guia_id
*
|
integer |
Resposta de exemplo
{
"success": true
}
Distribui passageiros nos quartos automaticamente, respeitando capacidade e separação por gênero/grupo familiar quando aplicável.
hospedagem:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
vinculoId
*
|
integer | path | ID do vínculo excursão-hospedagem |
Resposta de exemplo
{
"success": true
}
Remove todos os passageiros e guias dos quartos. Mantém os quartos criados.
hospedagem:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
vinculoId
*
|
integer | path | ID do vínculo excursão-hospedagem |
Resposta de exemplo
{
"success": true
}
Passageiros sem quarto
hospedagem:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
vinculoId
*
|
integer | path | ID do vínculo excursão-hospedagem |
Resposta de exemplo
{
"success": true,
"data": {
"passageiros": []
}
}
Guias sem quarto
hospedagem:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
excursaoId
*
|
integer | path | ID da excursão |
vinculoId
*
|
integer | path | ID do vínculo excursão-hospedagem |
Resposta de exemplo
{
"success": true,
"data": {
"guias": []
}
}
Ingressos
Addon Ingressos — cadastro de atrações/eventos, categorias (tipos de ingresso com preço custo/venda), controle de estoque por data e vendas. Requer addon `ingressos` ativo no tenant (403 caso contrário).
Paginada. Filtros: ativo, cidade, search, data_min, data_max.
ingressos:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
ativo
|
boolean | query | |
cidade
|
string | query | |
search
|
string | query | Busca por nome |
data_min
|
string | query | Data evento mínima YYYY-MM-DD |
data_max
|
string | query | Data evento máxima YYYY-MM-DD |
per_page
|
integer | query | Max 100 (default 20) |
Resposta de exemplo
{
"success": true,
"data": [],
"meta": {
"total": 0
}
}
Quando `tipo_venda=direta` (default), `categorias[]` é obrigatório. Quando `tipo_venda=afiliado`, `website` é obrigatório e categorias podem ser omitidas.
ingressos:write
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
nome
*
|
string | |
descricao
|
string | |
local
|
string | |
cidade
|
string | |
estado
|
string | UF (2 letras) |
website
|
string | URL — obrigatório se tipo_venda=afiliado |
imagem_url
|
string | URL |
data_evento
|
string | YYYY-MM-DD (não pode ser passado) |
hora_evento
|
string | HH:MM |
quantidade_total
|
integer | |
quantidade_limite_venda
|
integer | |
ativo
|
boolean | |
destaque
|
boolean | |
tipo_venda
|
string | direta (default) | afiliado |
categorias
|
array | Array de {nome, descricao, idade_min, idade_max, preco_custo, preco_venda}. Obrigatório se tipo_venda=direta |
Resposta de exemplo
{
"success": true,
"message": "Ingresso cadastrado.",
"data": {
"id": 1
}
}
Detalhes do ingresso
ingressos:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do ingresso |
Resposta de exemplo
{
"success": true,
"data": {
"id": 1,
"nome": "Show da banda X",
"categorias": []
}
}
Atualizar ingresso
ingressos:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do ingresso |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
nome
|
string | |
descricao
|
string | |
ativo
|
boolean | |
destaque
|
boolean |
Resposta de exemplo
{
"success": true,
"message": "Ingresso atualizado."
}
Falha com 422 se houver vendas registradas.
ingressos:delete
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do ingresso |
Resposta de exemplo
{
"success": true
}
Toggle ativo/inativo
ingressos:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do ingresso |
Resposta de exemplo
{
"success": true,
"data": {
"ativo": true
}
}
Listar categorias
ingressos:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do ingresso |
Resposta de exemplo
{
"success": true,
"data": []
}
Ex: Inteira, Meia, Idoso, Estudante. Cada categoria tem preço de custo e venda.
ingressos:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do ingresso |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
nome
*
|
string | Ex: Inteira, Meia, Idoso |
descricao
|
string | |
idade_min
|
integer | |
idade_max
|
integer | |
preco_custo
*
|
number | |
preco_venda
*
|
number | |
ativo
|
boolean | |
ordem
|
integer |
Resposta de exemplo
{
"success": true,
"data": {
"id": 1
}
}
Atualizar categoria
ingressos:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do ingresso |
categoriaId
*
|
integer | path |
Resposta de exemplo
{
"success": true
}
Remover categoria
ingressos:delete
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do ingresso |
categoriaId
*
|
integer | path |
Resposta de exemplo
{
"success": true
}
Listar estoque por data
ingressos:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do ingresso |
data_min
|
string | query | YYYY-MM-DD |
data_max
|
string | query | YYYY-MM-DD |
Resposta de exemplo
{
"success": true,
"data": []
}
Upsert por (ingresso_id, data). Para alterar várias datas chame múltiplas vezes.
ingressos:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do ingresso |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
data
*
|
string | YYYY-MM-DD |
quantidade_total
*
|
integer | Estoque total para essa data |
disponivel
|
boolean | Liga/desliga venda nessa data |
Resposta de exemplo
{
"success": true,
"message": "Estoque atualizado."
}
Paginada. Filtros: ingresso_id, status, data_min, data_max.
ingressos:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
ingresso_id
|
integer | query | |
status
|
string | query | pendente|pago|cancelado|usado |
data_min
|
string | query | YYYY-MM-DD |
data_max
|
string | query | YYYY-MM-DD |
per_page
|
integer | query |
Resposta de exemplo
{
"success": true,
"data": []
}
Registra venda manualmente (ex: vendido no balcão). `valor_total` é calculado automaticamente como `quantidade * valor_unitario - desconto`.
ingressos:write
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
ingresso_id
*
|
integer | |
categoria_id
*
|
integer | |
cliente_id
|
integer | Se cliente já cadastrado |
comprador_nome
*
|
string | |
comprador_cpf
|
string | |
comprador_email
|
string | |
comprador_telefone
|
string | |
quantidade
*
|
integer | Min 1 |
valor_unitario
*
|
number | |
desconto
|
number | Default 0 |
forma_pagamento
|
string | pix|dinheiro|cartao|... |
data_uso
|
string | YYYY-MM-DD |
observacoes
|
string | |
status
|
string | pendente (default) | pago | cancelado | usado |
Resposta de exemplo
{
"success": true,
"message": "Venda registrada.",
"data": {
"id": 100
}
}
Detalhes da venda
ingressos:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da venda |
Resposta de exemplo
{
"success": true,
"data": {
"id": 100,
"status": "pago"
}
}
Atualizar status da venda
ingressos:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
status
*
|
string | pendente | pago | cancelado | usado |
Resposta de exemplo
{
"success": true
}
Experiências
Módulo de Experiências Turísticas (passeios): catálogo com categorias, horários, extras, temporadas e fotos, além das vendas com voucher por pessoa e check-in individual. Requer o addon passeios-experiencias ativo no tenant.
Lista paginada do catálogo, com a contagem de categorias, horários, extras e vendas de cada passeio.
passeios:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
page
|
integer | query | Número da página |
per_page
|
integer | query | Itens por página (max: 100) |
ativo
|
boolean | query | Filtra por disponível para venda |
destaque
|
boolean | query | Somente destacados |
mostrar_site
|
boolean | query | Somente os publicados no site |
status
|
string | query | rascunho ou publicado |
cidade
|
string | query | Busca parcial por cidade |
estado
|
string | query | UF exata |
pais
|
string | query | País exato |
categoria_tipo
|
string | query | Tipo do passeio |
dificuldade
|
string | query | Nível de dificuldade |
search
|
string | query | Busca em nome, descrição curta e local |
include
|
string | query | Sub-recursos no mesmo payload: categorias, horarios, extras, temporadas, fotos (separados por vírgula) |
Resposta de exemplo
{
"success": true,
"data": [
{
"id": 12,
"nome": "Trilha da Pedra Bonita ao amanhecer",
"slug": "trilha-pedra-bonita-amanhecer",
"descricao_curta": "Subida guiada com vista para a Barra da Tijuca.",
"local": "Parque Nacional da Tijuca",
"cidade": "Rio de Janeiro",
"estado": "RJ",
"pais": "Brasil",
"ponto_encontro": "Estacionamento da Pedra Bonita",
"latitude": -22.9871234,
"longitude": -43.2812345,
"duracao_minutos": 180,
"dificuldade": "moderado",
"idade_minima": 12,
"capacidade_maxima": 20,
"antecedencia_minima_horas": 12,
"cancelamento_horas": 24,
"reembolso_percentual": 100,
"exigir_waiver": true,
"mostrar_site": true,
"ativo": true,
"status": "publicado",
"categorias_count": 2,
"horarios_count": 3,
"extras_count": 1,
"vendas_count": 47
}
]
}
Retorna o passeio com categorias, horários, extras, temporadas e fotos já carregados.
passeios:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do passeio |
Resposta de exemplo
{
"success": true,
"data": {
"id": 12,
"nome": "Trilha da Pedra Bonita ao amanhecer",
"slug": "trilha-pedra-bonita-amanhecer",
"descricao_curta": "Subida guiada com vista para a Barra da Tijuca.",
"local": "Parque Nacional da Tijuca",
"cidade": "Rio de Janeiro",
"estado": "RJ",
"pais": "Brasil",
"ponto_encontro": "Estacionamento da Pedra Bonita",
"latitude": -22.9871234,
"longitude": -43.2812345,
"duracao_minutos": 180,
"dificuldade": "moderado",
"idade_minima": 12,
"capacidade_maxima": 20,
"antecedencia_minima_horas": 12,
"cancelamento_horas": 24,
"reembolso_percentual": 100,
"exigir_waiver": true,
"mostrar_site": true,
"ativo": true,
"status": "publicado",
"categorias_count": 2,
"horarios_count": 3,
"extras_count": 1,
"vendas_count": 47,
"categorias": [
{
"id": 30,
"passeio_id": 12,
"nome": "Adulto",
"descricao": "A partir de 12 anos",
"preco_custo": 40,
"preco_venda": 120,
"idade_min": 12,
"idade_max": null,
"conta_como": "pessoa",
"estoque_consome": 1,
"ativo": true,
"ordem": 0
}
]
}
}
Cria um passeio. Aceita as categorias no mesmo payload, porque passeio sem categoria não vende. O slug é gerado a partir do nome quando não informado.
passeios:write
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
nome
*
|
string | Nome do passeio |
slug
|
string | URL amigável. Gerado a partir do nome quando omitido. Único por tenant |
descricao
|
string | Descrição completa (HTML permitido) |
descricao_curta
|
string | Resumo usado em listagens e cards |
o_que_inclui
|
string | O que está incluído no valor |
o_que_nao_inclui
|
string | O que não está incluído |
o_que_levar
|
string | Itens que o cliente deve levar |
dicas
|
string | Dicas para o participante |
requisitos
|
string | Requisitos de saúde, físicos ou documentais |
local
|
string | Local do passeio |
endereco
|
string | Endereço completo |
cidade
|
string | Cidade |
estado
|
string | UF (2 letras) |
pais
|
string | País |
continente
|
string | Continente |
destino_slug
|
string | Slug do destino, para agrupar passeios da mesma região |
ponto_encontro
|
string | Onde o grupo se encontra |
ponto_encontro_maps
|
string | Link do Google Maps do ponto de encontro |
latitude
|
number | Latitude (-90 a 90) |
longitude
|
number | Longitude (-180 a 180) |
imagem
|
string | URL da imagem de capa |
videos
|
array | Lista de URLs de vídeo |
duracao_minutos
|
integer | Duração em minutos |
dificuldade
|
string | Nível de dificuldade (facil, moderado, dificil) |
idade_minima
|
integer | Idade mínima permitida |
capacidade_maxima
|
integer | Capacidade máxima por saída |
categoria_tipo
|
string | Tipo do passeio (aventura, cultural, gastronomico...) |
antecedencia_minima_horas
|
integer | Antecedência mínima para reservar |
cancelamento_horas
|
integer | Prazo em horas para cancelar com reembolso |
reembolso_percentual
|
integer | Percentual reembolsado dentro do prazo (0 a 100) |
permitir_reagendamento
|
boolean | Permite remarcar a data |
exigir_waiver
|
boolean | Exige termo de responsabilidade assinado |
mostrar_site
|
boolean | Aparece no site público |
ativo
|
boolean | Disponível para venda (default true) |
destaque
|
boolean | Destacado nas listagens |
status
|
string | rascunho ou publicado |
banner_display_mode
|
string | Como a capa é exibida no site |
meta_title
|
string | Título para SEO |
meta_description
|
string | Descrição para SEO |
meta_keywords
|
string | Palavras-chave para SEO |
observacoes_internas
|
string | Notas internas, não exibidas ao cliente |
preco_display_modo
|
string | Como o preço aparece no site |
preco_display_intervalo
|
boolean | Exibe faixa de preço em vez de valor único |
modo_preco
|
string | Modo de precificação |
seguro_link
|
string | Link da apólice de seguro |
seguro_label
|
string | Texto do botão de seguro |
badge_sazonalidade
|
string | Selo de sazonalidade exibido no card |
tags_categorias
|
array | Tags livres de categorização |
import_source
|
string | Origem, quando importado de outro sistema |
import_external_id
|
string | ID no sistema de origem |
categorias
|
array | Categorias criadas junto com o passeio (apenas no POST). Cada item aceita nome, preco_venda, preco_custo, idade_min, idade_max, conta_como, ordem |
Resposta de exemplo
{
"success": true,
"message": "Passeio criado com sucesso",
"data": {
"id": 12,
"nome": "Trilha da Pedra Bonita ao amanhecer",
"slug": "trilha-pedra-bonita-amanhecer",
"descricao_curta": "Subida guiada com vista para a Barra da Tijuca.",
"local": "Parque Nacional da Tijuca",
"cidade": "Rio de Janeiro",
"estado": "RJ",
"pais": "Brasil",
"ponto_encontro": "Estacionamento da Pedra Bonita",
"latitude": -22.9871234,
"longitude": -43.2812345,
"duracao_minutos": 180,
"dificuldade": "moderado",
"idade_minima": 12,
"capacidade_maxima": 20,
"antecedencia_minima_horas": 12,
"cancelamento_horas": 24,
"reembolso_percentual": 100,
"exigir_waiver": true,
"mostrar_site": true,
"ativo": true,
"status": "publicado",
"categorias_count": 2,
"horarios_count": 3,
"extras_count": 1,
"vendas_count": 47
}
}
Atualização parcial: envie apenas os campos que quer mudar.
passeios:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do passeio |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
nome
|
string | Nome do passeio |
slug
|
string | URL amigável. Gerado a partir do nome quando omitido. Único por tenant |
descricao
|
string | Descrição completa (HTML permitido) |
descricao_curta
|
string | Resumo usado em listagens e cards |
o_que_inclui
|
string | O que está incluído no valor |
o_que_nao_inclui
|
string | O que não está incluído |
o_que_levar
|
string | Itens que o cliente deve levar |
dicas
|
string | Dicas para o participante |
requisitos
|
string | Requisitos de saúde, físicos ou documentais |
local
|
string | Local do passeio |
endereco
|
string | Endereço completo |
cidade
|
string | Cidade |
estado
|
string | UF (2 letras) |
pais
|
string | País |
continente
|
string | Continente |
destino_slug
|
string | Slug do destino, para agrupar passeios da mesma região |
ponto_encontro
|
string | Onde o grupo se encontra |
ponto_encontro_maps
|
string | Link do Google Maps do ponto de encontro |
latitude
|
number | Latitude (-90 a 90) |
longitude
|
number | Longitude (-180 a 180) |
imagem
|
string | URL da imagem de capa |
videos
|
array | Lista de URLs de vídeo |
duracao_minutos
|
integer | Duração em minutos |
dificuldade
|
string | Nível de dificuldade (facil, moderado, dificil) |
idade_minima
|
integer | Idade mínima permitida |
capacidade_maxima
|
integer | Capacidade máxima por saída |
categoria_tipo
|
string | Tipo do passeio (aventura, cultural, gastronomico...) |
antecedencia_minima_horas
|
integer | Antecedência mínima para reservar |
cancelamento_horas
|
integer | Prazo em horas para cancelar com reembolso |
reembolso_percentual
|
integer | Percentual reembolsado dentro do prazo (0 a 100) |
permitir_reagendamento
|
boolean | Permite remarcar a data |
exigir_waiver
|
boolean | Exige termo de responsabilidade assinado |
mostrar_site
|
boolean | Aparece no site público |
ativo
|
boolean | Disponível para venda (default true) |
destaque
|
boolean | Destacado nas listagens |
status
|
string | rascunho ou publicado |
banner_display_mode
|
string | Como a capa é exibida no site |
meta_title
|
string | Título para SEO |
meta_description
|
string | Descrição para SEO |
meta_keywords
|
string | Palavras-chave para SEO |
observacoes_internas
|
string | Notas internas, não exibidas ao cliente |
preco_display_modo
|
string | Como o preço aparece no site |
preco_display_intervalo
|
boolean | Exibe faixa de preço em vez de valor único |
modo_preco
|
string | Modo de precificação |
seguro_link
|
string | Link da apólice de seguro |
seguro_label
|
string | Texto do botão de seguro |
badge_sazonalidade
|
string | Selo de sazonalidade exibido no card |
tags_categorias
|
array | Tags livres de categorização |
import_source
|
string | Origem, quando importado de outro sistema |
import_external_id
|
string | ID no sistema de origem |
categorias
|
array | Categorias criadas junto com o passeio (apenas no POST). Cada item aceita nome, preco_venda, preco_custo, idade_min, idade_max, conta_como, ordem |
Resposta de exemplo
{
"success": true,
"message": "Passeio atualizado com sucesso",
"data": {
"id": 12,
"nome": "Trilha da Pedra Bonita ao amanhecer",
"slug": "trilha-pedra-bonita-amanhecer",
"descricao_curta": "Subida guiada com vista para a Barra da Tijuca.",
"local": "Parque Nacional da Tijuca",
"cidade": "Rio de Janeiro",
"estado": "RJ",
"pais": "Brasil",
"ponto_encontro": "Estacionamento da Pedra Bonita",
"latitude": -22.9871234,
"longitude": -43.2812345,
"duracao_minutos": 180,
"dificuldade": "moderado",
"idade_minima": 12,
"capacidade_maxima": 20,
"antecedencia_minima_horas": 12,
"cancelamento_horas": 24,
"reembolso_percentual": 100,
"exigir_waiver": true,
"mostrar_site": true,
"ativo": true,
"status": "publicado",
"categorias_count": 2,
"horarios_count": 3,
"extras_count": 1,
"vendas_count": 47
}
}
Atalho para mudar ativo, mostrar_site, destaque ou status sem enviar o cadastro inteiro.
passeios:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do passeio |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
ativo
|
boolean | Disponível para venda |
mostrar_site
|
boolean | Aparece no site |
destaque
|
boolean | Destacado |
status
|
string | rascunho ou publicado |
Resposta de exemplo
{
"success": true,
"message": "Status atualizado"
}
Remove o passeio e seus sub-recursos. Bloqueado com 422 quando já há vendas registradas (PASSEIO_COM_VENDAS): nesse caso use ativo=false, que tira da venda sem apagar histórico.
passeios:delete
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do passeio |
Resposta de exemplo
{
"success": true,
"message": "Passeio removido com sucesso"
}
Tipos de bilhete do passeio (Adulto, Criança, Meia), com preço de custo e de venda.
passeios:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do passeio |
Resposta de exemplo
{
"success": true,
"data": [
{
"id": 30,
"passeio_id": 12,
"nome": "Adulto",
"descricao": "A partir de 12 anos",
"preco_custo": 40,
"preco_venda": 120,
"idade_min": 12,
"idade_max": null,
"conta_como": "pessoa",
"estoque_consome": 1,
"ativo": true,
"ordem": 0
}
]
}
Tipos de bilhete do passeio (Adulto, Criança, Meia), com preço de custo e de venda.
passeios:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do passeio |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
nome
*
|
string | Nome da categoria (Adulto, Criança, Meia...) |
descricao
|
string | Detalhamento da regra |
preco_venda
*
|
number | Valor cobrado do cliente |
preco_custo
|
number | Custo do fornecedor, usado no cálculo de lucro |
idade_min
|
integer | Idade mínima |
idade_max
|
integer | Idade máxima |
conta_como
|
string | Como conta na capacidade (pessoa, meia, cortesia) |
estoque_id
|
integer | Estoque compartilhado, quando houver |
estoque_consome
|
integer | Quantas vagas cada unidade consome |
ativo
|
boolean | Disponível para venda |
ordem
|
integer | Ordem de exibição |
Resposta de exemplo
{
"success": true,
"message": "Categoria criada com sucesso",
"data": {
"id": 30,
"passeio_id": 12,
"nome": "Adulto",
"descricao": "A partir de 12 anos",
"preco_custo": 40,
"preco_venda": 120,
"idade_min": 12,
"idade_max": null,
"conta_como": "pessoa",
"estoque_consome": 1,
"ativo": true,
"ordem": 0
}
}
Atualização parcial: envie apenas os campos que quer mudar.
passeios:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do passeio |
categoriaId
*
|
integer | path | ID da categoria |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
nome
|
string | Nome da categoria (Adulto, Criança, Meia...) |
descricao
|
string | Detalhamento da regra |
preco_venda
|
number | Valor cobrado do cliente |
preco_custo
|
number | Custo do fornecedor, usado no cálculo de lucro |
idade_min
|
integer | Idade mínima |
idade_max
|
integer | Idade máxima |
conta_como
|
string | Como conta na capacidade (pessoa, meia, cortesia) |
estoque_id
|
integer | Estoque compartilhado, quando houver |
estoque_consome
|
integer | Quantas vagas cada unidade consome |
ativo
|
boolean | Disponível para venda |
ordem
|
integer | Ordem de exibição |
Resposta de exemplo
{
"success": true,
"message": "Categoria atualizada com sucesso"
}
Bloqueado com 422 quando a categoria já tem vendas (RECURSO_EM_USO): nesse caso use ativo=false.
passeios:delete
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do passeio |
categoriaId
*
|
integer | path | ID da categoria |
Resposta de exemplo
{
"success": true,
"message": "Categoria removida com sucesso"
}
Grade de saídas: recorrente por dia da semana, diária ou em data específica.
passeios:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do passeio |
Resposta de exemplo
{
"success": true,
"data": [
{
"id": 55,
"passeio_id": 12,
"tipo_recorrencia": "semanal",
"dias_semana": [
6,
0
],
"horario_inicio": "05:30",
"horario_fim": "08:30",
"vagas": 20,
"ativo": true
}
]
}
Grade de saídas: recorrente por dia da semana, diária ou em data específica.
passeios:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do passeio |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
tipo_recorrencia
*
|
string | semanal, diario ou data_especifica |
dias_semana
|
array | Dias da semana quando semanal (0=domingo a 6=sábado) |
data_especifica
|
date | Data única quando tipo_recorrencia=data_especifica |
horario_inicio
*
|
string | Hora de início (HH:MM) |
horario_fim
|
string | Hora de término (HH:MM) |
vagas
|
integer | Vagas desta saída. Sem valor usa a capacidade do passeio |
vigencia_inicio
|
date | A partir de quando a grade vale |
vigencia_fim
|
date | Até quando a grade vale |
ativo
|
boolean | Horário ativo |
Resposta de exemplo
{
"success": true,
"message": "Horário criada com sucesso",
"data": {
"id": 55,
"passeio_id": 12,
"tipo_recorrencia": "semanal",
"dias_semana": [
6,
0
],
"horario_inicio": "05:30",
"horario_fim": "08:30",
"vagas": 20,
"ativo": true
}
}
Atualização parcial: envie apenas os campos que quer mudar.
passeios:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do passeio |
horarioId
*
|
integer | path | ID da horario |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
tipo_recorrencia
|
string | semanal, diario ou data_especifica |
dias_semana
|
array | Dias da semana quando semanal (0=domingo a 6=sábado) |
data_especifica
|
date | Data única quando tipo_recorrencia=data_especifica |
horario_inicio
|
string | Hora de início (HH:MM) |
horario_fim
|
string | Hora de término (HH:MM) |
vagas
|
integer | Vagas desta saída. Sem valor usa a capacidade do passeio |
vigencia_inicio
|
date | A partir de quando a grade vale |
vigencia_fim
|
date | Até quando a grade vale |
ativo
|
boolean | Horário ativo |
Resposta de exemplo
{
"success": true,
"message": "Horário atualizada com sucesso"
}
Remove o registro.
passeios:delete
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do passeio |
horarioId
*
|
integer | path | ID da horario |
Resposta de exemplo
{
"success": true,
"message": "Horário removida com sucesso"
}
Itens opcionais vendidos junto com o passeio.
passeios:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do passeio |
Resposta de exemplo
{
"success": true,
"data": [
{
"id": 8,
"passeio_id": 12,
"nome": "Transfer hotel",
"preco": 30,
"tipo_cobranca": "por_pessoa",
"quantidade_maxima": 4,
"ativo": true,
"ordem": 0
}
]
}
Itens opcionais vendidos junto com o passeio.
passeios:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do passeio |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
nome
*
|
string | Nome do item opcional (transfer, almoço, foto) |
descricao
|
string | Detalhamento |
preco
*
|
number | Valor do extra |
tipo_cobranca
|
string | por_pessoa ou por_reserva |
quantidade_maxima
|
integer | Limite por reserva |
ativo
|
boolean | Disponível |
ordem
|
integer | Ordem de exibição |
Resposta de exemplo
{
"success": true,
"message": "Extra criada com sucesso",
"data": {
"id": 8,
"passeio_id": 12,
"nome": "Transfer hotel",
"preco": 30,
"tipo_cobranca": "por_pessoa",
"quantidade_maxima": 4,
"ativo": true,
"ordem": 0
}
}
Atualização parcial: envie apenas os campos que quer mudar.
passeios:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do passeio |
extraId
*
|
integer | path | ID da extra |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
nome
|
string | Nome do item opcional (transfer, almoço, foto) |
descricao
|
string | Detalhamento |
preco
|
number | Valor do extra |
tipo_cobranca
|
string | por_pessoa ou por_reserva |
quantidade_maxima
|
integer | Limite por reserva |
ativo
|
boolean | Disponível |
ordem
|
integer | Ordem de exibição |
Resposta de exemplo
{
"success": true,
"message": "Extra atualizada com sucesso"
}
Remove o registro.
passeios:delete
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do passeio |
extraId
*
|
integer | path | ID da extra |
Resposta de exemplo
{
"success": true,
"message": "Extra removida com sucesso"
}
Ajuste de preço por período. Quando dois períodos se sobrepõem, vence a maior prioridade.
passeios:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do passeio |
Resposta de exemplo
{
"success": true,
"data": [
{
"id": 3,
"passeio_id": 12,
"nome": "Alta temporada",
"data_inicio": "2026-12-20",
"data_fim": "2027-01-31",
"tipo_ajuste": "percentual",
"valor_ajuste": 20,
"prioridade": 1,
"ativo": true
}
]
}
Ajuste de preço por período. Quando dois períodos se sobrepõem, vence a maior prioridade.
passeios:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do passeio |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
nome
*
|
string | Nome do período (Alta temporada, Feriado) |
data_inicio
*
|
date | Início do período |
data_fim
*
|
date | Fim do período |
tipo_ajuste
*
|
string | percentual, valor_fixo ou preco_fixo |
valor_ajuste
*
|
number | Valor do ajuste conforme o tipo |
prioridade
|
integer | Quando dois períodos se sobrepõem, vence a maior prioridade |
ativo
|
boolean | Temporada ativa |
Resposta de exemplo
{
"success": true,
"message": "Temporada criada com sucesso",
"data": {
"id": 3,
"passeio_id": 12,
"nome": "Alta temporada",
"data_inicio": "2026-12-20",
"data_fim": "2027-01-31",
"tipo_ajuste": "percentual",
"valor_ajuste": 20,
"prioridade": 1,
"ativo": true
}
}
Atualização parcial: envie apenas os campos que quer mudar.
passeios:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do passeio |
temporadaId
*
|
integer | path | ID da temporada |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
nome
|
string | Nome do período (Alta temporada, Feriado) |
data_inicio
|
date | Início do período |
data_fim
|
date | Fim do período |
tipo_ajuste
|
string | percentual, valor_fixo ou preco_fixo |
valor_ajuste
|
number | Valor do ajuste conforme o tipo |
prioridade
|
integer | Quando dois períodos se sobrepõem, vence a maior prioridade |
ativo
|
boolean | Temporada ativa |
Resposta de exemplo
{
"success": true,
"message": "Temporada atualizada com sucesso"
}
Remove o registro.
passeios:delete
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do passeio |
temporadaId
*
|
integer | path | ID da temporada |
Resposta de exemplo
{
"success": true,
"message": "Temporada removida com sucesso"
}
Galeria do passeio, na ordem de exibição.
passeios:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do passeio |
Resposta de exemplo
{
"success": true,
"data": [
{
"id": 71,
"passeio_id": 12,
"url": "https:\/\/cdn.exemplo.com\/foto.jpg",
"titulo": "Vista do topo",
"ordem": 0
}
]
}
Adiciona uma foto por URL. O arquivo deve estar hospedado pelo integrador.
passeios:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do passeio |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
url
*
|
string | URL da imagem |
thumbnail_url
|
string | URL da miniatura |
titulo
|
string | Título da foto |
descricao
|
string | Legenda |
ordem
|
integer | Ordem de exibição |
Resposta de exemplo
{
"success": true,
"message": "Foto criada com sucesso"
}
Remove a foto da galeria.
passeios:delete
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do passeio |
fotoId
*
|
integer | path | ID da foto |
Resposta de exemplo
{
"success": true,
"message": "Foto removida com sucesso"
}
Lista paginada das vendas, com passeio, categoria, cliente e a contagem de itens do voucher.
passeios:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
page
|
integer | query | Número da página |
per_page
|
integer | query | Itens por página (max: 100) |
passeio_id
|
integer | query | Filtra por passeio |
cliente_id
|
integer | query | Filtra por cliente |
sessao_id
|
integer | query | Filtra por sessão |
status
|
string | query | reservado, confirmado, usado ou cancelado |
checked_in
|
boolean | query | Somente com ou sem check-in |
origem
|
string | query | Canal da venda |
codigo_voucher
|
string | query | Código do voucher da venda (case-insensitive) |
data_de
|
date | query | Data inicial da sessão |
data_ate
|
date | query | Data final da sessão |
search
|
string | query | Busca por nome ou documento do beneficiário |
Resposta de exemplo
{
"success": true,
"data": [
{
"id": 508,
"uuid": "3f1c0a2e-8b4d-4f6a-9c11-2d7e5a9b0c33",
"passeio_id": 12,
"categoria_id": 30,
"cliente_id": 91,
"beneficiario_nome": "Marina Torres",
"beneficiario_documento": "123.456.789-00",
"quantidade": 2,
"valor_unitario": 120,
"valor_extras": 30,
"desconto": 0,
"valor_total": 270,
"status": "confirmado",
"codigo_voucher": "K7PJ4RQ2",
"checked_in": false,
"origem": "api",
"voucher_items_count": 2
}
]
}
Retorna a venda com os itens do voucher, os pagamentos e os check-ins.
passeios:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da venda |
Resposta de exemplo
{
"success": true,
"data": {
"id": 508,
"uuid": "3f1c0a2e-8b4d-4f6a-9c11-2d7e5a9b0c33",
"passeio_id": 12,
"categoria_id": 30,
"cliente_id": 91,
"beneficiario_nome": "Marina Torres",
"beneficiario_documento": "123.456.789-00",
"quantidade": 2,
"valor_unitario": 120,
"valor_extras": 30,
"desconto": 0,
"valor_total": 270,
"status": "confirmado",
"codigo_voucher": "K7PJ4RQ2",
"checked_in": false,
"origem": "api",
"voucher_items_count": 2,
"voucher_items": [
{
"id": 1044,
"passeio_venda_id": 508,
"categoria_nome": "Adulto",
"numero_item": 1,
"codigo_qrcode": "K7PJ4RQ2-01",
"beneficiario_nome": "Marina Torres",
"status": "valido",
"usado_em": null
}
]
}
}
Registra uma venda e gera o código do voucher. Sem valor_unitario, usa o preco_venda da categoria, para o integrador não precisar replicar a tabela de preços. Recusa com 422 quando a categoria não pertence ao passeio (CATEGORIA_DE_OUTRO_PASSEIO) ou quando o desconto deixa o total negativo (TOTAL_NEGATIVO).
passeios:write
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
passeio_id
*
|
integer | ID do passeio |
categoria_id
*
|
integer | ID da categoria. Precisa pertencer ao passeio informado |
sessao_id
|
integer | Sessão (data e hora) escolhida |
cliente_id
|
integer | Cliente cadastrado, quando houver |
beneficiario_nome
*
|
string | Nome de quem vai fazer o passeio |
beneficiario_documento
|
string | CPF ou documento |
beneficiario_telefone
|
string | Telefone de contato |
quantidade
*
|
integer | Quantidade de pessoas. Gera um item de voucher para cada |
valor_unitario
|
number | Valor por pessoa. Sem valor, usa o preco_venda da categoria |
valor_custo
|
number | Custo por pessoa. Sem valor, usa o preco_custo da categoria |
valor_extras
|
number | Soma dos extras |
extras
|
array | Extras escolhidos |
desconto
|
number | Desconto aplicado |
desconto_motivo
|
string | Motivo do desconto |
acrescimo
|
number | Acréscimo aplicado |
acrescimo_motivo
|
string | Motivo do acréscimo |
status
|
string | reservado (default), confirmado, usado ou cancelado |
origem
|
string | Canal da venda. Default: api |
campos_customizados
|
object | Campos livres do integrador |
Resposta de exemplo
{
"success": true,
"message": "Venda registrada com sucesso",
"data": {
"id": 508,
"uuid": "3f1c0a2e-8b4d-4f6a-9c11-2d7e5a9b0c33",
"passeio_id": 12,
"categoria_id": 30,
"cliente_id": 91,
"beneficiario_nome": "Marina Torres",
"beneficiario_documento": "123.456.789-00",
"quantidade": 2,
"valor_unitario": 120,
"valor_extras": 30,
"desconto": 0,
"valor_total": 270,
"status": "confirmado",
"codigo_voucher": "K7PJ4RQ2",
"checked_in": false,
"origem": "api",
"voucher_items_count": 2
}
}
Atualiza dados do beneficiário, extras e valores. Não muda status: use o endpoint próprio. Venda cancelada não pode ser editada (VENDA_CANCELADA).
passeios:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da venda |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
beneficiario_nome
|
string | Nome de quem vai fazer o passeio |
beneficiario_documento
|
string | CPF ou documento |
beneficiario_telefone
|
string | Telefone |
sessao_id
|
integer | Trocar a sessão (reagendamento) |
extras
|
array | Extras escolhidos |
valor_extras
|
number | Soma dos extras |
desconto
|
number | Desconto |
desconto_motivo
|
string | Motivo do desconto |
acrescimo
|
number | Acréscimo |
acrescimo_motivo
|
string | Motivo do acréscimo |
campos_customizados
|
object | Campos livres do integrador |
Resposta de exemplo
{
"success": true,
"message": "Venda atualizada com sucesso"
}
Não existe DELETE de venda: cancelar preserva voucher e financeiro. Ao cancelar, motivo_cancelamento é obrigatório e a data é carimbada.
passeios:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da venda |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
status
*
|
string | reservado, confirmado, usado ou cancelado |
motivo_cancelamento
|
string | Obrigatório quando status=cancelado |
Resposta de exemplo
{
"success": true,
"message": "Status atualizado"
}
Pagamentos lançados nesta venda.
passeios:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da venda |
Resposta de exemplo
{
"success": true,
"data": [
{
"id": 91,
"passeio_venda_id": 508,
"valor": 270,
"forma": "pix",
"data_pagamento": "2026-08-05"
}
]
}
Lança um pagamento na venda.
passeios:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da venda |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
valor
*
|
number | Valor pago |
forma
*
|
string | Forma de pagamento (pix, dinheiro, cartao...) |
data_pagamento
|
date | Data do pagamento. Default: agora |
observacao
|
string | Observação |
Resposta de exemplo
{
"success": true,
"message": "Pagamento registrado"
}
O voucher tem UM item por pessoa, cada um com seu QR code. Uma venda de 4 pessoas gera 4 itens, e o check-in pode ser individual.
passeios:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da venda |
Resposta de exemplo
{
"success": true,
"data": {
"venda_id": 508,
"codigo_voucher": "K7PJ4RQ2",
"quantidade": 2,
"itens": [
{
"id": 1044,
"passeio_venda_id": 508,
"categoria_nome": "Adulto",
"numero_item": 1,
"codigo_qrcode": "K7PJ4RQ2-01",
"beneficiario_nome": "Marina Torres",
"status": "valido",
"usado_em": null
}
]
}
}
Usado na portaria. Procura primeiro pelo código do ITEM (o que está no QR de cada pessoa) e, se não achar, pelo código da venda. Busca case-insensitive, porque leitor de QR devolve em caixa variada. O campo "tipo" na resposta diz qual dos dois foi encontrado.
passeios:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
codigo
*
|
string | path | Código do item do voucher ou da venda |
Resposta de exemplo
{
"success": true,
"data": {
"tipo": "item",
"item": {
"id": 1044,
"passeio_venda_id": 508,
"categoria_nome": "Adulto",
"numero_item": 1,
"codigo_qrcode": "K7PJ4RQ2-01",
"beneficiario_nome": "Marina Torres",
"status": "valido",
"usado_em": null
}
}
}
Sem voucher_item_id, marca a venda inteira. Com ele, marca só aquela pessoa, que é o caso de grupo chegando em horários diferentes. A venda só passa para "usado" quando não resta item pendente. Recusa item já usado (ITEM_JA_USADO), item de outra venda (ITEM_DE_OUTRA_VENDA) e venda cancelada (VENDA_CANCELADA).
passeios:write
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da venda |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
voucher_item_id
|
integer | Item do voucher, para check-in individual |
latitude
|
number | Latitude de onde o check-in foi feito |
longitude
|
number | Longitude |
guia_id
|
integer | Guia que registrou |
registrado_por_nome
|
string | Nome de quem registrou |
metodo
|
string | Método (qrcode, manual, api) |
dispositivo
|
string | Identificação do aparelho |
Resposta de exemplo
{
"success": true,
"message": "Check-in registrado"
}
Histórico de check-ins, do mais recente para o mais antigo.
passeios:read
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID da venda |
Resposta de exemplo
{
"success": true,
"data": [
{
"id": 22,
"venda_id": 508,
"data_hora": "2026-08-06T05:32:00-03:00",
"metodo": "qrcode"
}
]
}
Webhooks
Cadastro e gestão de webhooks. Eventos chegam via POST com envelope padronizado (event, event_id UUID, created_at ISO 8601, data) + assinatura HMAC-SHA256 no header X-Viagilize-Signature.
Retorna todos os eventos que podem ser inscritos, agrupados por categoria (reservas, pagamentos, clientes, excursoes, contratos, checkin).
webhooks:manage
Resposta de exemplo
{
"success": true,
"data": {
"groups": {
"reservas": {
"label": "Reservas",
"events": {
"reserva.criada": "Nova reserva criada",
"reserva.confirmada": "Reserva confirmada (pagamento OK)",
"reserva.cancelada": "Reserva cancelada",
"reserva.expirada": "Reserva expirada por falta de pagamento",
"vaga_pendente.preenchida": "Vaga pendente preenchida (convidado\/comprador completou dados)"
}
},
"pagamentos": {
"label": "Pagamentos",
"events": {
"pagamento.criado": "Novo pagamento registrado",
"pagamento.confirmado": "Pagamento confirmado",
"pagamento.estornado": "Pagamento estornado"
}
},
"contratos": {
"label": "Contratos",
"events": {
"contrato.assinado": "Contrato assinado pelo cliente"
}
}
}
}
}
Lista paginada de webhooks cadastrados.
webhooks:manage
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
page
|
integer | query | Página |
per_page
|
integer | query | Itens (max 100) |
Resposta de exemplo
{
"success": true,
"data": [
{
"id": 1,
"name": "Integração Kommo CRM",
"url": "https:\/\/meusistema.com.br\/webhooks\/viagilize",
"events": [
"reserva.criada",
"reserva.confirmada",
"pagamento.confirmado"
],
"is_active": true,
"last_triggered_at": "2026-04-25T17:30:11-03:00",
"last_status": "success",
"failure_count": 0,
"created_at": "2026-04-20T10:00:00-03:00"
}
],
"meta": {
"current_page": 1,
"per_page": 20,
"total": 1
}
}
Retorna dados de um webhook (sem expor o secret).
webhooks:manage
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do webhook |
Resposta de exemplo
{
"success": true,
"data": {
"id": 1,
"name": "Integração Kommo CRM",
"url": "https:\/\/meusistema.com.br\/webhooks\/viagilize",
"events": [
"reserva.criada",
"reserva.confirmada",
"pagamento.confirmado"
],
"is_active": true,
"last_triggered_at": "2026-04-25T17:30:11-03:00",
"last_status": "success",
"failure_count": 0,
"created_at": "2026-04-20T10:00:00-03:00"
}
}
Cadastra um webhook. Retorna o secret UMA UNICA VEZ — guarde com seguranca para validar HMAC nas entregas.
webhooks:manage
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
name
*
|
string | Nome para identificar o webhook |
url
*
|
string | URL HTTPS que recebera os eventos |
events
*
|
array | Lista de eventos para inscrever (ex: ["reserva.criada", "pagamento.confirmado"]) |
Resposta de exemplo
{
"success": true,
"message": "Webhook criado. Guarde o secret — ele nao sera exibido novamente.",
"data": {
"webhook": {
"id": 1,
"name": "Integração Kommo CRM",
"url": "https:\/\/meusistema.com.br\/webhooks\/viagilize",
"events": [
"reserva.criada",
"reserva.confirmada",
"pagamento.confirmado"
],
"is_active": true,
"last_triggered_at": "2026-04-25T17:30:11-03:00",
"last_status": "success",
"failure_count": 0,
"created_at": "2026-04-20T10:00:00-03:00"
},
"secret": "whsec_aBcDeFgHiJkLmNoPqRsTuVwXyZ012345"
}
}
Atualiza nome, url, lista de eventos ou flag is_active.
webhooks:manage
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do webhook |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
name
|
string | Novo nome |
url
|
string | Nova URL |
events
|
array | Nova lista de eventos |
is_active
|
boolean | Ativa/desativa o webhook |
Resposta de exemplo
{
"success": true,
"message": "Webhook atualizado.",
"data": {
"id": 1,
"name": "Integração Kommo CRM",
"url": "https:\/\/meusistema.com.br\/webhooks\/viagilize",
"events": [
"reserva.criada",
"reserva.confirmada",
"pagamento.confirmado"
],
"is_active": true,
"last_triggered_at": "2026-04-25T17:30:11-03:00",
"last_status": "success",
"failure_count": 0,
"created_at": "2026-04-20T10:00:00-03:00"
}
}
Remove definitivamente o webhook. Entregas em fila para esse webhook deixam de ser processadas.
webhooks:manage
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do webhook |
Resposta de exemplo
{
"success": true,
"message": "Webhook removido."
}
Gera um novo secret para o webhook. Invalida HMAC de qualquer entrega futura usando o secret antigo. Atualize seu receiver imediatamente.
webhooks:manage
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do webhook |
Resposta de exemplo
{
"success": true,
"message": "Secret regenerado.",
"data": {
"secret": "whsec_novoSecretGerado12345abcdef67890"
}
}
Envia um evento test.ping para a URL configurada. Útil para validar que o receiver está respondendo corretamente.
webhooks:manage
Parâmetros
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
id
*
|
integer | path | ID do webhook |
Resposta de exemplo
{
"success": true,
"data": {
"success": true,
"status": "success",
"response_code": 200,
"response_time_ms": 245,
"error_message": null
}
}
Webhooks (Recebimento)
Como receber e validar eventos enviados pelo Viagilize
Envelope padronizado
Todo evento entregue tem o mesmo formato — apenas o conteudo de data varia por tipo.
{
"event": "reserva.criada",
"event_id": "5b3a0e2c-3d6f-4e6a-9b2a-7e9d1c2f3a4b",
"created_at": "2026-04-25T18:30:42-03:00",
"data": { ... }
}
Headers HTTP
Content-Type: application/json
X-Viagilize-Signature: sha256=<hmac_hex>
X-Viagilize-Event: reserva.criada
User-Agent: Viagilize-Webhook/1.0
Validação HMAC (PHP)
A assinatura é HMAC-SHA256 do corpo bruto usando o secret do webhook. Sempre use comparação timing-safe.
$rawBody = $request->getContent();
$expected = 'sha256=' . hash_hmac('sha256', $rawBody, $secret);
if (!hash_equals($expected, $request->header('X-Viagilize-Signature'))) {
abort(401);
}
Idempotência (event_id)
O event_id é UUID v4. Em retries (após 5xx ou timeout), o mesmo id reaparece — guarde-o e dedupe do seu lado antes de processar.
Retry e Backoff
- Máximo de tentativas: 3
- Backoff: 10s, 30s, 60s
- Timeout HTTP: 10s por tentativa
- Sucesso: qualquer 2xx; falha: não-2xx ou timeout
- Após 10 falhas consecutivas o webhook é desativado automaticamente
Eventos disponíveis
Schema completo de cada payload em /docs/API-WEBHOOKS-PAYLOADS.md.
reserva.criada
reserva.confirmada
reserva.cancelada
reserva.expirada
pagamento.criado
pagamento.confirmado
pagamento.estornado
cliente.criado
excursao.publicada
excursao.cancelada
contrato.assinado
checkin.realizado
checkout.realizado
Códigos de Erro
Tratamento de erros da API
Bad Request
A requisição contém dados inválidos ou mal formatados.
Unauthorized
Token de autenticação ausente ou inválido.
Forbidden
Token não possui permissão (scope) para esta ação.
Not Found
Recurso não encontrado.
Unprocessable Entity
Erro de validação nos dados enviados.
Too Many Requests
Limite de requisições excedido. Aguarde antes de tentar novamente.
Internal Server Error
Erro interno do servidor. Entre em contato com o suporte.
Formato de erro
{
"success": false,
"message": "Descrição do erro",
"errors": {
"campo": ["Mensagem de validação"]
}
}
Rate Limiting
Limites de requisições
Para garantir a estabilidade do serviço, a API limita o volume de requisições:
por token de API
Ao exceder o limite:
- A API responde HTTP 429 (Too Many Requests).
-
O header
Retry-Afterinforma em quantos segundos tentar de novo.
Em toda resposta, acompanhe seu consumo pelos headers
X-RateLimit-Limit e
X-RateLimit-Remaining.
Na resposta 429 também vêm
Retry-After e
X-RateLimit-Reset.