Quro Integraciones

Webhooks de telemetría en tiempo real · servicio 1.0.0 · formato quro.telemetria.v1 · OpenAPI 3.0.3
URL base del APIhttps://integraciones.quro.com.mx
AutenticaciónAuthorization: Bearer qi_…
Contrato para herramientas/openapi.json (Postman, Swagger, Insomnia)

Quro manda a tu sistema (un «destino»: tu webhook) la posición y los sensores de tus vehículos en el momento en que llegan, de equipos Ruptela, QURO 4G y QURO 2G. Tú decides a qué URL, con qué seguridad, de qué vehículos, qué campos y con qué nombres.

Inicio rápido

  1. Tu llave del API. Plataforma Quro te entrega una llave qi_…. Va en cada petición: Authorization: Bearer qi_….
  2. Da de alta tu destino: POST /api/v1/destinos con al menos nombre y url. Quro lo prueba al guardarlo.
  3. Guarda el secretoFirma que regresa: se muestra una sola vez y sirve para verificar que cada envío viene de Quro.
  4. Revisa lo que vas a recibir: POST /api/v1/destinos/{id}/vista-previa.
  5. Vigila: GET /api/v1/destinos/{id}/envios (cada intento) y GET /api/v1/destinos/{id}/reporte (resumen diario).

Permisos de las llaves

PermisoQué permite
destinos:leerVer destinos, sus vehículos y la vista previa
destinos:escribirCrear, cambiar, probar, pausar y borrar destinos; rotar la firma; cambiar vehículos
reportes:leerBitácora de entregas y reportes
llaves:gestionarCrear y revocar llaves de tu cuenta (nunca con más permisos que la tuya)
operadorSólo llaves que entrega Plataforma Quro a un implementador: clientes y destinos de todas las empresas; no llaves, configuración general, límites ni suspensión

Cada llave sólo ve y toca lo de su empresa. Puede limitarse a ciertas IPs y tener fecha de expiración. Límite: 300 peticiones por minuto por llave.

Lo que recibe tu endpoint

Headers de cada petición

Content-Typeapplication/json; charset=utf-8
X-Quro-Firmat=<segundos>,v1=<HMAC-SHA256 en hex> — siempre, aunque tu destino no tenga autenticación
X-Quro-LoteId único del envío. Si te llega dos veces el mismo (un reintento después de un timeout), descarta el repetido
X-Quro-DestinoId de tu destino
X-Quro-Versionquro.telemetria.v1
X-Quro-Prueba1 sólo en las pruebas (sin puntos)

Más tu autenticación (apikey en header o query, basic, bearer u OAuth2 client_credentials) y tus headers propios.

Cuerpo con la configuración por omisión (envoltura «lote», todos los campos, fecha ISO UTC)

{
  "version": "quro.telemetria.v1",
  "lote": "6f1c2a9e-…",
  "enviadoEn": "2026-10-14T21:22:32.000Z",
  "total": 1,
  "puntos": [
    {
      "imei": "867060038218321",
      "empresa": {
        "uid": "7ca085a2-e29c-40dd-85d6-249ad45d21b2"
      },
      "vehiculo": {
        "uid": "04ed95ca-e595-45b2-8239-34af1d446c8d",
        "alias": "TR-685",
        "noEconomico": "685",
        "placa": "XY-1234-Z"
      },
      "fechaLocal": "2026-10-14T15:22:31",
      "posicion": {
        "latitud": 20.97418,
        "longitud": -89.623456,
        "velocidad": 62,
        "rumbo": 186.1
      },
      "evento": {
        "id": 1,
        "nombre": "Movimiento"
      },
      "direccion": "Calle 60, Centro, Mérida, Yucatán",
      "sensores": {
        "temperatura": 0,
        "rpm": 1390,
        "odometroObd": 73640,
        "distancia": 0.59,
        "combustible": {
          "tanque1": 42.6,
          "capacidad": 200
        },
        "voltajeBateria": 4.1,
        "voltajeVehiculo": 13.8,
        "motor": 1,
        "rssi": 24,
        "domo": 1,
        "valvula": 1,
        "fechaUltimoDomo": "2026-10-14T08:02:11",
        "fechaUltimaValvula": "2026-10-14T08:02:11",
        "codigo": "396869"
      },
      "fechaGps": "2026-10-14T21:22:31.000Z",
      "recibidoEn": "2026-10-14T21:22:33.410Z",
      "familia": "ruptela"
    }
  ]
}

Con campos elegidos y renombrados (envoltura «arreglo», fecha en milisegundos, una constante)

[
  {
    "plate": "XY-1234-Z",
    "gps": {
      "lat": 20.97418,
      "lng": -89.623456
    },
    "ts": 1792012951000,
    "proveedor": "Quro"
  }
]

Un campo sin dato en ese punto no se manda (no llega como null). Los campos «sólo Ruptela» no existen en equipos QURO 4G/2G.

Campos de quro.telemetria.v1

