https://api.webzy.com.br/api/v1
Autenticação
Todas as requisições exigem um token no header Authorization:
GET https://api.webzy.com.br/api/v1/products # Headers obrigatórios: Authorization: Bearer SEU_TOKEN_AQUI Accept: application/json
Headers de Rate Limit (incluídos em todas as respostas):
X-RateLimit-Limit | Limite máximo de requisições por minuto |
X-RateLimit-Remaining | Requisições restantes na janela atual |
Retry-After | Segundos até poder tentar novamente (só quando excede o limite) |
Verificar token:
GET https://api.webzy.com.br/api/v1/me # Retorna informações do token e do tenant associado
Formato das Respostas
Sucesso (registro único):
{
"success": true,
"message": "Success",
"data": {
"id": 1,
"title": "..."
}
}
Erro:
{
"success": false,
"message": "Validation failed",
"errors": {
"title": ["The title field is required."]
}
}
Paginação e Filtros
Todos os endpoints de listagem suportam paginação:
| Parâmetro | Descrição | Padrão |
|---|---|---|
page | Número da página | 1 |
per_page | Itens por página (máx. 30) | 15 |
sort_by | Campo para ordenação | created_at |
sort_dir | asc ou desc | desc |
search | Busca textual (título, descrição, etc.) | - |
Exemplo de resposta paginada:
GET https://api.webzy.com.br/api/v1/products?page=2&per_page=10&sort_by=price&sort_dir=asc { "success": true, "data": [/* array de registros */], "meta": { "current_page": 2, "last_page": 5, "per_page": 10, "total": 48 }, "links": { "first": "...?page=1", "last": "...?page=5", "prev": "...?page=1", "next": "...?page=3" } }
Preço Promocional
Disponível em Imóveis, Veículos e Produtos. O campo promotional_price representa o preço com desconto. Quando preenchido e estritamente menor que price, o site exibe o formato "De ~~R$ X~~ por R$ Y" com o percentual de desconto.
Regras de validação:
promotional_priceé opcional — envienull(ou omita) para não ter promoção.- Quando preenchido, deve ser
≥ 0.01e estritamente menor queprice. - Em
PUTparcial, sepricenão for enviado no payload, o valor armazenado no banco é usado como referência.
Resposta com promoção ativa (GET):
{
"id": 42,
"title": "Apartamento 3 quartos - Centro",
"price": 450000,
"promotional_price": 399000,
"promotion": {
"active": true,
"percentage": 11,
"price_from": 450000,
"price_to": 399000
},
// ...demais campos
}
// Quando não há promoção: "promotional_price": null e "promotion": null
Filtrar somente itens em promoção:
GET https://api.webzy.com.br/api/v1/imoveis?on_sale=1 GET https://api.webzy.com.br/api/v1/vehicles?on_sale=1 GET https://api.webzy.com.br/api/v1/products?on_sale=1
Ordenar por preço promocional:
GET https://api.webzy.com.br/api/v1/products?sort_by=promotional_price&sort_dir=asc
Imóveis
| GET | /imoveis/options | Valores aceitos para campos dropdown (ver Opções) |
| GET | /imoveis | Listar imóveis |
| GET | /imoveis/{id} | Detalhe de um imóvel |
| POST | /imoveis | Criar imóvel (requer permissão CRUD) |
| PUT | /imoveis/{id} | Atualizar imóvel (requer permissão CRUD) |
| DELETE | /imoveis/{id} | Excluir imóvel (requer permissão CRUD) |
Filtros de listagem:
status | draft, published, sold, rented |
type | venda, aluguel, temporada |
property_type | Tipo de propriedade (casa, apartamento, etc.) |
city | Filtro por cidade (busca parcial) |
featured | true ou false |
price_min / price_max | Faixa de preço (compara com price) |
on_sale | 1 retorna apenas imóveis em promoção (promotional_price ativo) |
bedrooms_min | Quartos mínimos |
category_id | Filtrar por categoria |
Exemplo - criar imóvel:
POST https://api.webzy.com.br/api/v1/imoveis Content-Type: application/json Authorization: Bearer SEU_TOKEN { "title": "Apartamento 3 quartos - Centro", "type": "venda", "property_type": "apartamento", "status": "published", "price": 450000, "promotional_price": 399000, // opcional; deve ser menor que price "bedrooms": 3, "bathrooms": 2, "area_total": 120.5, "features": ["piscina", "churrasqueira", "elevador"], "city": "São Paulo", "state": "SP", "category_ids": [1, 5] } // Campos dropdown (type, property_type, features) aceitam apenas // valores retornados pelo endpoint GET /imoveis/options
Veículos
| GET | /vehicles/options | Valores aceitos para campos dropdown (ver Opções) |
| GET | /vehicles | Listar veículos |
| GET | /vehicles/{id} | Detalhe |
| POST | /vehicles | Criar (CRUD) |
| PUT | /vehicles/{id} | Atualizar (CRUD) |
| DELETE | /vehicles/{id} | Excluir (CRUD) |
Filtros de listagem:
status | draft, published, sold |
condition | novo, usado |
brand | Marca (ex: Toyota, Honda) |
vehicle_type | Tipo (carro, moto, caminhão, etc.) |
fuel_type | Combustível (flex, gasolina, diesel, elétrico) |
transmission | Câmbio (manual, automático) |
featured | true ou false |
price_min / price_max | Faixa de preço (compara com price) |
on_sale | 1 retorna apenas veículos em promoção (promotional_price ativo) |
year_min / year_max | Faixa de ano |
category_id | Filtrar por categoria |
Exemplo - criar veículo:
POST https://api.webzy.com.br/api/v1/vehicles Content-Type: application/json { "title": "Honda Civic EXL 2024", "status": "published", "price": 145000, "promotional_price": 129900, // opcional; deve ser menor que price "condition": "usado", "brand": "honda", "vehicle_type": "carro", "model": "Civic", "year_manufacture": 2024, "year_model": 2024, "mileage": 15000, "fuel_type": "flex", "transmission": "automatico", "color": "branco", "features": ["ar_condicionado", "airbag", "camera_re"], "category_ids": [3] } // Campos dropdown (brand, vehicle_type, fuel_type, transmission, // color, condition, features) aceitam apenas valores (keys) // retornados pelo endpoint GET /vehicles/options
Produtos
| GET | /products | Listar produtos |
| GET | /products/{id} | Detalhe |
| POST | /products | Criar (CRUD) |
| PUT | /products/{id} | Atualizar (CRUD) |
| DELETE | /products/{id} | Excluir (CRUD) |
Filtros de listagem:
status | draft, published, archived |
stock_status | in_stock, out_of_stock, on_backorder |
featured | true ou false |
price_min / price_max | Faixa de preço (compara com price) |
on_sale | 1 retorna apenas produtos em promoção (promotional_price ativo) |
sku | Filtrar por SKU exato |
category_id | Filtrar por categoria |
Exemplo - criar produto:
POST https://api.webzy.com.br/api/v1/products Content-Type: application/json { "title": "Camiseta Polo Premium", "status": "published", "price": 129.90, "promotional_price": 89.90, // opcional; deve ser menor que price "sku": "POLO-001", "stock": 50, "stock_status": "in_stock", "summary": "Camiseta polo em algodão premium", "category_ids": [2, 7] }
Blog / Notícias
| GET | /blog-posts | Listar posts |
| GET | /blog-posts/{id} | Detalhe |
| POST | /blog-posts | Criar (CRUD) |
| PUT | /blog-posts/{id} | Atualizar (CRUD) |
| DELETE | /blog-posts/{id} | Excluir (CRUD) |
Filtros de listagem:
status | draft, published, archived |
featured | true ou false |
category_id | Filtrar por categoria |
Exemplo - criar post:
POST https://api.webzy.com.br/api/v1/blog-posts Content-Type: application/json { "title": "Como escolher o melhor imóvel", "status": "published", "excerpt": "Dicas essenciais para sua compra", "content": "<p>Conteúdo HTML do post...</p>", "category_ids": [4] }
Categorias Somente leitura
| GET | /categories | Listar categorias |
| GET | /categories/{id} | Detalhe (inclui subcategorias) |
Filtros:
node_type | Tipo: blog, product, imovel, vehicle, etc. |
roots_only | true para retornar só categorias raiz (sem parent) |
with_children | true para incluir subcategorias |
# Categorias raiz de produtos com subcategorias GET https://api.webzy.com.br/api/v1/categories?node_type=product&roots_only=true&with_children=true
Outros Endpoints Somente leitura
FAQ
| GET | /faq | Listar — filtros: status, category_id, search |
| GET | /faq/{id} | Detalhe |
Portfólio
| GET | /portfolio | Listar — filtros: status, featured, category_id, search |
| GET | /portfolio/{id} | Detalhe |
Equipe
| GET | /team | Listar — filtros: status, department, search |
| GET | /team/{id} | Detalhe |
Depoimentos
| GET | /testimonials | Listar — filtros: status, featured, rating_min, search |
| GET | /testimonials/{id} | Detalhe |
Newsletter
| GET | /newsletter | Listar inscritos — filtros: status, source, search |
| POST | /newsletter/subscribe | Inscrever e-mail |
POST https://api.webzy.com.br/api/v1/newsletter/subscribe Content-Type: application/json { "email": "cliente@email.com", "name": "João Silva" }
Galeria de Imagens CRUD
Os 4 models CRUD (imóveis, veículos, produtos, blog) possuem endpoints de galeria de imagens. Requer permissão CRUD.
Substitua {model} por: imoveis, vehicles, products ou blog-posts
| GET | /{model}/{id}/images | Listar imagens da entidade |
| POST | /{model}/{id}/images | Upload de imagens (multipart/form-data). Aceita ?mode=replace para substituir a galeria. |
| POST | /{model}/{id}/images/{imageId}/cover | Definir imagem como capa |
| POST | /{model}/{id}/images/reorder | Reordenar imagens |
| PUT | /{model}/{id}/images/{imageId} | Atualizar alt/caption |
| DELETE | /{model}/{id}/images/{imageId} | Excluir uma imagem |
| DELETE | /{model}/{id}/images | Excluir todas as imagens da entidade |
Upload de Imagens
Envie via multipart/form-data. Formatos aceitos: jpg, jpeg, png, gif, webp, svg.
# Upload de imagens para um imóvel POST https://api.webzy.com.br/api/v1/imoveis/1/images Content-Type: multipart/form-data Authorization: Bearer SEU_TOKEN # Body (form-data): files[]: (arquivo binário - foto1.jpg) files[]: (arquivo binário - foto2.jpg)
Exemplos em código:
PHP (cURL)
$ch = curl_init('https://api.webzy.com.br/api/v1/imoveis/1/images'); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Bearer TOKEN']); curl_setopt($ch, CURLOPT_POSTFIELDS, [ 'files[0]' => new CURLFile('/caminho/foto.jpg'), 'files[1]' => new CURLFile('/caminho/foto2.jpg'), ]);
Python (requests)
import requests files = [ ('files[]', open('foto.jpg', 'rb')), ('files[]', open('foto2.jpg', 'rb')), ] r = requests.post('https://api.webzy.com.br/api/v1/imoveis/1/images', headers={'Authorization': 'Bearer TOKEN'}, files=files)
JavaScript (fetch)
const form = new FormData(); form.append('files[]', fileInput1); form.append('files[]', fileInput2); fetch('https://api.webzy.com.br/api/v1/imoveis/1/images', { method: 'POST', headers: { 'Authorization': 'Bearer TOKEN' }, body: form });
Resposta do upload:
{
"success": true,
"message": "2 image(s) uploaded successfully",
"data": [
{
"id": 42,
"filename": "foto_1707040123_abc123.jpg",
"original_name": "foto.jpg",
"is_cover": true,
"order": 0,
"mime_type": "image/jpeg",
"size": 245678,
"width": 2000,
"height": 1500,
"urls": {
"original": "https://...",
"thumb": "https://..._thumb.jpg",
"small": "https://..._small.jpg",
"medium": "https://..._medium.jpg",
"large": "https://..._large.jpg"
}
}
]
}
Definir imagem capa
POST https://api.webzy.com.br/api/v1/imoveis/1/images/42/cover Authorization: Bearer SEU_TOKEN
Reordenar imagens
POST https://api.webzy.com.br/api/v1/imoveis/1/images/reorder Content-Type: application/json Authorization: Bearer SEU_TOKEN { "ids": [5, 3, 1, 4] // nova ordem desejada }
Atualizar alt/caption
PUT https://api.webzy.com.br/api/v1/imoveis/1/images/42 Content-Type: application/json Authorization: Bearer SEU_TOKEN { "alt": "Vista da sala de estar", "caption": "Ampla sala com piso em porcelanato" }
Excluir uma imagem
DELETE https://api.webzy.com.br/api/v1/imoveis/1/images/42 Authorization: Bearer SEU_TOKEN
Excluir todas as imagens
Remove todas as imagens da entidade (originais e variantes) do storage e do banco. Útil para "zerar" a galeria antes de outra operação.
DELETE https://api.webzy.com.br/api/v1/imoveis/1/images Authorization: Bearer SEU_TOKEN
Substituir toda a galeria (mode=replace)
Fluxo típico de integrações do tipo gateway: o sistema externo re-envia todas as imagens
do cadastro a cada mudança. Sem esse parâmetro, cada upload seria acumulado e as fotos
iriam duplicar. Com mode=replace, o Webzy sobe as imagens novas primeiro e só
então remove as antigas — se qualquer upload falhar, o rollback é automático e a galeria
anterior permanece intacta.
# Substitui toda a galeria pela lista enviada POST https://api.webzy.com.br/api/v1/imoveis/1/images?mode=replace Content-Type: multipart/form-data Authorization: Bearer SEU_TOKEN # Body (form-data): files[]: (foto1.jpg) files[]: (foto2.jpg) files[]: (foto3.jpg) # Resposta: # { # "success": true, # "message": "Gallery replaced with 3 image(s)", # "data": [ ... ] # }
- Em modo
append(padrão) as imagens são adicionadas à galeria existente. - Em modo
replaceo upload é atômico do ponto de vista do cliente — ou toda a galeria é trocada, ou nada muda. Não é possível ficar com uma galeria vazia por falha parcial. - A primeira imagem enviada é definida como capa automaticamente (quando a entidade ainda não tem capa).
- A imagem capa recebe variantes em todos os tamanhos (thumb, small, medium, large).
- Imagens não-capa recebem apenas thumbnail (economia de armazenamento).
- Ao excluir a capa individualmente, a próxima imagem é promovida automaticamente.
- Funciona com armazenamento local e MinIO/S3 — transparente para o consumidor da API.
Campos com Opções (Dropdowns)
Alguns campos de Veículos e Imóveis aceitam apenas valores pré-definidos. Para saber quais valores são aceitos, consulte o endpoint /options de cada entidade:
GET https://api.webzy.com.br/api/v1/vehicles/options GET https://api.webzy.com.br/api/v1/imoveis/options
Exemplo de resposta (veículos):
{
"success": true,
"data": {
"condition": { "novo": "Novo", "usado": "Usado" },
"vehicle_type": { "carro": "Carro", "moto": "Moto", ... },
"brand": { "volkswagen": "Volkswagen", "fiat": "Fiat", ... },
"fuel_type": { "flex": "Flex", "gasolina": "Gasolina", ... },
"transmission": { "manual": "Manual", "automatico": "Automático", ... },
"color": { "branco": "Branco", "preto": "Preto", ... },
"features": { "ar_condicionado": "Ar Condicionado", ... },
"status": { "draft": "Rascunho", "published": "Publicado", ... }
}
}
"brand": "volkswagen", e para features envie "features": ["ar_condicionado", "airbag"].
Campos dropdown por entidade:
| Entidade | Campos |
|---|---|
| Veículos | condition, vehicle_type, brand, fuel_type, transmission, color, features |
| Imóveis | type, property_type, features |
As opções disponíveis podem variar por tenant. O administrador pode adicionar opções customizadas nas configurações do módulo no painel. Valores enviados fora das opções disponíveis serão rejeitados com erro 422.
Limites de Cadastro
A API respeita os limites de cadastro configurados no painel (Configurações > Limites). Ao tentar criar um registro quando o limite foi atingido, a API retorna:
# HTTP 403 { "success": false, "message": "Registration limit reached for this module" }
Módulos com limite:
| Módulo | Endpoint | Limite padrão |
|---|---|---|
| Imóveis | POST /imoveis | 500 |
| Veículos | POST /vehicles | 500 |
| Produtos | POST /products | 500 |
| Blog | POST /blog-posts | 100 |
Limite 0 = ilimitado. Os limites podem ser ajustados pelo administrador no painel.
Códigos de Erro
| Código | Significado | Quando ocorre |
|---|---|---|
401 | Não autenticado | Token ausente, inválido, inativo ou expirado |
403 | Acesso negado | Token sem permissão para este recurso/ação, ou limite de cadastros atingido |
404 | Não encontrado | Recurso ou endpoint não existe |
409 | Conflito | E-mail já inscrito na newsletter |
422 | Validação falhou | Dados enviados com erros (campos obrigatórios, formato inválido) |
429 | Muitas requisições | Rate limit excedido — aguarde Retry-After segundos |
Vinculando Categorias
Para vincular registros a categorias ao criar ou atualizar, envie o campo category_ids com um array de IDs:
# No create ou update de qualquer CRUD model { "title": "Meu produto", "category_ids": [1, 5, 12] // substitui todas as categorias }
- Enviar
category_idssubstitui todas as categorias do registro (sync). - Enviar
[](array vazio) remove todas as categorias. - Não enviar o campo mantém as categorias atuais (só no update).
- Os IDs devem ser de categorias que pertencem ao mesmo tenant do token.