Para Apps de replicación/multi-posting
Para gestionar agencias y mantener publicaciones son 3 las informaciones que verás más de frecuente en las URLs:
-
{adminmail}
Es el e-mail address que identifica el administrador de una cuenta de agencia. Con el {adminmail} en una path de un endpoints accede a la información de una agencia. -
{operador}
Es el e-mail de un colaborador de una agencia. En una agencia pueden colaborar varios sujetos con distintos roles/responsabilidades.
Cuando publicas un auto, si no aclaras el OperadorResponsable asumiremos que es el mismo que administra la cuenta de la agencia, del mismo modo que si no aclaras la Locacion del {operador} asumiremos alguna dirección de dicho {operador}.
Cuando accedes a la información (publicaciones/consultas/visitas etc.) siempre te pediremos el {adminmail} y podrás filtrar por {operador}. -
{externalid}
Es el ID que tu app asignó a una publicación.
Para nosotros será case-insesitive y, ya que lo usaremos en path, admite solo caracteres compatibles con valores admitidos en un path-segment de una URL (https://www.w3.org/Addressing/URL/5_URI_BNF.html) excluyendo algún otro carácter que nos resultan "poco sano".
Así como no se modifican los IDs en tu app, tampoco esperamos que lo cambies para publicar en Autocosmos. Si al publicar te contestamos con un 409 y tú decides cambiar levemente tu ExternalId para forzar la publicación, si no tienes suerte (o sea si no te bloqueamos con 400) y hasta que generes lio solo para la agencia no pasa nada, pero, si el lío se refleja en decenas/centenas/miles de publicaciones abandonadas en Autocosmos, te bloquearemos el acceso a la API, archivaremos todas las publicaciones que nos parezcan y si alguien de la empresa por la cual trabajas se quiere contactar lo atenderemos (antes de generar semejante lío, puedes escribirnos y lo charlamos entre developers).
En Autocosmos las publicaciones tienen tres estados:
- Activa
- Suspendida
- Archivada
Una vez Archivada la publicación, y con ella tu ExternalId, terminó su ciclo de vida o sea que no podrá ser modificada y no podrás usar el mismo ExternalId para otra publicación en la misma agencia.
Es importante que entienda este punto. Si quieres que una publicación no quede más accesible/consultable por un tiempo determinado (hay una reserva para ese auto, se está reevaluando el precio etc.) lo que tienes que hacer es suspender la publicación.
Si el auto se vendió y/o ya no es interés de la agencia volver a gestionar la publicación, usarás el archivar.
Agregar cuenta (agencia, concesionario, automotriz)
Cuando tengas tu AppKey y AppSecret, según los acuerdos comerciales que obtengas, es posible que tengas acceso a la posibilidad de invitar agencias y concesionarios a tener su account en Autocosmos. Leyendo la documentación del endpoint de invitación notarás que, entre los responses, están:
-
409 (Conflict)
El 409 te informa que el email que asignaste a la propidad AdminMail ya está registrado en Autocosmos. Si tu app no tiene acceso a la información de la cuenta, la persona trás el email deberá ponerse en contacto con nuestro servicio de atención al cliente para que se gestione el caso y, eventualmente, se otorgue el permiso de acceso a tu app. Si quieres evitar recibir un 409 y controlar si tienes el permiso de POST siempre podrás usar el HTTP-Method
OPTIONS
con la URL del mismo endpoint que usas para elGET
de la información de una agencia. NOTA: si al usuario, o a algún fantasioso personal de soporte, se le ocurre cambiar el email de invitación, y terminar teniendo dos cuentas activas, lo más probable que suceda es que se bloqueen todas las cuentas que haya creado (no está demás aclararlo). -
202 (Accepted)
El 202 te indica que Autocosmos aceptó tu pedido de invitación. En este caso se envía un e-mail al address que asignaste a la propidad AdminMail de forma que, la persona trás el email, pueda seguir el proceso de registración. En el procedimiento de registración por invitación, el usuario podrá cambiar toda la información, que proporcionaste en la invitación, excepto el e-mail-address. Según el país, en el que se está registrando, es posible que, además de la aceptación de los términos y condiciones, se le pida también la verificación del teléfono. El usuario podrá verificar el teléfono, cuando quiera, también entrando a su cuenta en Autocosmos.
Si fué pedida la verificación del teléfono y el usuario no la completa tu app no podrá publicar.
Como hace tu app a saber si el usuario terminó el proceso de registración
Hay dos formas para conocer si el usuario aceptó la invitación:
-
En el response con 202 te enviamos el header
Location
con la URL para verificar la conclusión. Cuando lo consideres oportuno (evita el polling cada 5") podrás acceder al endpoint, informado en el headerLocation
, usando el HTTP-MethodOPTIONS
y verificando el headerAllow
, o usando el HTTP-MethodGET
y controlando el HTTP-StatusCode. -
Puedes suscribirte al webhook, para tu app, y recibir la callback en el momento que se efectúe la registración.
El topic del webhook es
invitacionagencia_aceptada
y la información que te enviaremos la puedes ver en la sección de payloads de la documentación de nuestros WebHooks.
OPTIONS
, verificando el header Allow
,
o usar el HTTP-Method POST
controlando el HTTP-StatusCode (un 4xx según corresponda).
Publicar
Teniendo marca+modelo+versión+año+carrocería+propulsion+transmisión es probable que logres publicar un auto con un solo request, pero ya que somos conscientes de los temas que enumeramos anteriormente,
en realidad, no nos esperamos que hagas ni menos ni más de dos requests. Tu sabrás cuantas diferencias hay entre tus datos y los nuestros y evaluarás como proceder; si ves que necesitas más de dos requests y quieres que evaluemos juntos el problema, escribinos.
- Un request para buscar si hay una versión de auto que coincida a lo que estás publicando
- Un request para publicar
1. Búsqueda de marca+modelo+versión
El endpoint para la búsqueda de una versión para publicar es el siguiente:
/v3/versiones/bestmatch?make={make}&model={model}&trim={trim}&year={year}&bodystyle={bodystyle}&transmissionType={transmissionType}&displacement={displacement}&power={power}&fuelType={fuelType}
Vamos a buscar un BMW Serie 3 del 2009 (así como la llamaría un cualquier vecino). Estas tres informaciones no suelen ser suficientes para poder publicar para la mayoría de las marcas.
Si buscamos make=bmw&model=serie 3&trim=pizza&year=2009
puedes obtener un resultado tipo:
{ "Make": "/v3/marcas/603", "Model": "/v3/modelos/10081", "Trim": "pizza", "FuelType": "gasolina", "TransmisionType": "Manual", "Match": null }
make=bmw&model=serie 3&trim=pizza&year=2009&bodystyle=coupe
:
{ "Make": "/v3/marcas/603", "Model": "/v3/modelos/10080", "Trim": "pizza", "FuelType": "gasolina", "TransmisionType": "Manual", "Match": null }
Model
y si usas estos datos, como veremos después, ya podrás publicar el auto.Cambiamos solo trim con algo más cercano a la realidad
make=bmw&model=serie 3&trim=executive&year=2009&bodystyle=coupe
:
{ "Make": "/v3/marcas/603", "Model": "/v3/modelos/10080", "Trim": "/v3/versiones/149478", "FuelType": "gasolina", "TransmisionType": "Manual", "Match": { "Propulsion": "gasolina", "Transmision": "Manual "Potencia": "156 cv "Cilindrada": "2.0L "Marca": "BMW "Modelo": "Serie 3 Coupé", "Nombre": "320i Executive", "Codename": "320i-executive", "Carroceria": "Coupé", "Segmento": "", "_links": { "self": { "href": "/v3/versiones/149478" } } } }
Si prestas atención en ningún caso coincide exactamente el nombre de la versión y en los últimos dos casos tampoco coincide el nombre del modelo.
Vamos con algo un poco más extremo, y que tal vez sea lo que termines usando, sin nada de trim pero agregando power
make=bmw&model=serie%203&year=2009&bodystyle=coupe&power=156cv
:
{ "Make": "/v3/marcas/603", "Model": "/v3/modelos/10080", "Trim": "/v3/versiones/149478", "FuelType": "gasolina", "TransmisionType": "Manual", "Match": { "Propulsion": "gasolina", "Transmision": "Manual", "Potencia": "156 cv", "Cilindrada": "2.0L", "Marca": "BMW", "Modelo": "Serie 3 Coupé", "Nombre": "320i Executive", "Codename": "320i-executive", "Carroceria": "Coupé", "Segmento": "", "_links": { "self": { "href": "/v3/versiones/149478" } } } }
make=bmw&model=serie 3&year=2009&bodystyle=coupe&power=306cv
:
{ "Make": "/v3/marcas/603", "Model": "/v3/modelos/10080", "Trim": "/v3/versiones/154451", "FuelType": "gasolina", "TransmisionType": "Manual", "Match": { "Propulsion": "gasolina", "Transmision": "Manual", "Potencia": "306 cv", "Cilindrada": "3.0L", "Marca": "BMW", "Modelo": "Serie 3 Coupé", "Nombre": "335i Sportive", "Codename": "335i-sportive", "Carroceria": "Coupé", "Segmento": "", "_links": { "self": { "href": "/v3/versiones/154451" } } } }
make=bmw&model=serie 3&year=2009&bodystyle=convertible&power=306cv
:
{ "Make": "/v3/marcas/603", "Model": "/v3/modelos/10079", "Trim": "/v3/versiones/127560", "FuelType": "gasolina", "TransmisionType": "Manual", "Match": { "Propulsion": "gasolina", "Transmision": "Manual", "Potencia": null, "Cilindrada": null, "Marca": "BMW", "Modelo": "Serie 3 Convertible", "Nombre": "330Ci Executive", "Codename": "330ci-executive", "Carroceria": "Convertible", "Segmento": "D", "_links": { "self": { "href": "/v3/versiones/127560" } } } }
Tal vez, en futuro, dejaremos que tú le enseñes a encontrar lo que necesites usando solo tu información...tendremos que hablar un poco pero es factible.
Hasta ahora quisimos que te concentrara en el
Match
del bestmatch de versiones y por eso te ocultamos una propiedad más que verás en el response; la propiedad Candidates
.Por más que lo intentemos, lo nuestro no es hacer milagros y las máquinas, por más que les enseñemos, van a seguir siendo solo estupidas rápidas. Quisiéramos que la publicación se mantenga en no más de dos requests así que, haya o no haya match, si encontramos por lo menos un modelo, intetaremos siempre devolverte una lista de versiones candidatas para que, eventualmente, tú busques la más apropiada a tu caso.
Candidates
trasforma el bestmatch de versiones en la herramienta de búsqueda en el catálogo de Autocosmos; si Candidates
está vacía es poco útil que intentes downloads masivos del catálogo, será mucho más conveniente ajustar tu información de búsqueda.
2. Publicar
Como habrás notado el bestmatch de versiones devuelve una serie de informaciones y, en algún caso ves url-path y en otros texto simple.
A menos que tengas un null
en la propiedad Trim
, la información devuelta por el bestmatch de versiones es la que deberías usar as is para publicar.
El endpoint para publicar es /v3/publicaciones/{adminmail} y la asignación es la siguiente:
Modelo = bestmatch.Model
Version = bestmatch.Trim
Transmision = bestmatch.TransmisionType
Propulsion = bestmatch.FuelType
Puedes intentar publicar directamente sin usar el bestmatch de versiones pero, en ese caso, es fundamental que asignes también la propiedad Carroceria con algo que hace match en /v3/carrocerias/bestmatch.
Si bien hay unos endpoints para colores, al publicar, el valor de la propiedad Color lo dejamos a tu fantasía (no lo tomes tan literal).
Cambio precios
Las agencias suelen cambiar los precios de venta periódicamente, es decir que mantienen las misma publicación y solo cambian las condiciones de venta (precio o financiamiento).
Si en tu app hay un use-case que se dedica exclusivamente al cambio de precios te invitamos a que uses el PATCH de publicación en lugar que usar el PUT
.
A parte de ser más eficiente en todos sentidos, evitas accidentes como por ejemplo enviarnos una lista vacía de fotos.
Las fotos
En Autocosmos mostramos sólo imágenes de nuestros storages (única excepción son los thumbnails de videos de Youtube).
Esto significa que cuando nos mandas una URL de una foto, usaremos la URL solo para hacer un download de la foto para procesarla y guardarla en nuestros storages.
La URL, de la foto que nos enviarás, solo vive hasta que intentemos el download, luego de eso tu URL no existirá más en nuestros storages.
Si hay algún problema, en intentar el download o en procesar las foto, la foto se pierde y la única forma que tienes para que volvamos a intentar es volver a pasarnos las fotos con el PUT.
Ya que nosotros procesamos las fotos trata de enviarnos fotos originales o las que tengas con la mejor resolución.
Para el formato de las imagenes aceptamos varios entre los cuales JPG, PNG, WEBP y otros cuantos.
La dimensiones mínimas son min-width=640px
y min-height=360px
; si cualquiera, de las dos dimensiones, es inferiror la foto será rechazada.
Cabe destacar que hace años que no existe en el mercado un device que tome fotos tan pequeñas así que si a tus usuarios le agarra la vena artística, por favor, avísale de tu lado.
Antes de enviarnos un POST o un PUT, de una publicación con sus fotos, asegurate que las fotos estén accesibles publicamente en las URLs que nos envías (debes grabar todo en tu sistema antes que intentes grabar con nuestra API).
Todas las fotos se procesan de forma asincrónica, es decir que cuando hagas un POST o un PUT, a pesar de contestarte con un 201 o un 200, es posible que la publicación se auto-modifique luego de procesar cada foto (por ejemplo se puede auto-suspender si, la publicación, se queda sin fotos).
¿Que pasará con la publicación y las URLs que nos envías?
- Una vez persistidos los cambios a la publicación, anotamos en una queue las URLs de la fotos para procesar. Hay procesos que escalan hasta 10 instancias (10 máquinas) según la cantidad de fotos que estén en queue de procesamiento (no te preocupes que tambien tenemos cuidado a no presionar demasiado tu storage).
- Si tu server nos contesta con un 404, la foto no existe así que la borramos de la publicación.
- Si tu server nos contesta con un 5xx haremos otros dos intentos, distanciados cada 15 minutos, antes de eliminar la foto en la publicación.
- Si logramos hacer el download de la foto (tu server contesta con un 200 y un content con los bytes de la foto), intentaremos procesarla.
- Si el formato no está soportado la foto se rechaza.
- Si la foto no respeta la dimesiones mínimas, la foto se rechaza.
- Si todo pasó sin problemas, la foto se procesa, se guardará en nuestros storages y tu verás que las URLs que te informamos en el POST/PUT te mostrarán una de las imagenes grabadas en nuestros storages.
- Si, al procesar todas las URLs de las fotos, la publicación se queda sin fotos validas, la publicación será suspendida y quedará en un estado inválido hasta que se modifique, con un PUT, agregando por lo menos una foto válida.
No terminó...
En Autocosmos hay bots y humanos que moderan publicaciones así que si a algunos de los dos "no le gusta" la foto que se subió, es posible que le pase algo a la foto, a la publicación o hasta a la subscription según cuan grave sea el grado de "disgusto".Para Apps que consumen nuestro catálogo
Quien usa nuestra API para ofrecer productos relacionados al mercado de autos nuevos, y lo primero que necesitan es la selección del auto, el día a día podría ser algo así:
-
Accede a la home de la API /v3.
Allí te guardas el bookmark :
home.Marcas._links.newcars.href
-
Envías el GET al bookmark anterior con
Accept: application/json
.
Con el response, envías a tu frontend un key-value-pair generado recorriendomarcas._entries
y por cada ítem generas{ key: item.Modelos.newcars.href, value: item.Nombre }
. Con esa lista, tu frontend, podrá renderizar un<select>
cuyas options terminen luciendo algo tipo<option value="/v3/modelos?marca=1561&soloMercadoNuevos=true">Acura</option>
. -
El usuario selecciona algo, a tu backend le llega el
string
"/v3/modelos?marca=1561&soloMercadoNuevos=true" y tu, desde el backend, usas directamente esestring
para envíarnos el request que busca modelos. Envías el GET conAccept: application/json
.
Con el response, envías a tu frontend un key-vaule-pair generado recorriendomodelos._entries
y por cada ítem generas{ key: item.Versiones.newcars.href, value: item.Nombre }
. Con esa lista, tu frontend, podrá renderizar un<select>
cuyas options terminen luciendo algo tipo<option value="/v3/versiones?modelo=9999">MDX</option>
. -
Una vez más el usuario selecciona algo, a tu backend le llega el
string
"/v3/versiones?modelo=9999" y tú, desde el backend, usas directamente esestring
para envíarnos el request que busca versiones. Envías el GET esta vez conAccept: application/vnd.autocosmos.ref+json
.
Con el response, envías a tu frontend un key-value-pair generado recorriendoversiones._entries
y por cada ítem generas{ key: item.href, value: item.Version + " " + item.VersionYear }
. Con esa lista, tu frontend, podrá renderizar un<select>
cuyas options terminen luciendo algo tipo<option value="/v3/versiones/164868">Advance 2022</option>
. -
Una vez más el usuario selecciona algo, a tu backend le llega el
string
"/v3/versiones/164868" y tú, desde el backend, usas directamente esestring
para envíarnos el request que lee toda la información de la versión.
Nuestra recomendación es que no compartas tu AppKey y AppSecret en un JS porque alguien, seguro, se va a hacer un festín, en Autocosmos, con tus credenciales.