CampoTipoEquiposQué es
imeistringtodasIdentificador del equipo GPS.
familiastringtodasFamilia del equipo: «ruptela» o «quro» (QURO 4G/2G).
empresa.uidstringtodasEmpresa dueña del vehículo (UUID).
vehiculo.uidstringtodasVehículo (UUID).
vehiculo.aliasstringtodasAlias del vehículo.
vehiculo.noEconomicostringtodasNúmero económico.
vehiculo.placastringtodasPlacas.
fechaGpsfechatodasFecha y hora del punto, en el formato de fecha del destino (por omisión ISO en UTC).
fechaLocalstringtodasLa misma fecha en la hora local configurada para la empresa en Quro, sin desfase (AAAA-MM-DDTHH:mm:ss), como la ve la plataforma.
recibidoEnfechatodasCuándo recibió Quro el punto (sirve para medir el atraso del equipo).
posicion.latitudnumbertodasLatitud en grados decimales.
posicion.longitudnumbertodasLongitud en grados decimales.
posicion.velocidadnumbertodasVelocidad en km/h.
posicion.rumbonumbertodasRumbo en grados (0 = norte).
evento.idintegertodasTipo de evento (número).
evento.nombrestringtodasNombre del evento (encendido, detenido, exceso de velocidad…).
direccionstringtodasDirección geocodificada del punto.
chofer.uidstringtodasChofer asignado (UUID), si hay.
sensores.temperaturanumbertodasTemperatura del sensor.
sensores.temperaturaMotornumbersólo RuptelaTemperatura del motor (OBD).
sensores.rpmnumbertodasRevoluciones del motor.
sensores.odometroObdnumbertodasOdómetro leído del vehículo (OBD), en km.
sensores.distancianumbertodasDistancia recorrida desde el punto anterior (km).
sensores.combustible.tanque1numbertodasCombustible en el tanque 1 (litros).
sensores.combustible.tanque1Porcentajenumbersólo RuptelaCombustible en el tanque 1 (%).
sensores.combustible.tanque2numbersólo RuptelaCombustible en el tanque 2 (litros).
sensores.combustible.tanque2Porcentajenumbersólo RuptelaCombustible en el tanque 2 (%).
sensores.combustible.capacidadnumbertodasCapacidad del tanque (litros).
sensores.voltajeBaterianumbersólo RuptelaVoltaje de la batería interna del equipo.
sensores.voltajeVehiculonumbertodasVoltaje del vehículo.
sensores.motorintegertodasMotor: 1 encendido, 0 apagado.
sensores.rssiintegertodasIntensidad de la señal celular.
sensores.anguloSensornumbersólo RuptelaÁngulo del sensor de inclinación (0 si el equipo no lo tiene).
sensores.chapaMagneticaintegersólo RuptelaEstado de la chapa magnética (0 si el equipo no la tiene).
sensores.domointegersólo RuptelaSello del domo: 1 cerrado, 0 abierto.
sensores.valvulaintegersólo RuptelaSello de la válvula: 1 cerrada, 0 abierta.
sensores.fechaUltimoDomostringsólo RuptelaÚltimo cambio del domo (hora local de la empresa).
sensores.fechaUltimaValvulastringsólo RuptelaÚltimo cambio de la válvula (hora local de la empresa).
sensores.codigostringtodasCódigo aleatorio de 6 dígitos mientras los sellos están cerrados.

El formato es estable: dentro de v1 sólo se agregan campos nuevos, nunca se quitan ni cambian de significado. Un cambio incompatible sería v2, y v1 seguiría funcionando.

Verificar la firma

Calcula HMAC-SHA256(secretoFirma, t + "." + cuerpo) sobre el cuerpo exacto que recibiste (antes de parsearlo) y compáralo con v1. Rechaza si t tiene más de 5 minutos.

Node.js
import crypto from 'node:crypto';

// cuerpo: el texto EXACTO recibido (antes de JSON.parse); cabecera: X-Quro-Firma
function firmaValida(secreto, cuerpo, cabecera, toleranciaS = 300) {
  const m = /^t=(\d+),v1=([a-f0-9]{64})$/.exec(cabecera || '');
  if (!m) return false;
  if (Math.abs(Date.now() / 1000 - Number(m[1])) > toleranciaS) return false;   // contra repeticiones
  const esperado = crypto.createHmac('sha256', secreto).update(`${m[1]}.${cuerpo}`).digest();
  const dado = Buffer.from(m[2], 'hex');
  return dado.length === esperado.length && crypto.timingSafeEqual(dado, esperado);
}
Python
import hmac, hashlib, re, time

def firma_valida(secreto: str, cuerpo: bytes, cabecera: str, tolerancia_s: int = 300) -> bool:
    m = re.fullmatch(r"t=(\d+),v1=([a-f0-9]{64})", cabecera or "")
    if not m or abs(time.time() - int(m.group(1))) > tolerancia_s:
        return False
    esperado = hmac.new(secreto.encode(), m.group(1).encode() + b"." + cuerpo, hashlib.sha256).hexdigest()
    return hmac.compare_digest(esperado, m.group(2))
C# (.NET 6+)
using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions;

