Moovyi · API de Parceiros

Guia de Integração — Feed de Veículos

Como enviar o catálogo de veículos das suas revendas para a Moovyi. Envio por HTTP, autenticado, com processamento assíncrono.

URL base: https://moovyi-api-production.up.railway.app/api/v1

1 O que você recebe da Moovyi

Antes de começar, a Moovyi te entrega três coisas:

🔑
Token de acesso Uma chave secreta no formato mvp_.... Trate como senha — não compartilhe.
🌐
URL base da API https://moovyi-api-production.up.railway.app/api/v1
🏷️
Lista de 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:

HTTP header
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 & rotaPara 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

externalDealershipId externalVehicleId brand model yearFab yearModel color mileage price

Exemplo completo

POST /partner-feed/vehicles  ·  JSON
{
  "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

200 · 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)

CampoValores
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.
  • yearModel não pode ser menor que yearFab.
  • Se isPromotion: true, mande promoPrice.
  • 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).
  • status não aceita SOLD. Vendeu / saiu do estoque? Use DELETE ou mande status: "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 no sync.

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:

POST /partner-feed/vehicles/sync  ·  JSON
{
  "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 · requisição
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

bash
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

bash
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çãoO que acontece
Sem token / token errado401
externalDealershipId não combinado com a Moovyiveículo em rejected[] com DEALERSHIP_NOT_MAPPED
Revenda com assinatura Moovyi inativarejected[] com TENANT_INACTIVE — regularize a assinatura e reenvie
Campo fora do guia / enum inválido400 (ou o item em rejected[])
price em reais em vez de centavosaceito errado — sempre confira!
Faltou campo obrigatórioveículo em rejected[] com o motivo

11 Dúvidas frequentes

Com que frequência posso enviar?
Quando quiser, respeitando os limites por requisição. Mudou o preço de um carro? Reenvie ele com o mesmo externalVehicleId.
Reenviar o mesmo carro sem mudança faz mal?
Não — detectamos que nada mudou e ignoramos (idempotente).
Preciso mandar todos os campos sempre?
Os obrigatórios sim; os demais, quando tiver. Quanto mais completo, melhor o anúncio.