Plugin WordPress que cria endpoints REST API completos para gerenciar veículos (Custom Post Type cpt_cars) e suas taxonomias através de uma API REST moderna com suporte JWT.
- Descrição
- Funcionalidades
- Instalação
- Requisitos
- Configuração
- Como Usar a API
- Integração com n8n
- Estrutura de Resposta
- Formato do JSON
- Campos de Dados
- Segurança
- Troubleshooting
- Changelog
- Links Úteis
- Licença
Este plugin foi desenvolvido para o tema carz – Car Dealer, Shop & Repair WordPress Theme e oferece uma API REST completa para consulta (GET) e manipulação (POST/PUT/DELETE) de veículos, fabricantes, modelos, recursos e muito mais. Suporta dois tipos de autenticação: API Key (para leitura) e JWT (para escrita).
- ✅ Métodos HTTP: GET, POST, PUT, DELETE
- ✅ CRUD Completo: Criar, Ler, Atualizar e Deletar veículos e taxonomias
- ✅ Namespace Padrão:
carz-api/v1 - ✅ Endpoint Personalizado: Defina seu próprio endpoint (ex:
api/veiculos)
- ✅ Veículos: CRUD completo de veículos com 30+ campos
- ✅ Fabricantes (Makers): Gerenciar marcas de veículos
- ✅ Modelos (Models): Gerenciar modelos por fabricante
- ✅ Recursos (Features): Equipamentos e características
- ✅ Tipos (Types): Categorias de veículos (SUV, Sedan, etc)
- ✅ Status: Para venda, para alugar, etc
- ✅ Labels: Etiquetas personalizadas
- ✅ Cidades (Cities): Localização dos veículos
- ✅ Agentes (Agents): Vendedores/contatos
- ✅ Upload de Imagens: Enviar e gerenciar mídia
-
✅ API Key: Para operações GET (leitura)
- Via header
X-API-Key - Via query string
?api_key= - Opcional ou obrigatória
- Gerador automático de chaves seguras (64 caracteres)
- Via header
-
✅ JWT (JSON Web Token): Para operações POST/PUT/DELETE (escrita)
- Implementação nativa sem dependências externas
- Algoritmos suportados: HS256, HS384, HS512
- Token no header
Authorization: Bearer {token} - Validação de expiração automática
- ✅ CORS Habilitado: Suporte para requisições cross-origin
- ✅ Pretty Print: Formatar JSON com
?pretty - ✅ Status Visual: Coluna na lista de carros mostrando disponibilidade
- ✅ Interface Amigável: Página de configurações com exemplos
- ✅ Gerador de API Key: Gere chaves seguras com um clique
- Faça upload da pasta
carztheme-apipara/wp-content/plugins/ - Ative o plugin através do menu 'Plugins' no WordPress
- Acesse Configurações > Paradigma API para configurar
- Configure o
JWT_SECRETnowp-config.php(veja seção de Configuração JWT)
- ✅ WordPress 5.0 ou superior
- ✅ PHP 7.0 ou superior
- ✅ TRX Addons plugin ativo
- ✅ Custom Post Type
cpt_carsconfigurado
Para usar operações de escrita (POST, PUT, DELETE), você DEVE configurar o JWT_SECRET:
- Abra o arquivo
wp-config.phpna raiz do WordPress - Adicione a seguinte linha antes de
/* That's all, stop editing! */:
define('JWT_SECRET', 'sua-chave-secreta-super-forte-aqui-minimo-32-caracteres');- Use uma string aleatória e forte (mínimo 32 caracteres)
- NUNCA compartilhe seu
JWT_SECRET - Pode gerar uma chave forte em: Random.org
Exemplo de JWT_SECRET seguro:
define('JWT_SECRET', 'K8mN2pQ5rS9tV3wX6zA4bC7dE0fG1hJ4kL8mN2pQ5rS9tV3');| Método | Endpoint | Descrição | Autenticação |
|---|---|---|---|
GET |
/wp-json/carz-api/v1/vehicles |
Listar todos os veículos | API Key (opcional) |
GET |
/wp-json/carz-api/v1/vehicles/{id} |
Obter veículo específico | API Key (opcional) |
POST |
/wp-json/carz-api/v1/vehicles |
Criar novo veículo | JWT (obrigatório) |
PUT |
/wp-json/carz-api/v1/vehicles/{id} |
Atualizar veículo | JWT (obrigatório) |
DELETE |
/wp-json/carz-api/v1/vehicles/{id} |
Deletar veículo | JWT (obrigatório) |
| Método | Endpoint | Descrição | Autenticação |
|---|---|---|---|
GET |
/wp-json/carz-api/v1/makers |
Listar todos os fabricantes | API Key (opcional) |
POST |
/wp-json/carz-api/v1/makers |
Criar novo fabricante | JWT (obrigatório) |
PUT |
/wp-json/carz-api/v1/makers/{id} |
Atualizar fabricante | JWT (obrigatório) |
DELETE |
/wp-json/carz-api/v1/makers/{id} |
Deletar fabricante | JWT (obrigatório) |
| Método | Endpoint | Descrição | Autenticação |
|---|---|---|---|
GET |
/wp-json/carz-api/v1/models |
Listar todos os modelos | API Key (opcional) |
GET |
/wp-json/carz-api/v1/models?maker_id={id} |
Filtrar por fabricante | API Key (opcional) |
POST |
/wp-json/carz-api/v1/models |
Criar novo modelo | JWT (obrigatório) |
PUT |
/wp-json/carz-api/v1/models/{id} |
Atualizar modelo | JWT (obrigatório) |
DELETE |
/wp-json/carz-api/v1/models/{id} |
Deletar modelo | JWT (obrigatório) |
| Método | Endpoint | Descrição | Autenticação |
|---|---|---|---|
GET |
/wp-json/carz-api/v1/features |
Listar todos os recursos | API Key (opcional) |
POST |
/wp-json/carz-api/v1/features |
Criar novo recurso | JWT (obrigatório) |
PUT |
/wp-json/carz-api/v1/features/{id} |
Atualizar recurso | JWT (obrigatório) |
DELETE |
/wp-json/carz-api/v1/features/{id} |
Deletar recurso | JWT (obrigatório) |
| Método | Endpoint | Descrição | Autenticação |
|---|---|---|---|
GET |
/wp-json/carz-api/v1/types |
Listar todos os tipos | Nenhuma |
POST |
/wp-json/carz-api/v1/types |
Criar novo tipo | JWT (obrigatório) |
PUT |
/wp-json/carz-api/v1/types/{id} |
Atualizar tipo | JWT (obrigatório) |
DELETE |
/wp-json/carz-api/v1/types/{id} |
Deletar tipo | JWT (obrigatório) |
| Método | Endpoint | Descrição | Autenticação |
|---|---|---|---|
GET |
/wp-json/carz-api/v1/status |
Listar todos os status | Nenhuma |
POST |
/wp-json/carz-api/v1/status |
Criar novo status | JWT (obrigatório) |
DELETE |
/wp-json/carz-api/v1/status/{id} |
Deletar status | JWT (obrigatório) |
| Método | Endpoint | Descrição | Autenticação |
|---|---|---|---|
GET |
/wp-json/carz-api/v1/labels |
Listar todos os labels | Nenhuma |
POST |
/wp-json/carz-api/v1/labels |
Criar novo label | JWT (obrigatório) |
DELETE |
/wp-json/carz-api/v1/labels/{id} |
Deletar label | JWT (obrigatório) |
| Método | Endpoint | Descrição | Autenticação |
|---|---|---|---|
GET |
/wp-json/carz-api/v1/cities |
Listar todas as cidades | Nenhuma |
POST |
/wp-json/carz-api/v1/cities |
Criar nova cidade | JWT (obrigatório) |
PUT |
/wp-json/carz-api/v1/cities/{id} |
Atualizar cidade | JWT (obrigatório) |
DELETE |
/wp-json/carz-api/v1/cities/{id} |
Deletar cidade | JWT (obrigatório) |
| Método | Endpoint | Descrição | Autenticação |
|---|---|---|---|
GET |
/wp-json/carz-api/v1/agents |
Listar todos os agentes | API Key (opcional) |
GET |
/wp-json/carz-api/v1/agents/{id} |
Obter agente específico | API Key (opcional) |
POST |
/wp-json/carz-api/v1/agents |
Criar novo agente | JWT (obrigatório) |
PUT |
/wp-json/carz-api/v1/agents/{id} |
Atualizar agente | JWT (obrigatório) |
DELETE |
/wp-json/carz-api/v1/agents/{id} |
Deletar agente | JWT (obrigatório) |
| Método | Endpoint | Descrição | Autenticação |
|---|---|---|---|
POST |
/wp-json/carz-api/v1/upload |
Fazer upload de imagem | JWT (obrigatório) |
DELETE |
/wp-json/carz-api/v1/media/{id} |
Deletar imagem | JWT (obrigatório) |
Você pode definir um endpoint personalizado em Configurações > Paradigma API.
Exemplo: Se você definir api/veiculos:
GET /api/veiculos # Listar todos
GET /api/veiculos/{id} # Obter específico
- Acesse Configurações > Paradigma API
- No campo "Endpoint Personalizado", digite o caminho (ex:
api/veiculos) - Clique em Salvar Configurações
- Clique em Atualizar Permalinks
- Teste o endpoint clicando no botão "Testar"
- Marque a opção "Requer Autenticação"
- Clique em "Gerar API Key" para criar uma chave segura
- Clique em Salvar Configurações
- Use a API Key nas suas requisições (veja exemplos abaixo)
fetch('https://seusite.com/wp-json/carz-api/v1/vehicles')
.then(response => response.json())
.then(data => {
console.log(`Total de veículos: ${data.length}`);
data.forEach(vehicle => {
console.log(`${vehicle.title} - ${vehicle.prices.price}`);
});
});fetch('https://seusite.com/wp-json/carz-api/v1/vehicles', {
headers: {
'X-API-Key': 'carz_1234567890abcdef...'
}
})
.then(response => response.json())
.then(data => {
console.log(data);
});const apiKey = 'carz_1234567890abcdef...';
fetch(`https://seusite.com/api/veiculos?api_key=${apiKey}`)
.then(response => response.json())
.then(data => {
console.log(data);
});Para criar, atualizar ou deletar recursos, você precisa de um token JWT válido.
IMPORTANTE: Você precisa criar um endpoint de login personalizado ou usar um plugin de autenticação JWT WordPress. O token deve ser gerado com o mesmo JWT_SECRET configurado no wp-config.php.
Exemplo básico de geração de token (executar no backend):
// Em um arquivo PHP do WordPress
require_once ABSPATH . 'wp-content/plugins/carztheme-api/jwt-handler.php';
$jwt_secret = JWT_SECRET; // Definido no wp-config.php
// Dados do token
$token_data = array(
'user_id' => 1, // ID do usuário
'email' => 'admin@exemplo.com',
);
// Gerar token válido por 24 horas (86400 segundos)
$token = Carz_JWT_Handler::generate_token($token_data, $jwt_secret, 86400);
echo "Seu token JWT: " . $token;Exemplo com JavaScript usando biblioteca JWT (Node.js):
const jwt = require('jsonwebtoken');
const JWT_SECRET = 'K8mN2pQ5rS9tV3wX6zA4bC7dE0fG1hJ4kL8mN2pQ5rS9tV3'; // Mesmo do wp-config.php
const payload = {
user_id: 1,
email: 'admin@exemplo.com',
iat: Math.floor(Date.now() / 1000),
exp: Math.floor(Date.now() / 1000) + (24 * 60 * 60), // 24 horas
iss: 'https://seusite.com'
};
const token = jwt.sign(payload, JWT_SECRET, { algorithm: 'HS256' });
console.log('Token JWT:', token);const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'; // Seu token JWT
const newVehicle = {
title: 'Ferrari F8 Tributo 2024',
description: 'Superesportivo italiano com motor V8 turbo',
price: '1500000',
specifications: {
year: '2024',
fuel: 'Gasolina',
transmission: 'Automática',
mileage: '0'
}
};
fetch('https://seusite.com/wp-json/carz-api/v1/vehicles', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(newVehicle)
})
.then(response => response.json())
.then(data => {
if (data.error) {
console.error('Erro:', data.error);
} else {
console.log('Veículo criado:', data);
}
})
.catch(error => console.error('Erro:', error));const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...';
const vehicleId = 123;
const updatedData = {
price: '1450000',
specifications: {
mileage: '500'
}
};
fetch(`https://seusite.com/wp-json/carz-api/v1/vehicles/${vehicleId}`, {
method: 'PUT',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(updatedData)
})
.then(response => response.json())
.then(data => {
console.log('Veículo atualizado:', data);
});const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...';
const vehicleId = 123;
fetch(`https://seusite.com/wp-json/carz-api/v1/vehicles/${vehicleId}`, {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${token}`
}
})
.then(response => response.json())
.then(data => {
console.log('Veículo deletado:', data);
});$ch = curl_init('https://seusite.com/wp-json/carz-api/v1/vehicles');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'X-API-Key: carz_1234567890abcdef...'
]);
$response = curl_exec($ch);
$data = json_decode($response, true);
curl_close($ch);
foreach ($data as $vehicle) {
echo $vehicle['title'] . ' - ' . $vehicle['prices']['price'] . PHP_EOL;
}$token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...';
$newVehicle = array(
'title' => 'Porsche 911 Turbo S',
'price' => '1200000',
'specifications' => array(
'year' => '2024',
'fuel' => 'Gasolina'
)
);
$ch = curl_init('https://seusite.com/wp-json/carz-api/v1/vehicles');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($newVehicle));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $token,
'Content-Type: application/json'
]);
$response = curl_exec($ch);
$data = json_decode($response, true);
curl_close($ch);
print_r($data);import requests
headers = {'X-API-Key': 'carz_1234567890abcdef...'}
response = requests.get(
'https://seusite.com/wp-json/carz-api/v1/vehicles',
headers=headers
)
data = response.json()
print(f"Total: {len(data)}")
for vehicle in data:
print(f"{vehicle['title']} - {vehicle['prices']['price']}")import requests
token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
headers = {
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
}
new_vehicle = {
'title': 'Lamborghini Huracán',
'price': '2000000',
'specifications': {
'year': '2024',
'fuel': 'Gasolina'
}
}
response = requests.post(
'https://seusite.com/wp-json/carz-api/v1/vehicles',
json=new_vehicle,
headers=headers
)
print(response.json())$.ajax({
url: 'https://seusite.com/wp-json/carz-api/v1/vehicles',
method: 'GET',
headers: {
'X-API-Key': 'carz_1234567890abcdef...'
},
success: function(data) {
console.log('Total:', data.length);
$.each(data, function(i, vehicle) {
console.log(vehicle.title, vehicle.prices.price);
});
}
});const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...';
$.ajax({
url: 'https://seusite.com/wp-json/carz-api/v1/vehicles',
method: 'POST',
headers: {
'Authorization': 'Bearer ' + token
},
contentType: 'application/json',
data: JSON.stringify({
title: 'Audi R8 V10',
price: '1300000',
specifications: {
year: '2024'
}
}),
success: function(data) {
console.log('Veículo criado:', data);
},
error: function(xhr) {
console.error('Erro:', xhr.responseJSON);
}
});Configure o nó HTTP Request:
- Method:
GET - URL:
https://seusite.com/wp-json/carz-api/v1/vehicles - Authentication:
None - Response Format:
JSON
Configure o nó HTTP Request:
- Method:
GET - URL:
https://seusite.com/wp-json/carz-api/v1/vehicles - Authentication: Clique em "Add Credential"
- Escolha Header Auth
- Configure as credenciais:
- Name:
X-API-Key - Value:
carz_1234567890abcdef...(sua API Key)
- Name:
- Response Format:
JSON
Para criar, atualizar ou deletar veículos:
- Method:
POST|PUT|DELETE - URL:
- POST:
https://seusite.com/wp-json/carz-api/v1/vehicles - PUT:
https://seusite.com/wp-json/carz-api/v1/vehicles/{{$json.id}} - DELETE:
https://seusite.com/wp-json/carz-api/v1/vehicles/{{$json.id}}
- POST:
- Authentication: Clique em "Add Credential"
- Escolha Header Auth
- Configure as credenciais:
- Name:
Authorization - Value:
Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...(seu token JWT)
- Name:
- Body Content Type:
JSON - Body (para POST/PUT):
{
"title": "Ferrari F8 Tributo",
"price": "1500000",
"specifications": {
"year": "2024",
"fuel": "Gasolina",
"transmission": "Automática"
}
}Adicione um nó Split Out após o HTTP Request:
- Field to Split Out: Deixe vazio (o array já vem direto)
- Isso criará um item separado para cada veículo
- Cada veículo terá seu próprio JSON
Adicione um nó Set para extrair os campos desejados:
Campo | Expressão
-----------------|----------------------------------
title | {{ $json.title }}
price | {{ $json.prices.price }}
year | {{ $json.specifications.year }}
fuel | {{ $json.specifications.fuel }}
transmission | {{ $json.specifications.transmission }}
mileage | {{ $json.specifications.mileage }}
url | {{ $json.url }}
image | {{ $json.featured_image.url }}
[HTTP Request - GET]
↓ GET https://seusite.com/wp-json/carz-api/v1/vehicles
↓ Header: X-API-Key = sua-chave
↓
[Split Out]
↓ (Cria um item para cada veículo)
↓
[Set]
↓ Mapeia campos desejados
↓
[Google Sheets / Airtable / Webhook]
↓ Envia dados para destino
[Webhook / Google Sheets / CSV]
↓ Fonte de dados dos veículos
↓
[Set]
↓ Formata dados no formato esperado pela API
↓
[HTTP Request - POST]
↓ POST https://seusite.com/wp-json/carz-api/v1/vehicles
↓ Header: Authorization = Bearer {token}
↓ Body: JSON com dados do veículo
↓
[IF]
↓ Verifica se criação foi bem-sucedida
↓
[Sucesso / Erro]
[Schedule Trigger]
↓ Executa diariamente às 8h
↓
[HTTP Request - GET]
↓ Busca todos os veículos
↓
[Split Out]
↓ Separa cada veículo
↓
[Function]
↓ Aplica regra de desconto: preço * 0.9
↓
[HTTP Request - PUT]
↓ PUT https://seusite.com/wp-json/carz-api/v1/vehicles/{{$json.id}}
↓ Header: Authorization = Bearer {token}
↓ Body: { "price": "{{$json.new_price}}" }
Use o nó Filter para processar apenas veículos específicos:
// Apenas carros a partir de 2020
{{ $json.specifications.year >= 2020 }}
// Apenas com preço menor que 100000
{{ parseInt($json.prices.price) < 100000 }}
// Apenas Porsche
{{ $json.taxonomies.maker[0].name === "Porsche" }}Opção 1: Token Fixo (mais simples)
- Gere um token com validade longa (ex: 30 dias)
- Use diretamente nas credenciais do n8n
- Lembre-se de renovar antes de expirar
Opção 2: Token Dinâmico (mais seguro)
[Function Node - Generate JWT]
↓ Gera token usando biblioteca jsonwebtoken
↓
[Set Node]
↓ Armazena token em variável
↓
[HTTP Request - POST/PUT/DELETE]
↓ Usa token da variável
Código do Function Node:
const jwt = require('jsonwebtoken');
const JWT_SECRET = 'K8mN2pQ5rS9tV3wX6zA4bC7dE0fG1hJ4kL8mN2pQ5rS9tV3';
const payload = {
user_id: 1,
email: 'admin@exemplo.com',
iat: Math.floor(Date.now() / 1000),
exp: Math.floor(Date.now() / 1000) + (24 * 60 * 60), // 24h
iss: 'https://seusite.com'
};
const token = jwt.sign(payload, JWT_SECRET, { algorithm: 'HS256' });
return [{
json: {
jwt_token: token
}
}];Configure um webhook no n8n para executar o workflow periodicamente:
- Adicione um nó Schedule Trigger
- Configure para executar a cada hora/dia
- O workflow buscará automaticamente os veículos atualizados
Adicione um nó Error Trigger para capturar falhas:
[Error Trigger]
↓ Captura erros de autenticação ou validação
↓
[Set]
↓ Formata mensagem de erro
↓
[Send Email / Slack / Discord]
↓ Notifica sobre o erro
Formato: Array de objetos JSON (cada objeto = um veículo)
[
{
"id": 123,
"title": "Ferrari F8 Tributo",
"description": "Descrição completa...",
"excerpt": "Resumo...",
"slug": "ferrari-f8-tributo",
"status": "publish",
"date": "2024-01-15 10:30:00",
"modified": "2024-01-20 15:45:00",
"url": "https://seusite.com/cars/ferrari-f8-tributo",
"featured_image": {
"id": 456,
"url": "https://seusite.com/wp-content/uploads/ferrari.jpg",
"sizes": {
"thumbnail": "...",
"medium": "...",
"large": "...",
"full": "..."
}
},
"gallery": [...],
"prices": {
"price": "1500000",
"price2": "",
"price_prefix": "R$",
"price2_prefix": ""
},
"taxonomies": {
"maker": [{
"id": 10,
"name": "Ferrari",
"slug": "ferrari"
}],
"type": [...],
"status": [...]
},
"specifications": {
"model": "F8 Tributo",
"year": "2024",
"mileage": "0",
"fuel": "Gasolina",
"engine_size": "3.9",
"engine_type": "V8 Turbo",
"power": "720 cv",
"transmission": "Automática",
"drive": "Tração traseira",
"doors": "2",
"seats": "2",
"exterior_color": "Rosso Corsa",
"interior_color": "Preto",
"condition": "Novo",
"vin": "ZFF93VLA0L0123456",
"registration_date": "2024-01-15"
},
"location": {
"city": "São Paulo",
"country": "Brasil",
"address": "Av. Paulista, 1000",
"location": "-23.5505,-46.6333"
},
"features": [
"Ar condicionado",
"Direção elétrica",
"Freios ABS",
"Airbag"
],
"agent": {
"name": "João Silva",
"email": "joao@exemplo.com",
"phone": "+55 11 99999-9999"
},
"video": {
"url": "https://youtube.com/watch?v=...",
"embed": "<iframe>...</iframe>"
}
}
]💡 Importante: A API retorna um array direto onde cada item é um veículo completo.
{
"success": true,
"message": "Veículo criado com sucesso",
"id": 124,
"data": {
"id": 124,
"title": "Porsche 911 Turbo S",
"slug": "porsche-911-turbo-s",
"url": "https://seusite.com/cars/porsche-911-turbo-s",
...
}
}{
"success": true,
"message": "Veículo atualizado com sucesso",
"id": 123,
"data": {
"id": 123,
"title": "Ferrari F8 Tributo",
...
}
}{
"success": true,
"message": "Veículo deletado com sucesso",
"id": 123
}Token ausente:
{
"code": "rest_forbidden",
"message": "Token de autenticação ausente. Use o header Authorization: Bearer {token}",
"data": {
"status": 401
}
}Token inválido ou expirado:
{
"code": "rest_forbidden",
"message": "Token JWT inválido ou expirado.",
"data": {
"status": 401
}
}JWT_SECRET não configurado:
{
"code": "rest_forbidden",
"message": "JWT_SECRET não configurado no servidor.",
"data": {
"status": 500
}
}{
"code": "rest_forbidden",
"message": "API Key inválida ou ausente.",
"data": {
"status": 401
}
}{
"code": "not_found",
"message": "Veículo não encontrado.",
"data": {
"status": 404
}
}{
"code": "invalid_data",
"message": "Dados inválidos ou incompletos",
"data": {
"status": 400,
"errors": {
"title": "O título é obrigatório",
"price": "O preço deve ser numérico"
}
}
}Por padrão, o JSON é retornado em uma única linha (compacto) para melhor performance e economia de banda:
# Produção (compacto, rápido)
GET /wp-json/carz-api/v1/vehiclesResposta:
[{"id":123,"title":"Ferrari F8","price":"1500000"},{"id":124,"title":"Porsche 911","price":"1200000"}]Adicione ?pretty na URL para formatação legível com indentação (útil para desenvolvimento e debug):
# Debug (formatado, legível)
GET /wp-json/carz-api/v1/vehicles?prettyResposta:
[
{
"id": 123,
"title": "Ferrari F8",
"price": "1500000"
},
{
"id": 124,
"title": "Porsche 911",
"price": "1200000"
}
]💡 Dica: Use o modo pretty durante desenvolvimento e testes, mas remova em produção para melhor performance.
Cada veículo contém:
id,title,description,excerptslug,status,date,modified,url
featured_image- Imagem destacada (com 4 tamanhos)gallery- Array de imagens (com 4 tamanhos cada)
prices.price/price2prices.price_prefix/price2_prefix
taxonomies.maker- Fabricante(s)taxonomies.type- Tipo(s)taxonomies.status- Status
- Modelo, Ano, Quilometragem
- Combustível, Motor, Potência
- Transmissão, Tração, Portas, Assentos
- Cores, Condição, VIN, Data de registro
- Cidade, País, Endereço, Coordenadas
features- Características/equipamentosagent- Dados do vendedorvideo- URLs de vídeo
A API Key pode ser enviada de 2 formas:
No header HTTP (Recomendado):
X-API-Key: carz_1234567890abcdef...
Na query string:
?api_key=carz_1234567890abcdef...
Quando usar:
- Consultas públicas ou semi-públicas
- Integrações simples de leitura
- Dashboards e relatórios
- Aplicações frontend
O token JWT deve ser enviado no header Authorization:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Quando usar:
- Criar novos veículos
- Atualizar informações
- Deletar registros
- Upload de imagens
- Qualquer operação que modifique dados
Estrutura do token JWT:
{
"header": {
"typ": "JWT",
"alg": "HS256"
},
"payload": {
"user_id": 1,
"email": "admin@exemplo.com",
"iat": 1640000000,
"exp": 1640086400,
"iss": "https://seusite.com"
},
"signature": "..."
}Algoritmos suportados:
- HS256 (SHA-256) - Padrão
- HS384 (SHA-384)
- HS512 (SHA-512)
- ✅ Use HTTPS em produção (obrigatório)
- ✅ Configure um JWT_SECRET forte (mínimo 32 caracteres)
- ✅ NUNCA exponha seu
JWT_SECRETou API Key no código frontend - ✅ Gere tokens JWT com validade limitada (máximo 24h recomendado)
- ✅ Armazene tokens de forma segura (nunca em localStorage se possível)
- ✅ Regenere a API Key periodicamente (a cada 3-6 meses)
- ✅ Use variáveis de ambiente para armazenar chaves
- ✅ Implemente rate limiting para evitar abuso
- ✅ Habilite autenticação API Key mesmo para GET se os dados forem sensíveis
- ✅ Prefira autenticação por header em vez de query string
- ✅ Monitore logs de acesso à API
- ✅ Use CORS configurado corretamente
- ✅ Implemente refresh tokens para renovação automática
- ✅ Adicione IP whitelisting para endpoints críticos
- ✅ Use webhook signatures para validar origem de requisições
- ✅ Implemente two-factor authentication para geração de tokens
- ✅ Configure WAF (Web Application Firewall)
wp-config.php:
// JWT Secret (usar valor forte e único)
define('JWT_SECRET', 'K8mN2pQ5rS9tV3wX6zA4bC7dE0fG1hJ4kL8mN2pQ5rS9tV3');
// Opcional: Tempo de expiração do token (em segundos)
define('JWT_EXPIRATION', 86400); // 24 horas
// Opcional: CORS permitido
define('CARZ_API_CORS_ORIGIN', 'https://seuapp.com');Gerenciamento de Tokens:
// ❌ ERRADO - Nunca faça isso
const JWT_SECRET = 'meu-segredo'; // Exposto no frontend!
// ✅ CORRETO - Token gerado no backend e enviado ao frontend
// Backend gera o token
const token = generateJWT(userData, JWT_SECRET);
// Frontend apenas usa o token
fetch(url, { headers: { 'Authorization': `Bearer ${token}` } });Soluções:
- Salve as configurações novamente em Configurações > Paradigma API
- Clique em "Atualizar Permalinks"
- Verifique se não há conflito com outras regras de rewrite
- Teste o endpoint padrão do WordPress:
/wp-json/carz-api/v1/vehicles - Desative e reative o plugin
- Vá em Configurações > Permalinks e clique em "Salvar"
Problema: Header de autorização não está sendo enviado corretamente.
Soluções:
- Verifique se o header está no formato correto:
Authorization: Bearer {token} - Certifique-se de que há um espaço após "Bearer"
- Verifique se o servidor não está removendo o header Authorization (comum em alguns servidores Apache)
- Adicione ao
.htaccess(se Apache):
RewriteEngine On
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]Problema: Token expirado, inválido ou gerado com secret diferente.
Soluções:
- Verifique se o token não expirou (campo
expno payload) - Confirme que está usando o mesmo
JWT_SECRETdowp-config.php - Gere um novo token
- Verifique se o algoritmo é suportado (HS256, HS384, HS512)
- Use jwt.io para decodificar e validar o token
Problema: Variável JWT_SECRET não foi definida no wp-config.php.
Soluções:
- Abra o arquivo
wp-config.phpna raiz do WordPress - Adicione:
define('JWT_SECRET', 'sua-chave-forte-aqui'); - Certifique-se de que a linha está antes de
/* That's all, stop editing! */ - Salve o arquivo e teste novamente
Problema: API Key incorreta ou não foi enviada.
Soluções:
- Verifique se a autenticação está habilitada em Configurações > Paradigma API
- Confirme se a API Key está correta
- Teste com o header
X-API-Keyem vez de query string - Gere uma nova API Key através do painel admin
- Se não quiser autenticação para GET, desmarque "Requer Autenticação"
Soluções:
- Verifique se os posts estão com status "publish"
- Confirme se o CPT
cpt_carsestá registrado - Teste acessando o endpoint diretamente no navegador
- Verifique se não há filtros personalizados interferindo
- Desative outros plugins temporariamente para testar conflitos
Soluções:
- Instale e ative o TRX Addons
- Verifique se o Custom Post Type de Carros está habilitado no TRX Addons
- Acesse TRX Addons > Settings e ative o CPT "Cars"
Problema: Autenticação JWT não configurada ou token ausente.
Soluções:
- Configure o
JWT_SECRETnowp-config.php - Gere um token JWT válido
- Inclua o token no header:
Authorization: Bearer {token} - Verifique se o método HTTP está correto (POST, PUT, DELETE)
- Confirme que o Content-Type é
application/json
Problema: Cross-Origin Resource Sharing bloqueando a requisição.
Soluções:
- Verifique se está usando HTTPS
- O plugin já habilita CORS por padrão
- Se necessário, adicione ao
functions.phpdo tema:
add_filter('rest_pre_serve_request', function($served, $result, $request) {
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Authorization, Content-Type, X-API-Key');
return $served;
}, 10, 3);Soluções:
- Verifique permissões da pasta
/wp-content/uploads/ - Confirme que o token JWT está válido
- Verifique o tamanho máximo de upload no PHP (
upload_max_filesize) - Use
multipart/form-datano Content-Type para upload - Confira se a imagem está no formato suportado (jpg, png, gif, webp)
Problema: Por padrão, a API retorna JSON compacto para melhor performance.
Solução:
- Adicione
?prettyna URL para formatação legível:
/wp-json/carz-api/v1/vehicles?pretty
Habilitar logs de erro do WordPress:
- Edite
wp-config.php:
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);- Verifique logs em:
/wp-content/debug.log
Testar endpoints via cURL:
# GET com API Key
curl -H "X-API-Key: carz_abc123..." \
https://seusite.com/wp-json/carz-api/v1/vehicles
# POST com JWT
curl -X POST \
-H "Authorization: Bearer eyJhbGci..." \
-H "Content-Type: application/json" \
-d '{"title":"Teste","price":"100000"}' \
https://seusite.com/wp-json/carz-api/v1/vehiclesVerificar se JWT_SECRET está configurado:
// Executar em arquivo PHP temporário
<?php
require_once('wp-load.php');
echo defined('JWT_SECRET') ? 'JWT_SECRET está definido' : 'JWT_SECRET NÃO está definido';
?>- ✨ [BREAKING] Reescrita completa do plugin com foco em API REST moderna
- ✨ [NOVO] Suporte completo a métodos HTTP: GET, POST, PUT, DELETE
- ✨ [NOVO] Autenticação JWT para operações de escrita (POST/PUT/DELETE)
- Implementação nativa sem dependências externas
- Suporte a algoritmos HS256, HS384, HS512
- Validação de expiração automática
- ✨ [NOVO] Endpoints para CRUD completo de:
- Veículos (vehicles)
- Fabricantes (makers)
- Modelos (models)
- Recursos (features)
- Tipos (types)
- Status
- Labels
- Cidades (cities)
- Agentes (agents)
- Upload de mídia
- ✨ [NOVO] Autenticação API Key mantida para operações GET (retrocompatível)
- ✨ [NOVO] Gerador seguro de API Key (64 caracteres)
- ✨ [NOVO] Endpoint personalizado configurável
- ✨ [NOVO] CORS habilitado para requisições cross-origin
- ✨ [NOVO] Pretty print opcional com
?pretty - ✨ [NOVO] Coluna de status na lista de carros
- 🔧 [MELHORIA] Interface administrativa completamente reformulada
- 🔧 [MELHORIA] Documentação expandida com exemplos JWT
- 🔧 [MELHORIA] Tratamento de erros mais detalhado
- 🔧 [MELHORIA] Validação de dados aprimorada
- 📚 [DOCS] Guia completo de autenticação JWT
- 📚 [DOCS] Exemplos de uso com múltiplas linguagens
- 📚 [DOCS] Workflows n8n para operações CRUD
- ✅ API REST básica para listagem de veículos via GET
- ✅ Autenticação opcional com API Key
- ✅ Sincronização com API externa (removida na v2.0.0)
Para suporte, abra uma issue no repositório ou entre em contato.
- JWT.io - Decodificar e validar tokens JWT: https://jwt.io
- JSON Formatter - Validar e formatar JSON: https://jsonformatter.org
- Postman - Testar endpoints REST API: https://www.postman.com
- n8n - Automação de workflows: https://n8n.io
- Random.org - Gerar chaves aleatórias seguras: https://www.random.org/strings/
GPL v2 ou posterior.
🚗 Paradigma REST API - Desenvolvido para o tema Carz
Versão 2.0.0 | by UnkDev | paradigma.lat