static bool FirmaValida(string secreto, string cuerpo, string cabecera, int toleranciaS = 300) {
    var m = Regex.Match(cabecera ?? "", @"^t=(\d+),v1=([a-f0-9]{64})$");
    if (!m.Success || Math.Abs(DateTimeOffset.UtcNow.ToUnixTimeSeconds() - long.Parse(m.Groups[1].Value)) > toleranciaS) return false;
    using var h = new HMACSHA256(Encoding.UTF8.GetBytes(secreto));
    var esperado = h.ComputeHash(Encoding.UTF8.GetBytes(m.Groups[1].Value + "." + cuerpo));
    return CryptographicOperations.FixedTimeEquals(esperado, Convert.FromHexString(m.Groups[2].Value));
}

Cómo entrega Quro

Destino «peligroso»

Un destino sin autenticación o sin https se acepta y recibe datos, pero queda marcado seguridad.peligroso: true con sus motivos (sin_autenticacion, sin_https). Recomendamos https y alguna autenticación; la firma X-Quro-Firma va siempre. Nunca se aceptan URLs a IPs privadas o internas.

Errores del API

Todas las respuestas de error traen { "error": "CODIGO", "mensaje": "texto", "errores": ["…"] } (errores sólo en validación).

400VALIDACION (datos inválidos), URL_INVALIDA, URL_INTERNA
401SIN_LLAVE, LLAVE_INVALIDA, LLAVE_REVOCADA, LLAVE_EXPIRADA
403SIN_PERMISO, IP_NO_PERMITIDA, CUENTA_SUSPENDIDA
404NO_ENCONTRADO (no existe o no es de tu cuenta)
409NOMBRE_REPETIDO, VERSION (otro cambio llegó antes), LIMITE
429DEMASIADAS: espera lo que diga retry-after

Formato del punto

GET /api/v1/campos

Catálogo de campos de quro.telemetria.v1

Los nombres de campos.lista[].campo. familias dice de qué equipos llega cada campo.

Respuestas

200

{ version, campos: [{ ruta, tipo, descripcion, familias }], ejemplo }

Ejemplo con curl
curl -X GET 'https://integraciones.quro.com.mx/api/v1/campos'

Destinos

GET /api/v1/destinos

Lista los destinos de la cuenta

Parámetros

NombreDóndeObligatorioTipoQué es
empresaUidquerynostring

Sólo llaves internas: el cliente por su UID de empresa de QuroGPS (alternativa a cuentaId).

cuentaIdquerynostring

Sólo llaves internas: la cuenta sobre la que se actúa (id interno; o usa empresaUid).

Respuestas

200

{ items: [Destino] } (sin secretos)

Ejemplo con curl
curl -X GET 'https://integraciones.quro.com.mx/api/v1/destinos' \
  -H 'Authorization: Bearer qi_xxxxxxxx_…'

POST /api/v1/destinos

Da de alta un destino (y lo prueba)

Guarda el destino, cifra sus secretos y, si la configuración general lo pide, lo prueba al momento.

La respuesta trae secretoFirma una sola vez: guárdalo para verificar X-Quro-Firma. Si lo pierdes, usa /rotar-firma.

Parámetros

NombreDóndeObligatorioTipoQué es
empresaUidquerynostring

Sólo llaves internas: el cliente por su UID de empresa de QuroGPS (alternativa a cuentaId).

cuentaIdquerynostring

Sólo llaves internas: la cuenta sobre la que se actúa (id interno; o usa empresaUid).

Cuerpo (JSON)

Un destino nuevo. Sólo nombre y url son obligatorios; lo demás toma los valores por omisión.

CampoObligatorioTipoQué es
nombresístring

Nombre del destino (único en la cuenta).

urlsístring

Tu endpoint. Se recomienda https; con http el destino queda marcado como peligroso. Nunca IPs privadas o internas.

metodono«POST» | «PUT» | «PATCH»

Método HTTP (por omisión POST).

activonoboolean

false = no se envía nada (igual que pausar).

autenticacionnoobject

Autenticación ante tu endpoint. Se combina con headers propios.

tipo «ninguna» | «apikey» | «basic» | «bearer» | «oauth2_cc»

Cómo se autentica Quro ante tu endpoint. ninguna se permite, pero marca el destino como peligroso.

donde «header» | «query»

apikey: en un header (por omisión) o como parámetro de la URL.

nombre string

apikey: nombre del header o del parámetro (p. ej. x-api-key). Puede ser authorization si tu API espera la llave ahí sin «Bearer».

valor string

apikey: la llave · bearer: el token. Secreto: se guarda cifrado y nunca se devuelve. Al editar, si no lo mandas, se conserva el anterior.

usuario string

basic: usuario.

clave string

basic: contraseña (secreto).

tokenUrl string

oauth2_cc: URL del servidor de tokens (https obligatorio).

clienteId string

oauth2_cc: client_id.

clienteSecreto string

oauth2_cc: client_secret (secreto).

alcance string

oauth2_cc: scope (opcional).

headersnolista de object

Headers propios que se agregan a cada petición.

querynolista de object

Parámetros fijos que se agregan a la URL.

alcancenoobject
modo «todos» | «lista»

