Zokko Motor · API v1

API de Inventario para Concesionarios

Conecta tu DMS con Zokko y mantén todo tu stock sincronizado en automático. Sube tu inventario por lotes, refléjalo como un espejo de tu sistema o deja que Zokko lo traiga de tu feed XML. REST, JSON y una clave por concesionario.

Introducción

La API de inventario te permite publicar y mantener tu catálogo de vehículos en Zokko desde tu propio software de gestión (DMS, ERP o un script). Cada vehículo se identifica por una referencia única —el id de stock de tu sistema— de modo que las llamadas son idempotentes: si la referencia ya existe, se actualiza; si es nueva, se crea. Nunca duplica.

Los anuncios publicados por la API quedan automáticamente marcados como profesionales (con el sello de concesionario), atribuidos a tu ficha y a tu cuenta. No tienes que indicar el tipo de vendedor: se deriva de tu cuenta.

  • Base URL: https://zokko.es
  • Formato: JSON (request y response) · Content-Type: application/json
  • Versión: v1 (prefijo /api/v1/dealer)
  • Dos modos de integración: push (tú llamas a la API) o pull (Zokko trae tu feed XML).

Autenticación

Todas las llamadas de inventario se autentican con una clave de API por concesionario en la cabecera Authorization:

Authorization: Bearer zkd_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxx

Cómo conseguir tu clave

  1. Entra en tu panel profesional con tu cuenta de concesionario.
  2. Abre la sección «API e integraciones» y pulsa «Generar clave».
  3. Copia la clave zkd_live_… que aparece. Solo se muestra una vez; guárdala en un sitio seguro.

La clave se guarda hasheada (SHA-256) en nuestros servidores: nadie —ni Zokko— puede volver a verla. Si la pierdes, revócala y genera una nueva. Trátala como una contraseña: nunca la publiques en repos, apps cliente ni capturas. Puedes tener hasta 5 claves activas por concesionario y revocar cualquiera al instante.

Errores de autenticación

401

Falta la clave, no es válida o ha sido revocada.

403

El concesionario está desactivado.

Quickstart

Sube tus dos primeros coches en menos de un minuto. Sustituye zkd_live_… por tu clave real:

cURL
curl -X POST https://zokko.es/api/v1/dealer/vehicles \
  -H "Authorization: Bearer zkd_live_xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "vehicles": [
      {
        "reference": "REF-A1",
        "make": "Cupra",
        "model": "Leon",
        "version": "VZ",
        "price": 28900,
        "year": 2022,
        "mileage_km": 15000,
        "fuel": "gasolina",
        "transmission": "automatico",
        "city": "Bilbao",
        "region": "País Vasco",
        "images": ["https://tu-dms.com/fotos/refa1-1.jpg"]
      }
    ]
  }'
Respuesta · 200 OK
{
  "success": true,
  "summary": { "total": 1, "created": 1, "updated": 0, "errors": 0 },
  "results": [
    { "reference": "REF-A1", "status": "created", "id": 747, "photos": 1, "photos_failed": 0 }
  ]
}

Vuelve a lanzar la misma llamada cambiando el price: verás "status": "updated" y "updated": 1. La reference es la clave de la sincronización.

Campos del vehículo

Cada vehículo del array vehicles acepta los siguientes campos. Solo cuatro son obligatorios; el resto se sanea y normaliza. Un ítem inválido se devuelve con status: "error" sin tumbar el resto del lote.

CampoTipoReq.Descripción
referencestringTu id de stock del DMS. Único por concesionario. Es la clave del upsert.
makestringMarca. Ej. Cupra.
modelstringModelo. Ej. Leon.
priceintegerPrecio en euros, entero ≥ 0.
versionstringNoAcabado / versión. Ej. VZ.
yearintegerNoAño de matriculación.
mileage_kmintegerNoKilómetros.
fuelstringNoTexto libre, se normaliza: gasolina, diesel, electrico, hibrido, hibrido_enchufable, glp, gnc, hidrogeno.
transmissionstringNoTexto libre: manual o automatico (auto/dsg/dct… → automatico).
body_typestringNoCarrocería. Ej. berlina, suv.
doorsintegerNoNº de puertas.
seatsintegerNoNº de plazas.
power_cvintegerNoPotencia en CV.
colorstringNoColor.
platestringNoMatrícula.
vinstringNoBastidor (VIN).
descriptionstringNoDescripción comercial (hasta 8.000 caracteres).
imagesstring[]NoURLs de fotos externas (máx. 20). Se descargan y re-suben a Zokko. Ver ingesta de fotos.
citystringNoCiudad donde está el vehículo.
regionstringNoProvincia / comunidad.
statusstringNoavailable → publicado. Cualquier otro (sold, reserved, withdrawn…) → archivado.

