1 O que você recebe da Moovyi
Antes de começar, a Moovyi te entrega três coisas:
mvp_.... Trate como senha — não compartilhe.
https://moovyi-api-production.up.railway.app/api/v1
externalDealershipId
Os identificadores de cada revenda (combinados entre você e a Moovyi).
2 Autenticação
Toda requisição leva o header de autorização com o seu token:
Authorization: Bearer SEU_TOKEN_AQUI
Sem o header, ou com token errado/revogado, a resposta é 401 Unauthorized.
3 Endpoints
Todos sob a URL base + /partner-feed.
| Método & rota | Para quê |
|---|---|
POST /partner-feed/vehicles |
Enviar (criar/atualizar) de 1 a 200 veículos por vez. |
POST /partner-feed/vehicles/sync |
Enviar o catálogo completo de uma revenda — o que faltar é arquivado. |
DELETE /partner-feed/vehicles/{externalVehicleId} |
Dar baixa em um veículo (sai da vitrine). |
Sucesso é sempre 202 Accepted — significa "recebido, vou processar". O processamento acontece logo em seguida.
4 Enviar veículos
POST /partner-feed/vehicles — corpo com a lista vehicles (máx. 200 por requisição; se tiver mais, mande em vários lotes).
Campos obrigatórios
Exemplo completo
{
"vehicles": [
{
// === IDENTIFICAÇÃO (sempre obrigatórios) ===
"externalDealershipId": "REV-00123", // qual revenda (id combinado com a Moovyi)
"externalVehicleId": "VEIC-98765", // id do carro no SEU sistema (chave de deduplicação)
// === OBRIGATÓRIOS ===
"brand": "Toyota",
"model": "Corolla XEi 2.0",
"yearFab": 2023, // ano de fabricação
"yearModel": 2024, // ano do modelo (precisa ser >= yearFab)
"color": "Prata",
"mileage": 45000, // km rodados (inteiro, >= 0)
"price": 12500000, // ⚠️ EM CENTAVOS — veja o item 6
// === RECOMENDADOS (melhoram o anúncio) ===
"version": "XEi 2.0 Flex",
"fuel": "flex", // valores no item 5
"transmission": "automatic", // valores no item 5
"bodyType": "sedan", // valores no item 5
"condition": "USED", // NEW | USED | CERTIFIED (padrão: USED)
"vehicleType": "CAR", // CAR | MOTORCYCLE (padrão: CAR)
"images": [ // URLs públicas, no mínimo 800x600 px
"https://cdn.seusite.com/veic98765/1.jpg",
"https://cdn.seusite.com/veic98765/2.jpg"
],
// === OPCIONAIS ===
"plate": "ABC1D23", // opcional; uso interno, nunca aparece na vitrine
"promoPrice": 11900000, // centavos (se em promoção)
"isPromotion": true, // se true, promoPrice é obrigatório
"description": "Único dono, revisões em dia.",
"videoUrl": "https://youtube.com/watch?v=...", // YouTube ou Vimeo
"doors": 4, // 2 a 6
"power": 170, // cavalos (1 a 2000)
"engineSize": 2000, // cilindrada em cc (50 a 10000)
"features": ["Ar condicionado", "Airbag", "ABS"], // até 50
"tags": ["seminovo", "família"], // até 20
"origin": "Nacional",
"previousOwners": 1,
"lastRevisionDate": "2024-06-15", // formato YYYY-MM-DD
"ipvaPaid": true,
"licensed": true,
"warrantyUntil": "2026-12-31", // formato YYYY-MM-DD
"status": "AVAILABLE" // AVAILABLE | RESERVED | ARCHIVED (padrão AVAILABLE)
}
]
}
Resposta
{
"batchId": "9b9a...-...", // id do lote (para referência)
"accepted": 2, // quantos foram aceitos e enfileirados
"rejected": [ // os que falharam na validação — o lote NÃO cai por causa deles
{
"externalVehicleId": "VEIC-99999",
"errors": ["Revenda \"REV-XYZ\" não mapeada (DEALERSHIP_NOT_MAPPED)."]
}
]
}
Um veículo inválido entra em rejected[] com o motivo — os demais do lote seguem normalmente.
5 Valores aceitos (enums)
| Campo | Valores |
|---|---|
fuel | flexgasolineethanoldieselelectrichybridplugin_hybridgnv |
transmission | manualautomaticcvtautomateddct |
bodyType(carro) | hatchsedansuvpickupcoupeconvertiblewagonvanminivancrossover |
bodyType(moto) | streetscooternakedsporttrailbig_trailcruisertouringoff_road |
condition | NEWUSEDCERTIFIED |
vehicleType | CARMOTORCYCLE |
status | AVAILABLERESERVEDARCHIVED |
Aceitamos e normalizamos variações comuns — ex.: "gasolina"→gasoline, "aut"→automatic, "VW - VolksWagen"→Volkswagen, "Preta"→Preto. Mas o ideal é mandar os valores da tabela.
6 Regras importantes
price e promoPrice são em CENTAVOS. R$ 125.000,00 = 12500000.
Esse é o erro nº 1. Mandar em reais deixa o preço 100× errado — e não é rejeitado (é aceito errado). Confira sempre.
- Mande só os campos deste guia. Um campo desconhecido faz a requisição inteira ser rejeitada com
400. Nada de campos "extras". externalVehicleIdé a sua chave. Reenviar o mesmo id atualiza o carro (não duplica). É assim que você manda mudança de preço, correção, etc.yearModelnão pode ser menor queyearFab.- Se
isPromotion: true, mandepromoPrice. - Imagens: URLs públicas, no mínimo 800×600 px. A primeira vira a foto principal. Nós baixamos e re-hospedamos; imagem menor é descartada (o carro continua, só sem aquela foto).
statusnão aceitaSOLD. Vendeu / saiu do estoque? UseDELETEou mandestatus: "ARCHIVED". Vendas são geridas dentro da Moovyi — o feed nunca "revende" nem reverte uma venda registrada lá.- Placa é opcional. Carro 0km / sem placa é aceito normalmente (a deduplicação é pelo
externalVehicleId). - Limite por requisição: 200 veículos no
POST /vehicles; 2000 nosync.
7 Sincronizar o catálogo completo
POST /partner-feed/vehicles/sync — mande o estoque inteiro de uma revenda de uma vez.
Os veículos daquela revenda que não vierem neste envio são arquivados automaticamente (saem da vitrine). É a forma de dizer "esses são exatamente os carros que a revenda tem agora". Aqui a revenda vai no topo (uma vez), não em cada item:
{
"externalDealershipId": "REV-00123",
"vehicles": [
{ "externalVehicleId": "VEIC-1", "brand": "...", "model": "...", "yearFab": 2022, "yearModel": 2023, "color": "...", "mileage": 30000, "price": 8000000 },
{ "externalVehicleId": "VEIC-2", "brand": "...", "model": "...", "yearFab": 2021, "yearModel": 2021, "color": "...", "mileage": 50000, "price": 6500000 }
]
}
Resposta: 202 com { batchId, accepted, archived, rejected } — o archived diz quantos foram arquivados por não estarem no envio.
Não mande catálogo vazio (vehicles: []) — é rejeitado de propósito, para não arquivar a loja inteira por engano. Para tirar carros um a um, use DELETE.
8 Dar baixa em um veículo
DELETE /partner-feed/vehicles/{externalVehicleId}
DELETE /api/v1/partner-feed/vehicles/VEIC-98765
Authorization: Bearer SEU_TOKEN
O carro é arquivado (sai da vitrine). É reversível: se você reenviar o mesmo externalVehicleId num POST /vehicles depois, ele volta.
9 Exemplos com curl
Enviar um veículo
curl -X POST "https://moovyi-api-production.up.railway.app/api/v1/partner-feed/vehicles" \
-H "Authorization: Bearer SEU_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"vehicles": [{
"externalDealershipId": "REV-00123",
"externalVehicleId": "VEIC-98765",
"brand": "Toyota", "model": "Corolla XEi 2.0",
"yearFab": 2023, "yearModel": 2024,
"color": "Prata", "mileage": 45000, "price": 12500000,
"fuel": "flex", "transmission": "automatic", "bodyType": "sedan",
"images": ["https://cdn.seusite.com/veic98765/1.jpg"]
}]
}'
Dar baixa
curl -X DELETE "https://moovyi-api-production.up.railway.app/api/v1/partner-feed/vehicles/VEIC-98765" \
-H "Authorization: Bearer SEU_TOKEN"
10 Erros mais comuns
| Situação | O que acontece |
|---|---|
| Sem token / token errado | 401 |
externalDealershipId não combinado com a Moovyi | veículo em rejected[] com DEALERSHIP_NOT_MAPPED |
| Revenda com assinatura Moovyi inativa | rejected[] com TENANT_INACTIVE — regularize a assinatura e reenvie |
| Campo fora do guia / enum inválido | 400 (ou o item em rejected[]) |
price em reais em vez de centavos | aceito errado — sempre confira! |
| Faltou campo obrigatório | veículo em rejected[] com o motivo |
11 Dúvidas frequentes
Com que frequência posso enviar?
externalVehicleId.