todos los vehículos de la empresa, o sólo los de /destinos/{id}/vehiculos.

camposnoobject
modo «todos» | «lista»

todos: el punto completo de quro.telemetria.v1. lista: sólo los campos de lista.

lista lista de object

Campos a enviar (ver GET /api/v1/campos). como cambia el nombre con el que llega (y puede anidar: gps.lat).

constantes lista de object

Valores fijos que se agregan a cada punto (p. ej. {"nombre":"proveedor","valor":"Quro"}).

formatonoobject
version «quro.telemetria.v1»

Versión del formato. Hoy sólo existe v1; un cambio incompatible será v2 y v1 seguirá funcionando.

fecha «iso_utc» | «iso_local» | «epoch_ms»

iso_utc (2026-10-14T21:22:31.000Z), iso_local (2026-10-14T15:22:31-06:00, con zona) o epoch_ms (número).

zona string

Zona horaria IANA para iso_local (por omisión America/Mexico_City).

envoltura «lote» | «arreglo» | «objeto»

lote: {version, lote, enviadoEn, total, puntos:[…]} · arreglo: […] · objeto: un solo punto por petición (requiere entrega individual).

entreganoobject
modo «lote» | «individual»

lote: los puntos que se juntan mientras hay un envío en curso salen juntos. individual: una petición por punto.

maxPorLote integer

Máximo de puntos por petición (lote).

esperaMaxMs integer

Lo más que puede esperar un punto para juntarse con otros. Por omisión 0: sale al momento (tiempo real) y sólo se juntan los que llegan mientras tu endpoint responde.

maxPeticionesPorSeg number

Límite de peticiones por segundo a tu endpoint.

timeoutMs integer

Tiempo máximo de respuesta de tu endpoint.

Ejemplo de cuerpo
{
  "nombre": "ERP de logística",
  "url": "https://erp.cliente.com/api/gps",
  "autenticacion": {
    "tipo": "apikey",
    "donde": "header",
    "nombre": "x-api-key",
    "valor": "<tu-llave>"
  },
  "campos": {
    "modo": "lista",
    "lista": [
      {
        "campo": "vehiculo.placa",
        "como": "plate"
      },
      {
        "campo": "posicion.latitud",
        "como": "lat"
      },
      {
        "campo": "posicion.longitud",
        "como": "lng"
      },
      {
        "campo": "fechaGps",
        "como": "timestamp"
      }
    ]
  },
  "formato": {
    "fecha": "iso_utc",
    "envoltura": "lote"
  },
  "entrega": {
    "modo": "lote",
    "maxPorLote": 100
  }
}

Respuestas

201

{ destino, secretoFirma, prueba, advertencias }

400

Datos inválidos o URL interna

409

Nombre repetido o límite de destinos

Ejemplo con curl
curl -X POST 'https://integraciones.quro.com.mx/api/v1/destinos' \
  -H 'Authorization: Bearer qi_xxxxxxxx_…' \
  -H 'Content-Type: application/json' \
  -d '{"nombre":"ERP de logística","url":"https://erp.cliente.com/api/gps","autenticacion":{"tipo":"apikey","donde":"header","nombre":"x-api-key","valor":"<tu-llave>"},"campos":{"modo":"lista","lista":[{"campo":"vehiculo.placa","como":"plate"},{"campo":"posicion.latitud","como":"lat"},{"campo":"posicion.longitud","como":"lng"},{"campo":"fechaGps","como":"timestamp"}]},"formato":{"fecha":"iso_utc","envoltura":"lote"},"entrega":{"modo":"lote","maxPorLote":100}}'

GET /api/v1/destinos/{id}

Un destino

Parámetros

NombreDóndeObligatorioTipoQué es
idpathsístring

id del destino

Respuestas

200

{ destino, vehiculos } (vehiculos = cuántos hay en su lista)

404

No existe (o no es de tu cuenta)

Ejemplo con curl
curl -X GET 'https://integraciones.quro.com.mx/api/v1/destinos/<id>' \
  -H 'Authorization: Bearer qi_xxxxxxxx_…'

PATCH /api/v1/destinos/{id}

Cambia un destino

Si cambia la conexión (url, método, autenticación, headers o query) se vuelve a probar.

Parámetros

NombreDóndeObligatorioTipoQué es
idpathsístring

id del destino

Cuerpo (JSON)

Sólo lo que cambia. formato y entrega se combinan con lo actual; autenticacion, headers, query y campos se reemplazan (los secretos no reenviados se conservan).

CampoObligatorioTipoQué es
nombrenostring

Nombre del destino (único en la cuenta).

urlnostring

Tu endpoint. Se recomienda https; con http el destino queda marcado como peligroso. Nunca IPs privadas o internas.

metodono«POST» | «PUT» | «PATCH»

Método HTTP (por omisión POST).

activonoboolean

false = no se envía nada (igual que pausar).

autenticacionnoobject

Autenticación ante tu endpoint. Se combina con headers propios.

tipo «ninguna» | «apikey» | «basic» | «bearer» | «oauth2_cc»

