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

Your first label

Create a shipment, compare rates, and buy your first label (guía) in test mode — from zero to PDF in minutes.

Here you create your first shipping label (guía) in test mode. Test mode uses simulated carriers and a virtual balance. No real money moves. The steps in production are the same. To go live, change the key.

You need a SendIt account and your test key (sk_test_...). Find it in the dashboard under Settings → API keys, or via GET /v1/api-keys.

Create a shipment

A shipment describes the origin, the destination, and the parcel. The response carries the new shipment and rates[]. rates[] holds quotes from every carrier available for that route.

curl -X POST https://api.sendit.mx/v1/shipments \
  -H "X-API-Key: sk_test_..." \
  -H "Content-Type: application/json" \
  -d '{
    "from": {
      "contactName": "Almacén CDMX",
      "contactPhone": "+5215512345678",
      "street": "Av. Insurgentes Sur",
      "exteriorNumber": "1602",
      "neighborhood": "Crédito Constructor",
      "city": "Ciudad de México",
      "state": "CDMX",
      "postalCode": "03940",
      "country": "MX"
    },
    "to": {
      "contactName": "María López",
      "contactPhone": "+5213312345678",
      "street": "Av. López Mateos",
      "exteriorNumber": "45",
      "neighborhood": "Jardines del Sol",
      "city": "Zapopan",
      "state": "JAL",
      "postalCode": "45050",
      "country": "MX"
    },
    "parcel": { "length": 30, "width": 20, "height": 15, "weight": 2.5 }
  }'
const response = await fetch("https://api.sendit.mx/v1/shipments", {
  method: "POST",
  headers: {
    "X-API-Key": process.env.SENDIT_API_KEY, // sk_test_...
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    from: {
      contactName: "Almacén CDMX",
      contactPhone: "+5215512345678",
      street: "Av. Insurgentes Sur",
      exteriorNumber: "1602",
      neighborhood: "Crédito Constructor",
      city: "Ciudad de México",
      state: "CDMX",
      postalCode: "03940",
      country: "MX",
    },
    to: {
      contactName: "María López",
      contactPhone: "+5213312345678",
      street: "Av. López Mateos",
      exteriorNumber: "45",
      neighborhood: "Jardines del Sol",
      city: "Zapopan",
      state: "JAL",
      postalCode: "45050",
      country: "MX",
    },
    parcel: { length: 30, width: 20, height: 15, weight: 2.5 },
  }),
});

const { data: shipment } = await response.json();
console.log(shipment.id, shipment.rates.length);

The (trimmed) response carries the shipment in DRAFT status plus its rates:

{
  "success": true,
  "data": {
    "id": "clxq1w2e3r4t5y6u7i8o9p0a",
    "status": "DRAFT",
    "rates": [
      {
        "id": "DHL_standard_a1b2c3",
        "carrierCode": "DHL",
        "serviceCode": "EXPRESS_WORLDWIDE",
        "serviceName": "DHL Express Nacional",
        "serviceLevel": "standard",
        "totalPrice": 326.82,
        "currency": "MXN",
        "estimatedDays": { "min": 1, "max": 2 },
        "expiresAt": "2026-07-18T14:30:00.000Z"
      },
      {
        "id": "ESTAFETA_economy_x9y8z7",
        "carrierCode": "ESTAFETA",
        "serviceCode": "TERRESTRE",
        "serviceName": "Estafeta Terrestre",
        "serviceLevel": "economy",
        "totalPrice": 289.50,
        "currency": "MXN",
        "estimatedDays": { "min": 3, "max": 5 },
        "expiresAt": "2026-07-18T14:30:00.000Z"
      }
    ],
    "ratesStatus": "ready",
    "ratesExpiresAt": "2026-07-18T14:30:00.000Z"
  }
}

Pick a rate

Each element of rates[] is a firm offer. Its totalPrice includes tax and is exactly what your wallet is charged. Choose by price, speed, or carrier. For the next step you only need the rate’s id.

const cheapest = shipment.rates
  .slice()
  .sort((a, b) => a.totalPrice - b.totalPrice)[0];

console.log(cheapest.id); // "ESTAFETA_economy_x9y8z7"

Rates stay valid for 24 hours. If they expire, fetch fresh ones with GET /v1/shipments/:id/rates?refresh=true.

Buy the label

Send the chosen rateId. The Idempotency-Key header is optional, but send one on this call. If your request is interrupted and you retry with the same key, there is no double charge.

curl -X POST https://api.sendit.mx/v1/shipments/clxq1w2e3r4t5y6u7i8o9p0a/label \
  -H "X-API-Key: sk_test_..." \
  -H "Idempotency-Key: 1f0e6f0e-59a4-4a6f-9d2e-9b1a7b2c3d4e" \
  -H "Content-Type: application/json" \
  -d '{ "rateId": "ESTAFETA_economy_x9y8z7" }'
const purchase = await fetch(
  `https://api.sendit.mx/v1/shipments/${shipment.id}/label`,
  {
    method: "POST",
    headers: {
      "X-API-Key": process.env.SENDIT_API_KEY,
      "Idempotency-Key": crypto.randomUUID(),
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ rateId: cheapest.id }),
  }
);

const { data: label } = await purchase.json();
console.log(label.trackingNumber, label.labelUrl);
{
  "success": true,
  "data": {
    "shipmentId": "clxq1w2e3r4t5y6u7i8o9p0a",
    "labelId": "clxlbl456abc789def012ghi",
    "trackingNumber": "TEST-ESTAFETA-A1B2C3D4",
    "labelUrl": "https://labels.sendit.mx/test/clxq1w2e3r4t5y6u7i8o9p0a/TEST-ESTAFETA-A1B2C3D4.pdf",
    "carrierCode": "ESTAFETA",
    "serviceName": "Estafeta Terrestre",
    "charged": "289.50",
    "currency": "MXN",
    "walletBalanceAfter": "9710.50",
    "breakdown": {
      "ivaAmount": "39.93",
      "overageCharge": "0.00",
      "total": "289.50"
    }
  }
}

Download the PDF from labelUrl. That is your label. The charge came out of the virtual test balance, not real money.

Watch your shipment move

In test mode the parcel simulates its journey on its own. It goes from PICKED_UP to DELIVERED in under half an hour. To skip the wait, advance the status by hand:

curl -X POST https://api.sendit.mx/v1/shipments/clxq1w2e3r4t5y6u7i8o9p0a/test/advance-status \
  -H "X-API-Key: sk_test_..."

Each call advances one step:

LABEL_PURCHASED → READY_FOR_PICKUP → PICKED_UP → IN_TRANSIT → OUT_FOR_DELIVERY → DELIVERED

Check the status and the event history any time with GET /v1/shipments/:id.

Next steps

¿Te ha resultado útil esta página?