Subir / actualizar inventario (lote)

POST/api/v1/dealer/vehicles

Crea o actualiza vehículos por reference. Acepta { "vehicles": [...] } o directamente un array [...] (máximo 200 por llamada). No retira nada: solo toca lo que envías.

cURL
curl -X POST https://zokko.es/api/v1/dealer/vehicles \
  -H "Authorization: Bearer zkd_live_xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '[
    { "reference": "REF-A1", "make": "Cupra", "model": "Leon", "price": 28900 },
    { "reference": "REF-B2", "make": "Seat",  "model": "Ibiza", "price": 14500 }
  ]'
Respuesta · 200 OK
{
  "success": true,
  "summary": { "total": 2, "created": 2, "updated": 0, "errors": 0 },
  "results": [
    { "reference": "REF-A1", "status": "created", "id": 747, "photos": 0, "photos_failed": 0 },
    { "reference": "REF-B2", "status": "created", "id": 748, "photos": 0, "photos_failed": 0 }
  ]
}

HTTP: 200 (todo OK) · 207 (mixto: algunos OK, algunos error) · 422 (todos error) · 400 (body inválido). Cada ítem con error devuelve { "reference", "status": "error", "error" }.

Sincronizar inventario completo (espejo del DMS)

POST/api/v1/dealer/vehicles/sync

El array que envías es tu inventario completo. Zokko crea/actualiza los que mandas y retira automáticamente (archiva) los que ya no aparezcan. Es la forma recomendada para que Zokko sea un espejo fiel de tu DMS.

Envía siempre el stock entero en este endpoint. Si mandas solo una parte, todo lo ausente se archivará. Para actualizaciones parciales usa POST /api/v1/dealer/vehicles.

Respuesta · 200 OK
{
  "success": true,
  "summary": { "total": 120, "created": 4, "updated": 116, "retired": 3, "errors": 0 },
  "retired_references": ["REF-OLD-1", "REF-OLD-2", "REF-OLD-3"],
  "results": [ /* un objeto por vehículo enviado */ ]
}

Listar tu inventario

GET/api/v1/dealer/vehicles?status=published&limit=50&offset=0

Devuelve el inventario que tienes en Zokko. Parámetros: status = published | archived | all (por defecto published), limit y offset para paginar.

curl https://zokko.es/api/v1/dealer/vehicles?status=published&limit=50 \
  -H "Authorization: Bearer zkd_live_xxxxxxxxxxxxxxxx"
Respuesta · 200 OK
{
  "success": true,
  "total": 118, "count": 50, "limit": 50, "offset": 0,
  "vehicles": [
    {
      "reference": "REF-A1", "id": 747, "status": "published",
      "title": "Cupra Leon VZ", "make": "Cupra", "model": "Leon",
      "version": "VZ", "year": 2022, "price": 28900, "mileage_km": 15000,
      "fuel": "gasolina", "transmission": "automatico",
      "city": "Bilbao", "region": "País Vasco",
      "image_cover_url": "/api/uploads/motor/dealer-1718-ab12.webp",
      "images": ["/api/uploads/motor/dealer-1718-ab12.webp"],
      "url": "https://zokko.es/motor/coche/cupra-leon-vz-747"
    }
  ]
}

Ver un vehículo por referencia

GET/api/v1/dealer/vehicles/{reference}

Devuelve un único vehículo en el formato de salida, o 404 si esa referencia no existe en tu inventario.

curl https://zokko.es/api/v1/dealer/vehicles/REF-A1 \
  -H "Authorization: Bearer zkd_live_xxxxxxxxxxxxxxxx"

Retirar un vehículo

DELETE/api/v1/dealer/vehicles/{reference}

Retira (archiva) el vehículo: deja de mostrarse a los compradores pero la operación es reversible (vuelve a publicarse si lo subes otra vez con status: "available").

Respuesta · 200 OK
{ "success": true, "reference": "REF-A1", "status": "archived", "id": 747 }

Cuenta y plan

GET/api/v1/dealer/account

Comprueba qué concesionario resuelve tu clave, tu plan y cuántos coches tienes publicados / archivados. Útil para validar la integración.

Respuesta · 200 OK
{
  "success": true,
  "dealer": { "id": 12, "name": "Autos Bilbao", "slug": "autos-bilbao", "verified": true, "city": "Bilbao", "region": "País Vasco", "profile_url": "https://zokko.es/motor/coches/autos-bilbao" },
  "plan": { "account_type": "dealer", "plan": "pro", "plan_key": "pro", "status": "active", "max_listings": 200, "period_end": null },
  "vehicles": { "published": 118, "archived": 7, "total": 125 }
}