Cómo se autentica Quro ante tu endpoint. ninguna se permite, pero marca el destino como peligroso.

donde «header» | «query»

apikey: en un header (por omisión) o como parámetro de la URL.

nombre string

apikey: nombre del header o del parámetro (p. ej. x-api-key). Puede ser authorization si tu API espera la llave ahí sin «Bearer».

valor string

apikey: la llave · bearer: el token. Secreto: se guarda cifrado y nunca se devuelve. Al editar, si no lo mandas, se conserva el anterior.

usuario string

basic: usuario.

clave string

basic: contraseña (secreto).

tokenUrl string

oauth2_cc: URL del servidor de tokens (https obligatorio).

clienteId string

oauth2_cc: client_id.

clienteSecreto string

oauth2_cc: client_secret (secreto).

alcance string

oauth2_cc: scope (opcional).

headersnolista de object

Headers propios que se agregan a cada petición.

querynolista de object

Parámetros fijos que se agregan a la URL.

alcancenoobject
modo «todos» | «lista»

todos los vehículos de la empresa, o sólo los de /destinos/{id}/vehiculos.

camposnoobject
modo «todos» | «lista»

todos: el punto completo de quro.telemetria.v1. lista: sólo los campos de lista.

lista lista de object

Campos a enviar (ver GET /api/v1/campos). como cambia el nombre con el que llega (y puede anidar: gps.lat).

constantes lista de object

Valores fijos que se agregan a cada punto (p. ej. {"nombre":"proveedor","valor":"Quro"}).

formatonoobject
version «quro.telemetria.v1»

Versión del formato. Hoy sólo existe v1; un cambio incompatible será v2 y v1 seguirá funcionando.

fecha «iso_utc» | «iso_local» | «epoch_ms»

iso_utc (2026-10-14T21:22:31.000Z), iso_local (2026-10-14T15:22:31-06:00, con zona) o epoch_ms (número).

zona string

Zona horaria IANA para iso_local (por omisión America/Mexico_City).

envoltura «lote» | «arreglo» | «objeto»

lote: {version, lote, enviadoEn, total, puntos:[…]} · arreglo: […] · objeto: un solo punto por petición (requiere entrega individual).

entreganoobject
modo «lote» | «individual»

lote: los puntos que se juntan mientras hay un envío en curso salen juntos. individual: una petición por punto.

maxPorLote integer

Máximo de puntos por petición (lote).

esperaMaxMs integer

Lo más que puede esperar un punto para juntarse con otros. Por omisión 0: sale al momento (tiempo real) y sólo se juntan los que llegan mientras tu endpoint responde.

maxPeticionesPorSeg number

Límite de peticiones por segundo a tu endpoint.

timeoutMs integer

Tiempo máximo de respuesta de tu endpoint.

versionnointeger

Opcional: la versión que editas. Si alguien lo cambió antes, responde 409 en vez de pisar su cambio.

Respuestas

200

{ destino, prueba, advertencias }

409

Otro cambio llegó antes (versión) o nombre repetido

Ejemplo con curl
curl -X PATCH 'https://integraciones.quro.com.mx/api/v1/destinos/<id>' \
  -H 'Authorization: Bearer qi_xxxxxxxx_…'

DELETE /api/v1/destinos/{id}

Da de baja un destino

Deja de enviar al momento. Su bitácora y reportes se conservan.

Parámetros

NombreDóndeObligatorioTipoQué es
idpathsístring

id del destino

Respuestas

200

{ ok: true }

Ejemplo con curl
curl -X DELETE 'https://integraciones.quro.com.mx/api/v1/destinos/<id>' \
  -H 'Authorization: Bearer qi_xxxxxxxx_…'

POST /api/v1/destinos/{id}/probar

Prueba el destino ahora

Manda una petición real a tu endpoint con su autenticación, headers y firma, sin puntos y con X-Quro-Prueba: 1. El cuerpo respeta tu envoltura: lote → {…, total: 0, puntos: [], prueba: true}, arreglo → [], objeto → {prueba: true}.

Parámetros

NombreDóndeObligatorioTipoQué es
idpathsístring

id del destino

Respuestas

200

{ prueba: { ok, http, ms, error, loteId }, destino }

Ejemplo con curl
curl -X POST 'https://integraciones.quro.com.mx/api/v1/destinos/<id>/probar' \
  -H 'Authorization: Bearer qi_xxxxxxxx_…'

POST /api/v1/destinos/{id}/vista-previa

Muestra exactamente lo que recibiría tu endpoint

Con puntos de ejemplo, aplica tus campos, nombres, fecha y envoltura. No envía nada. Los secretos salen enmascarados.

Parámetros

NombreDóndeObligatorioTipoQué es
familiaqueryno«ruptela» | «quro» (por omisión ruptela)

Equipos Ruptela traen más sensores que los QURO 4G/2G.

puntosquerynointeger (por omisión 2)
idpathsístring

id del destino

Respuestas

200

{ peticiones: [{ url, metodo, headers, cuerpo }] }

Ejemplo con curl
curl -X POST 'https://integraciones.quro.com.mx/api/v1/destinos/<id>/vista-previa' \
  -H 'Authorization: Bearer qi_xxxxxxxx_…'

