Saltar al contenido
SendIt está en desarrollo y todavía no opera comercialmente · SendIt is in development and not yet commercially available.
SendItdocs
Español
Esc
navigateopen⌘Jpreview
En esta página

Cotizaciones

Compara tarifas de todas las paqueterías en una sola llamada; el total cotizado es exactamente lo que pagas.

Las cotizaciones llegan solas: al crear un envío, la respuesta ya incluye rates[] con las tarifas de todas las paqueterías habilitadas para esa ruta. No hay una llamada separada de cotización que administrar.

Si ya sabes qué paquetería y servicio quieres, o solo quieres la más barata, agrega el objeto purchase al crear el envío. Ver Compra en una llamada.

El objeto tarifa

{
  "id": "DHL_standard_a1b2c3",
  "carrierCode": "DHL",
  "serviceCode": "EXPRESS_WORLDWIDE",
  "carrierName": "DHL Express",
  "serviceName": "DHL Express Nacional",
  "serviceLevel": "standard",
  "totalPrice": 326.82,
  "currency": "MXN",
  "isInsured": false,
  "estimatedDays": { "min": 1, "max": 2 },
  "expiresAt": "2026-07-18T14:30:00.000Z",
  "breakdown": {
    "baseRate": 264.50,
    "fuelSurcharge": 17.24,
    "insuranceCost": 0.00,
    "subtotal": 281.74,
    "ivaRate": 0.16,
    "ivaAmount": 45.08,
    "total": 326.82
  }
}
Campo Descripción
id El rateId — pásalo a la compra de guía
serviceCode Código nativo exacto del producto de la paquetería
serviceLevel Nivel normalizado entre paqueterías (express, standard, economy, …)
totalPrice El total a pagar, IVA incluido — coincide con breakdown.total
isInsured true si la tarifa incluye seguro (creaste el envío con requestInsurance)
estimatedDays Rango de días hábiles estimados de entrega
expiresAt Vigencia de la tarifa (24 horas)
breakdown Desglose transparente: tarifa base, sobrecargos, seguro, subtotal e IVA por separado

Si creaste el envío con requestInsurance: true y un declaredValue, las tarifas regresan con la prima en breakdown.insuranceCost e isInsured: true. Comprar una tarifa asegurada crea una póliza real que puedes reclamar. Ver Seguro y reclamaciones.

El ciclo de vida de una cotización

POST /v1/shipments
  → crea el envío (DRAFT)
  → cotiza con todas las paqueterías habilitadas
  → devuelve el envío + rates[] (vigencia: 24 h)

GET /v1/shipments/:id/rates        ← consulta o refresca cuando quieras

POST /v1/shipments/:id/label { rateId }   ← compra al precio cotizado

Si las paqueterías tardan

La cotización tiene un presupuesto de 8 segundos. Si alguna paquetería es lenta, el envío se devuelve de inmediato con las tarifas en camino:

{
  "success": true,
  "data": {
    "id": "clxq1w2e3r4t5y6u7i8o9p0a",
    "status": "DRAFT",
    "rates": [],
    "ratesStatus": "pending",
    "ratesExpiresAt": null,
    "ratesPollUrl": "/v1/shipments/clxq1w2e3r4t5y6u7i8o9p0a/rates"
  }
}

Consulta ratesPollUrl (por ejemplo cada 2 segundos) hasta que ratesStatus sea "ready".

Consulta o refresca las tarifas

GET /v1/shipments/:id/rates                  ← devuelve las tarifas vigentes
GET /v1/shipments/:id/rates?refresh=true     ← recotiza con las paqueterías

Sin ?refresh=true obtienes las tarifas en caché mientras su vigencia de 24 horas no haya vencido. Con ?refresh=true se recotiza todo y la vigencia se reinicia.

Cuando una tarifa expira

Comprar con un rateId vencido devuelve 410 RATES_EXPIRED:

{
  "success": false,
  "error": {
    "code": "RATES_EXPIRED",
    "message": "Shipping rates have expired. Please refresh rates and select again.",
    "details": {
      "shipmentId": "clxq1w2e3r4t5y6u7i8o9p0a",
      "hint": "GET /v1/shipments/clxq1w2e3r4t5y6u7i8o9p0a/rates"
    }
  }
}

Refresca, elige un nuevo rateId y vuelve a comprar. También verás este error si usas un rateId que pertenece a otro envío.

Cotiza sin crear un envío

Para widgets de checkout o estimaciones previas, usa el endpoint independiente:

Parámetros del cuerpo

PropType
originobjeto

El origen. Requiere al menos { postalCode }.

Typeobjeto
destinationobjeto

El destino. Requiere al menos { postalCode }.

Typeobjeto
parcelobjeto

El paquete: length, width, height (cm) y weight (kg).

Typeobjeto
curl -X POST https://api.sendit.mx/v1/rates \
  -H "X-API-Key: sk_test_..." \
  -H "Content-Type: application/json" \
  -d '{
    "origin": { "postalCode": "03940" },
    "destination": { "postalCode": "45050" },
    "parcel": { "weight": 1.5, "length": 20, "width": 15, "height": 10 }
  }'

La respuesta trae rates[] (el mismo objeto tarifa de arriba) y su vigencia:

{
  "success": true,
  "data": {
    "rates": [
      { "id": "DHL_standard_a1b2c3", "carrierCode": "DHL", "serviceCode": "EXPRESS_WORLDWIDE", "serviceLevel": "standard", "totalPrice": 88.40, "currency": "MXN", "isInsured": false }
    ],
    "expiresAt": "2026-07-18T14:30:00.000Z"
  }
}

Estas tarifas son solo informativas: no se pueden usar para comprar una guía. Para comprar, crea primero el envío. Puedes limitar a una paquetería (POST /v1/rates/carrier/DHL) u ordenar con ?sortBy=price o ?sortBy=speed.

Ordena las tarifas

const porPrecio = [...rates].sort((a, b) => a.totalPrice - b.totalPrice);
const porVelocidad = [...rates].sort(
  (a, b) => a.estimatedDays.min - b.estimatedDays.min || a.totalPrice - b.totalPrice
);

¿Te ha resultado útil esta página?