Feed XML automático (modo pull)

Si tu DMS ya publica tu inventario como un XML en una URL (formato coches.net, StandVirtual o el genérico de tu sistema), no necesitas escribir código: dile a Zokko dónde está tu feed y nosotros lo traemos y sincronizamos como un espejo (crea, actualiza y retira lo ausente), automáticamente a diario.

Configurarlo desde el panel

  1. En tu panel profesional → API e integraciones, pega la URL de tu feed en «URL de tu feed XML» y guarda.
  2. Pulsa «Sincronizar ahora» para la primera importación. Verás la última sincronización y el resultado (creados / actualizados / retirados / errores).

O por API, con tu clave

PUT/api/v1/dealer/feed
curl -X PUT https://zokko.es/api/v1/dealer/feed \
  -H "Authorization: Bearer zkd_live_xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://tu-dms.com/zokko-feed.xml", "format": "xml" }'
GET/api/v1/dealer/feed — consulta config + último estado
POST/api/v1/dealer/feed/sync — fuerza una sincronización ahora
Respuesta de /feed/sync · 200 OK
{
  "success": true, "source": "feed_xml",
  "feed_url": "https://tu-dms.com/zokko-feed.xml", "parsed": 120,
  "summary": { "total": 120, "created": 4, "updated": 116, "retired": 2, "errors": 0 },
  "retired_references": ["REF-OLD-1", "REF-OLD-2"]
}

Formato del feed XML

El parser es flexible: reconoce las etiquetas habituales de los feeds del sector (coches.net / StandVirtual / genéricos). Lo esencial es un elemento por vehículo con su referencia, marca, modelo y precio. Ejemplo mínimo válido:

<?xml version="1.0" encoding="UTF-8"?>
<vehicles>
  <vehicle>
    <reference>REF-A1</reference>
    <make>Cupra</make>
    <model>Leon</model>
    <version>VZ</version>
    <price>28900</price>
    <year>2022</year>
    <mileage_km>15000</mileage_km>
    <fuel>gasolina</fuel>
    <transmission>automatico</transmission>
    <city>Bilbao</city>
    <region>País Vasco</region>
    <status>available</status>
    <images>
      <image>https://tu-dms.com/fotos/refa1-1.jpg</image>
      <image>https://tu-dms.com/fotos/refa1-2.jpg</image>
    </images>
  </vehicle>
</vehicles>

El feed se trata siempre como inventario completo (espejo): los vehículos que dejen de aparecer en el XML se archivan en la siguiente sincronización. Las etiquetas de marca/modelo/precio/fotos admiten varios nombres equivalentes según el estándar de tu DMS; con los de arriba funciona seguro.

Ingesta de fotos

Las URLs de images[] (o las del feed XML) se descargan y re-suben a la infraestructura de Zokko con el mismo procesado que las subidas manuales: rotación según EXIF, redimensionado a ≤ 1600 px y conversión a WebP de calidad optimizada. No guardamos la URL externa: la portada y la galería quedan servidas desde Zokko (p. ej. /api/uploads/motor/dealer-….webp).

  • Máximo 20 fotos por vehículo.
  • Cada imagen: timeout de descarga 15 s, máx. 15 MB, debe ser un content-type de imagen.
  • Si una foto falla, se descarta y se sigue: lo verás en photos_failed del resultado.

Códigos de estado

200

Todo correcto.

207

Multi-status: parte de los ítems se procesaron, parte dieron error. Revisa results.

400

Body inválido (no es JSON, falta vehicles, etc.).

401

Clave ausente, no válida o revocada.

403

Concesionario desactivado.

404

Referencia no encontrada (GET/DELETE de un vehículo).

422

Todos los ítems del lote eran inválidos.

429

Has superado el rate-limit. Espera un momento.

502

El feed XML no se pudo descargar o leer (solo en /feed/sync).

Todas las respuestas de error tienen la forma { "success": false, "error": "mensaje legible" }.

Límites y rate-limit

LímiteValor
Peticiones por minuto y clave120
Vehículos por llamada (lote / sync)200
Fotos por vehículo20
Tamaño máximo por foto15 MB
Claves activas por concesionario5
Longitud de la descripción8.000 caracteres

Al superar el rate-limit recibirás un 429. Cada respuesta incluye cabeceras estándar RateLimit-* para que tu cliente pueda regularse.

Soporte

¿Dudas con tu integración, tu DMS no exporta XML, o necesitas ayuda con el mapeo de campos? Estamos para ayudarte.