POST /api/v1/destinos/{id}/pausar

Pausa el destino

Deja de enviar. Lo que llegue mientras está pausado no se guarda.

Parámetros

NombreDóndeObligatorioTipoQué es
idpathsístring

id del destino

Respuestas

200

{ destino }

Ejemplo con curl
curl -X POST 'https://integraciones.quro.com.mx/api/v1/destinos/<id>/pausar' \
  -H 'Authorization: Bearer qi_xxxxxxxx_…'

POST /api/v1/destinos/{id}/reanudar

Reanuda el destino

Vuelve a enviar y limpia el silencio y los fallos acumulados.

Parámetros

NombreDóndeObligatorioTipoQué es
idpathsístring

id del destino

Respuestas

200

{ destino }

Ejemplo con curl
curl -X POST 'https://integraciones.quro.com.mx/api/v1/destinos/<id>/reanudar' \
  -H 'Authorization: Bearer qi_xxxxxxxx_…'

POST /api/v1/destinos/{id}/rotar-firma

Genera un secreto de firma nuevo

El anterior deja de usarse al momento. El nuevo se muestra una sola vez.

Parámetros

NombreDóndeObligatorioTipoQué es
idpathsístring

id del destino

Respuestas

200

{ secretoFirma, destino }

Ejemplo con curl
curl -X POST 'https://integraciones.quro.com.mx/api/v1/destinos/<id>/rotar-firma' \
  -H 'Authorization: Bearer qi_xxxxxxxx_…'

Vehículos de un destino

GET /api/v1/destinos/{id}/vehiculos

Vehículos del destino

Parámetros

NombreDóndeObligatorioTipoQué es
limitequerynointeger (por omisión 1000)
despuesDequerynostring

Paginación: el último vehiculoUid de la página anterior.

idpathsístring

id del destino

Respuestas

200

{ total, items: [{ vehiculoUid, imei, alias, agregadoEn }] }

Ejemplo con curl
curl -X GET 'https://integraciones.quro.com.mx/api/v1/destinos/<id>/vehiculos' \
  -H 'Authorization: Bearer qi_xxxxxxxx_…'

PUT /api/v1/destinos/{id}/vehiculos

Reemplaza la lista completa de vehículos

Parámetros

NombreDóndeObligatorioTipoQué es
idpathsístring

id del destino

Cuerpo (JSON)

CampoObligatorioTipoQué es
vehiculossílista de object

Respuestas

200

{ total, agregados, quitados }

Ejemplo con curl
curl -X PUT 'https://integraciones.quro.com.mx/api/v1/destinos/<id>/vehiculos' \
  -H 'Authorization: Bearer qi_xxxxxxxx_…'

POST /api/v1/destinos/{id}/vehiculos

Agrega vehículos (los que ya estaban se conservan)

Parámetros

NombreDóndeObligatorioTipoQué es
idpathsístring

id del destino

Cuerpo (JSON)

CampoObligatorioTipoQué es
vehiculossílista de object

Respuestas

200

{ total, agregados }

Ejemplo con curl
curl -X POST 'https://integraciones.quro.com.mx/api/v1/destinos/<id>/vehiculos' \
  -H 'Authorization: Bearer qi_xxxxxxxx_…'

DELETE /api/v1/destinos/{id}/vehiculos/{vehiculoUid}

Quita un vehículo

Parámetros

NombreDóndeObligatorioTipoQué es
idpathsístring
vehiculoUidpathsístring

Respuestas

200

{ ok, total }

Ejemplo con curl
curl -X DELETE 'https://integraciones.quro.com.mx/api/v1/destinos/<id>/vehiculos/<vehiculoUid>' \
  -H 'Authorization: Bearer qi_xxxxxxxx_…'

Bitácora y reporte

GET /api/v1/destinos/{id}/receptor

Lo que llegó al receptor de pruebas de Quro

Para probar sin tener endpoint propio: da de alta el destino con url = https://integraciones.quro.com.mx/receptor/{id} (el id lo sabes tras crearlo: créalo con cualquier URL y luego cámbiala). Agrega ?responder=503 para simular fallas. Muestra los últimos 30 envíos: si la firma fue válida, lote, intento, puntos, nombres de headers y el cuerpo (hasta 8 KB). Se guarda sólo en memoria.

Parámetros

NombreDóndeObligatorioTipoQué es
idpathsístring

id del destino

Respuestas

200

{ total, items: [...] }

Ejemplo con curl
curl -X GET 'https://integraciones.quro.com.mx/api/v1/destinos/<id>/receptor' \
  -H 'Authorization: Bearer qi_xxxxxxxx_…'

GET /api/v1/destinos/{id}/envios

Bitácora de entregas del destino (30 días)

Cada intento: fecha, lote, puntos, bytes, intento, HTTP, milisegundos, ok y error. Más reciente primero; para la página siguiente usa hasta = ts del último.

Parámetros

NombreDóndeObligatorioTipoQué es
desdequerynostring
hastaquerynostring
tipoqueryno«entrega» | «prueba» | «reprueba»
soloFallidosquerynoboolean (por omisión false)
limitequerynointeger (por omisión 100)
idpathsístring

id del destino

Respuestas

200

{ items: [...] }

Ejemplo con curl
curl -X GET 'https://integraciones.quro.com.mx/api/v1/destinos/<id>/envios' \
  -H 'Authorization: Bearer qi_xxxxxxxx_…'

GET /api/v1/destinos/{id}/reporte

Reporte diario de entregas del destino

Por día (UTC): lotes peticiones entregadas, puntos entregados, fallidos intentos fallidos, reintentos, silencios (veces que se silenció), descartados (puntos perdidos por retención vencida o cola llena), msPromedio, msMax y tasaExito = lotes / (lotes + fallidos) en %.

Parámetros

NombreDóndeObligatorioTipoQué es
desdequerynostring

Día inicial (AAAA-MM-DD, UTC). Por omisión hace 7 días.

hastaquerynostring

Día final (AAAA-MM-DD, UTC). Por omisión hoy.

cuentaIdquerynostring

Sólo llaves internas.

empresaUidquerynostring

Sólo llaves internas: el cliente por su UID de empresa de QuroGPS (alternativa a cuentaId).

idpathsístring

id del destino

Respuestas

200

{ destino, desde, hasta, dias: [...], totales }

Ejemplo con curl
curl -X GET 'https://integraciones.quro.com.mx/api/v1/destinos/<id>/reporte' \
  -H 'Authorization: Bearer qi_xxxxxxxx_…'

GET /api/v1/reporte

Reporte de la cuenta: totales por destino

Parámetros

NombreDóndeObligatorioTipoQué es
desdequerynostring

Día inicial (AAAA-MM-DD, UTC). Por omisión hace 7 días.

hastaquerynostring

Día final (AAAA-MM-DD, UTC). Por omisión hoy.

cuentaIdquerynostring

Sólo llaves internas.

empresaUidquerynostring

Sólo llaves internas: el cliente por su UID de empresa de QuroGPS (alternativa a cuentaId).

Respuestas

200

{ desde, hasta, destinos: [...], totales }

Ejemplo con curl
curl -X GET 'https://integraciones.quro.com.mx/api/v1/reporte' \
  -H 'Authorization: Bearer qi_xxxxxxxx_…'

Llaves del API

GET /api/v1/llaves

Llaves de la cuenta (sin secretos)

Parámetros

NombreDóndeObligatorioTipoQué es
empresaUidquerynostring

Sólo llaves internas: el cliente por su UID de empresa de QuroGPS (alternativa a cuentaId).

cuentaIdquerynostring

Sólo llaves internas: la cuenta sobre la que se actúa (id interno; o usa empresaUid).

Respuestas

200

{ items: [Llave] }

Ejemplo con curl
curl -X GET 'https://integraciones.quro.com.mx/api/v1/llaves' \
  -H 'Authorization: Bearer qi_xxxxxxxx_…'

POST /api/v1/llaves

Crea una llave

La llave completa (qi_…) se muestra una sola vez en llave. Guárdala en un lugar seguro: Quro sólo guarda su hash.

Una llave de cuenta sólo puede crear llaves de su cuenta y con permisos que ella misma tenga.

Parámetros

NombreDóndeObligatorioTipoQué es
empresaUidquerynostring

Sólo llaves internas: el cliente por su UID de empresa de QuroGPS (alternativa a cuentaId).

cuentaIdquerynostring

Sólo llaves internas: la cuenta sobre la que se actúa (id interno; o usa empresaUid).

Cuerpo (JSON)

CampoObligatorioTipoQué es
nombresístring

Para qué es la llave (p. ej. «Portal del cliente»).

alcancessílista de valores

Permisos. admin y operador sólo en llaves internas (sin cuenta); operador = todo menos llaves, configuración general, límites y suspensión de cuentas. Una llave de cuenta no puede dar más permisos que los suyos.

ipsPermitidasnolista de string

Opcional: IPs o rangos CIDR desde los que se puede usar.

expiraEnnostring

Opcional: fecha de expiración (ISO 8601).

Ejemplo de cuerpo
{
  "nombre": "Portal del cliente",
  "alcances": [
    "destinos:leer",
    "destinos:escribir",
    "reportes:leer"
  ]
}

Respuestas

201

{ llave, datos: Llave }

Ejemplo con curl
curl -X POST 'https://integraciones.quro.com.mx/api/v1/llaves' \
  -H 'Authorization: Bearer qi_xxxxxxxx_…' \
  -H 'Content-Type: application/json' \
  -d '{"nombre":"Portal del cliente","alcances":["destinos:leer","destinos:escribir","reportes:leer"]}'

DELETE /api/v1/llaves/{id}

Revoca una llave (de inmediato)

Parámetros

NombreDóndeObligatorioTipoQué es
idpathsístring

Respuestas

200

{ ok: true }

Ejemplo con curl
curl -X DELETE 'https://integraciones.quro.com.mx/api/v1/llaves/<id>' \
  -H 'Authorization: Bearer qi_xxxxxxxx_…'

GET /api/v1/yo

Qué es la llave con la que llamas

Tipo (admin, operador o cuenta), permisos, expiración y, si es de cuenta, su empresa. Lo usa la consola para saber qué mostrar.

Respuestas

200

{ llave: { id, nombre, tipo, alcances, expiraEn }, cuenta }

Ejemplo con curl
curl -X GET 'https://integraciones.quro.com.mx/api/v1/yo' \
  -H 'Authorization: Bearer qi_xxxxxxxx_…'

GET /api/v1/cuenta

Mi cuenta: empresa, límites y si los envíos están activos

Respuestas

200

{ cuenta }

Ejemplo con curl
curl -X GET 'https://integraciones.quro.com.mx/api/v1/cuenta' \
  -H 'Authorization: Bearer qi_xxxxxxxx_…'

Cuentas (llave interna: admin u operador)

GET /api/v1/cuentas

Lista las cuentas

Respuestas

200

{ items: [Cuenta] }

Ejemplo con curl
curl -X GET 'https://integraciones.quro.com.mx/api/v1/cuentas' \
  -H 'Authorization: Bearer qi_xxxxxxxx_…'

POST /api/v1/cuentas

Da de alta una empresa

Después crea su llave con POST /llaves?cuentaId=….

Cuerpo (JSON)

CampoObligatorioTipoQué es
empresaUidsístring

UUID de la empresa en Quro.

nombresístring
limitesnoobject
maxDestinos integer
maxVehiculosPorDestino integer

Respuestas

201

{ cuenta }

409

La empresa ya tiene cuenta

Ejemplo con curl
curl -X POST 'https://integraciones.quro.com.mx/api/v1/cuentas' \
  -H 'Authorization: Bearer qi_xxxxxxxx_…'

PATCH /api/v1/cuentas/{id}

Cambia nombre, estado o límites

Parámetros

NombreDóndeObligatorioTipoQué es
idpathsístring

Cuerpo (JSON)

CampoObligatorioTipoQué es
nombrenostring
estadono«activa» | «suspendida»

suspendida corta al momento sus llaves; sus destinos dejan de recibir.

limitesnoobject
maxDestinos integer
maxVehiculosPorDestino integer

Respuestas

200

{ cuenta }

Ejemplo con curl
curl -X PATCH 'https://integraciones.quro.com.mx/api/v1/cuentas/<id>' \
  -H 'Authorization: Bearer qi_xxxxxxxx_…'

POST /api/v1/cuentas/{id}/detener-envios

Deja de enviar a TODOS los destinos del cliente

Al momento: no se encola nada más y se descarta lo pendiente. Sus destinos y llaves se conservan; reanudar-envios lo vuelve a encender.

Parámetros

NombreDóndeObligatorioTipoQué es
idpathsístring

Cuerpo (JSON)

CampoObligatorioTipoQué es
motivosístring

Por qué (queda en la cuenta y en la auditoría).

Respuestas

200

{ cuenta }

Ejemplo con curl
curl -X POST 'https://integraciones.quro.com.mx/api/v1/cuentas/<id>/detener-envios' \
  -H 'Authorization: Bearer qi_xxxxxxxx_…'

POST /api/v1/cuentas/{id}/reanudar-envios

Vuelve a enviar a los destinos activos del cliente

Parámetros

NombreDóndeObligatorioTipoQué es
idpathsístring

Respuestas

200

{ cuenta }

Ejemplo con curl
curl -X POST 'https://integraciones.quro.com.mx/api/v1/cuentas/<id>/reanudar-envios' \
  -H 'Authorization: Bearer qi_xxxxxxxx_…'

Configuración general (sólo admin)

GET /api/v1/config

Configuración general (reintentos, silencio, retención, límites, pruebas)

Respuestas

200

{ config }

Ejemplo con curl
curl -X GET 'https://integraciones.quro.com.mx/api/v1/config' \
  -H 'Authorization: Bearer qi_xxxxxxxx_…'

PATCH /api/v1/config

Cambia la configuración general

Cada sección que mandes se combina con la actual. El despachador la toma en menos de 60 s.

Cuerpo (JSON)

CampoObligatorioTipoQué es
reintentosnoobject
maximo integer
esperasMs lista de integer
silencionoobject
trasFallosSeguidos integer
inicialMin integer
maximoMin integer
factor number
repruebaCadaMin integer
retencionnoobject
silenciadoMin integer
bitacoraDias integer
maxPuntosPorDestino integer
limitesnoobject
maxPorLote integer
maxBytesPorPeticion integer
timeoutMaxMs integer
maxDestinosPorCuenta integer
pruebasnoobject
alCrear boolean
alCambiar boolean
despachonoobject
modo «apagado» | «registrar» | «enviar»

apagado: no se consume ni se envía nada · registrar: se arma todo y se cuenta, sin enviar · enviar: producción.

Respuestas

200

{ config }

Ejemplo con curl
curl -X PATCH 'https://integraciones.quro.com.mx/api/v1/config' \
  -H 'Authorization: Bearer qi_xxxxxxxx_…'