# PedidosYa Courier API v3 - Request/Response Schemas

Documentación completa de los esquemas de Request y Response para todos los endpoints de PedidosYa Courier API v3.

## Información General

**Base URL:** `https://courier-api.pedidosya.com`

**Autenticación:** Todas las solicitudes requieren el header `Authorization` con tu token:
```
Authorization: YOUR_TOKEN_HERE
```

**Documentación Oficial:** 
- [API Reference](https://developers.pedidosya.com/courier-api/v3)
- [Developer Portal](https://developers.pedidosya.com/courier-doc)
- [Generar Token](https://developers.pedidosya.com/courier-doc/first-steps#generate-token)

**Rate Limiting:** No realizar consultas excesivas (tracking se actualiza cada 30-60 segundos)

---

## Endpoints Adicionales Disponibles

Además de los 4 endpoints principales documentados abajo, la API ofrece:

- `GET /v3/shippings` - Listar envíos por rango de fechas (máx 15 días, 100 items por página)
- `GET /v3/shippings/{shippingId}` - Obtener detalles de un envío
- `GET /v3/shippings/{shippingId}/tracking` - Tracking en tiempo real (lat/lon del rider)
- `GET /v3/shippings/{shippingId}/proofOfDelivery` - Prueba de entrega (imagen base64)
- `GET /v3/shippings/{shippingId}/proofOfDelivery/pin` - PIN de validación de entrega
- `GET /v3/shippings/labels?values={ids}` - Generar etiquetas PDF (1-50 envíos)
- `PUT /v3/shippings/{shippingId}/deliveryInstructions` - Actualizar instrucciones
- `GET /v3/shippings/{shippingId}/callbacks` - Ver callbacks enviados a tu webhook
- `POST /v3/estimates/coverage` - Verificar cobertura de waypoints
- `GET /v3/working-zones` - Obtener zonas de trabajo (DEPRECATED)
- `GET /v3/schedules` - Obtener horarios de la flota
- `PUT /v3/webhooks-configuration` - Configurar webhooks para callbacks
- `GET /v3/webhooks-configuration` - Obtener configuración de webhooks
- `DELETE /v3/webhooks-configuration` - Eliminar configuración de webhook

---

## 1. Estimate Shipping Order

**Endpoint:** `POST /v3/shippings/estimates`

**Descripción:** Obtener cotización de envío con diferentes ofertas de delivery.

Este endpoint permite estimar un pedido de envío. La estimación te permitirá saber cuándo el pedido puede o no puede ser entregado dentro de los diferentes waypoints. Además, recibirás una estimación de la distancia y el precio del pedido de envío.

Este endpoint devolverá una lista de **delivery offers**, cada una tiene un tiempo máximo de confirmación. Más detalles en el endpoint de confirmación.

### Notas Importantes sobre deliveryTime

- **Si NO envías `deliveryTime`:** En casos donde los envíos se crean cerca del horario de cierre de la flota de riders, el envío será asignado para el próximo horario de apertura disponible, podría ser el día siguiente.

- **Si envías un `deliveryTime` específico:** Se calcula el tiempo estimado de pickup. Si este tiempo es después del cierre de la flota, tu envío será rechazado con el motivo: `INVALID_DELIVERY_TIME` (el tiempo de entrega está fuera del horario de la flota).

**(*) IMPORTANTE:** El precio puede variar al publicar el pedido según el uso de la flota. No dudes en contactar a PedidosYa para más información sobre este punto.

**Referencia:** [PedidosYa Courier API - Shipping Creation](https://developers.pedidosya.com/courier-doc/shipping-creation)

### Validaciones de PedidosYa

Cuando realizas la estimación, PedidosYa valida que:
- La dirección de retiro y la de entrega estén dentro del área de cobertura
- La distancia entre direcciones no exceda la distancia máxima preestablecida
- Todos los campos necesarios estén ingresados correctamente

### Modalidades de Envío

#### MODALIDAD INMEDIATA (EXPRESS)
Envíos que llegan en menos de 1 hora. Pueden crearse para entrega el mismo día o programarse hasta los siguientes 5 días.

#### MODALIDAD FRANJA HORARIA (STACKING/SCHEDULED)
Disponible previo acuerdo con equipo comercial. Permite entregar varios paquetes con menos repartidores. Beneficios:
- Envíos más económicos
- Mayor organización para retiro de paquetes
- Entregas en 3 horas o menos el mismo día

### Distancias Máximas por País

| País | Distancia Máxima |
|------|------------------|
| Argentina | 15 km |
| Bolivia | 15 km |
| Chile | 10 km |
| Costa Rica | 25 km |
| Ecuador | 20 km |
| El Salvador | 15 km |
| Guatemala | 20 km |
| Honduras | 15 km |
| Nicaragua | 15 km |
| Panamá | 15 km |
| Perú | 20 km |
| Paraguay | 15 km |
| Rep. Dominicana | 15 km |
| Uruguay | 15 km |
| Venezuela | 15 km |

**Nota:** Estas distancias son por defecto y pueden ajustarse según acuerdos con PedidosYa.

### Códigos de Error Comunes

| Código | Descripción |
|--------|-------------|
| `WAYPOINT_OUT_OF_ZONE` | Una o ambas direcciones fuera de zona de cobertura |
| `WAYPOINTS_NOT_FOUND` | No se encontró lat/long para las direcciones |
| `MAX_DISTANCE_EXCEEDED` | Excede distancia máxima preestablecida |
| `INVALID_DELIVERY_TIME` | Plazo de entrega fuera del horario de flota |
| `TEMPORARILY_CLOSED` | Flota temporalmente fuera de servicio |
| `DELAY_IN_ZONE_FOR_DELIVERY_TIME` | Retraso de flota en zona para hora deseada |
| `MAX_VALUE_EXCEEDED` | Valor declarado mayor al máximo permitido |
| `MAX_ITEMS_EXCEEDED` | Superado número de productos permitidos |
| `MAX_WAYPOINTS_EXCEEDED` | Superado número de direcciones permitidas |
| `MAX_WAYPOINTS_TYPE_EXCEEDED` | Solo existe una dirección para retiro |
| `MAX_VOLUME_EXCEEDED` | Excedido límite de volumen |
| `MAX_WEIGHT_EXCEEDED` | Excedido límite de peso |
| `MAX_ITEM_QUANTITY_EXCEEDED` | Excedida cantidad de productos |
| `JSON_INVALID` | JSON inválido detectado |

### Request Body Schema

```json
{
  "referenceId": "string (required, <= 255 chars)",
  "deliveryTime": "string (optional, date-time, default: YYYY-MM-DDTHH:MM:SSZ - as soon as possible)",
  "isTest": "boolean (optional, default: false)",
  "items": [
    {
      "type": "string (optional, default: STANDARD, enum: STANDARD|FRAGILE|COLD)",
      "value": "number (required, 0-1000000)",
      "description": "string (required, <= 235 chars)",
      "sku": "string (optional, <= 50 chars)",
      "quantity": "integer (required, 1-10000)",
      "volume": "number (required, 0-80840 cm³)",
      "weight": "number (required, 0-10 kg)"
    }
  ],
  "waypoints": [
    {
      "type": "string (required, enum: PICK_UP|DROP_OFF)",
      "addressStreet": "string (required, <= 255 chars)",
      "addressAdditional": "string (optional, <= 150 chars)",
      "latitude": "number (optional)",
      "longitude": "number (optional)",
      "phone": "string (required, <= 14 chars)",
      "name": "string (required, <= 70 chars)",
      "instructions": "string (optional, <= 255 chars)",
      "city": "string (required, <= 255 chars)",
      "collectMoney": "number (optional, only for DROP_OFF)"
    }
  ],
  "notificationMail": "string (optional, <= 255 chars)",
  "requirements": "object (optional)",
  "includeDeliveryFee": "boolean (optional, default: false)"
}
```

### Request Example

```json
{
  "referenceId": "Client Internal Reference",
  "isTest": true,
  "notificationMail": "email@email.com",
  "items": [
    {
      "type": "STANDARD",
      "value": 1250.6,
      "description": "Some book.",
      "sku": "ABC123",
      "quantity": 1,
      "volume": 10.01,
      "weight": 0.5
    },
    {
      "type": "STANDARD",
      "value": 250,
      "description": "T-Shirt",
      "sku": "ABC124",
      "quantity": 1,
      "volume": 10.01,
      "weight": 0.3
    }
  ],
  "waypoints": [
    {
      "type": "PICK_UP",
      "addressStreet": "Plaza Independencia 755",
      "addressAdditional": "Piso 6 Recepción",
      "city": "Montevideo",
      "latitude": -34.905988,
      "longitude": -56.199592,
      "phone": "+59898765432",
      "name": "Oficina Ciudad Vieja",
      "instructions": "El ascensor esta roto."
    },
    {
      "type": "DROP_OFF",
      "latitude": -34.9138414,
      "longitude": -56.1837661,
      "addressStreet": "La Cumparsita 1475",
      "addressAdditional": "Piso 1, Oficina Delivery",
      "city": "Montevideo",
      "phone": "+59812345678",
      "name": "Agustin",
      "instructions": "Entregar en mano",
      "collectMoney": 125
    }
  ]
}
```

### Response Schema

```json
{
  "estimateId": "string (<= 255 chars, pattern: [0-9]+)",
  "referenceId": "string (<= 255 chars)",
  "isTest": "boolean (default: false)",
  "items": [
    {
      "type": "string (enum: STANDARD|FRAGILE|COLD)",
      "value": "number (0-1000000)",
      "description": "string (<= 235 chars)",
      "sku": "string (<= 50 chars)",
      "quantity": "integer (1-10000)",
      "volume": "number (0-80840)",
      "weight": "number (0-10)"
    }
  ],
  "waypoints": [
    {
      "type": "string (enum: PICK_UP|DROP_OFF)",
      "addressStreet": "string (<= 255 chars)",
      "addressAdditional": "string (<= 150 chars)",
      "latitude": "number",
      "longitude": "number",
      "phone": "string (<= 14 chars)",
      "name": "string (<= 70 chars)",
      "instructions": "string (<= 255 chars)",
      "city": "string (<= 255 chars)",
      "collectMoney": "number (optional, DROP_OFF only)",
      "payMoney": "number (optional, PICK_UP only)",
      "collectDeliveryFeeMoney": "number (optional, DROP_OFF only)",
      "payDeliveryFeeMoney": "number (optional, PICK_UP only)"
    }
  ],
  "routes": {
    "distance": "number (meters)"
  },
  "deliveryOffers": [
    {
      "deliveryOfferId": "string (<= 255 chars)",
      "deliveryMode": "string (enum: EXPRESS|SCHEDULED|CROSS_DOCKING)",
      "estimatedPickUpTime": "string (date-time, ISO 8601)",
      "estimatedDrivingTime": "integer (minutes)",
      "deliveryTimeFrom": "string (date-time, ISO 8601)",
      "deliveryTimeTo": "string (date-time, ISO 8601)",
      "confirmationTimeLimit": "string (date-time, ISO 8601)",
      "pricing": {
        "subTotal": "number",
        "taxes": "number",
        "total": "number",
        "currency": "string (enum: UYU|CLP|ARS|USD|BRL|COP|PEN|VES|MXN|PAB|PYG|CRC|BOB|DOP)"
      }
    }
  ],
  "notificationMail": "string (<= 255 chars)"
}
```

### Response Example

```json
{
  "estimateId": "520644687847685483",
  "referenceId": "Client Internal Reference",
  "isTest": true,
  "items": [
    {
      "type": "STANDARD",
      "value": 1250.6,
      "description": "Some book.",
      "sku": "ABC123",
      "quantity": 1,
      "volume": 10.01,
      "weight": 0.5
    }
  ],
  "waypoints": [
    {
      "type": "PICK_UP",
      "addressStreet": "Plaza Independencia 755",
      "addressAdditional": "Piso 6 Recepción",
      "city": "Montevideo",
      "latitude": -34.905988,
      "longitude": -56.199592,
      "phone": "+59898765432",
      "name": "Oficina Ciudad Vieja",
      "instructions": "El ascensor esta roto."
    },
    {
      "type": "DROP_OFF",
      "latitude": -34.9138414,
      "longitude": -56.1837661,
      "addressStreet": "La Cumparsita 1475",
      "addressAdditional": "Piso 1, Oficina Delivery",
      "city": "Montevideo",
      "phone": "+59812345678",
      "name": "Agustin",
      "instructions": "Entregar en mano"
    }
  ],
  "routes": {
    "distance": 123
  },
  "deliveryOffers": [
    {
      "deliveryOfferId": "679db4989914e48805f3303eb29c4dec",
      "deliveryMode": "EXPRESS",
      "confirmationTimeLimit": "2023-04-08T17:12:40Z",
      "pricing": {
        "subTotal": 131.36,
        "taxes": 0,
        "total": 131.36,
        "currency": "UYU"
      }
    },
    {
      "deliveryOfferId": "679db4989914e48805f3303eb29c4dec",
      "deliveryMode": "SCHEDULE",
      "deliveryTimeFrom": "2023-04-06T11:00:00Z",
      "deliveryTimeTo": "2023-04-06T14:00:00Z",
      "confirmationTimeLimit": "2023-04-06T10:37:00Z",
      "pricing": {
        "subTotal": 131.36,
        "taxes": 0,
        "total": 131.36,
        "currency": "UYU"
      }
    },
    {
      "deliveryOfferId": "679db4989914e48805f3303eb29c4dec",
      "deliveryMode": "CROSS_DOCKING",
      "estimatedPickUpTime": "2023-04-04T13:00:00Z",
      "deliveryTimeFrom": "2023-04-04T15:00:00Z",
      "deliveryTimeTo": "2023-04-04T18:00:00Z",
      "confirmationTimeLimit": "2023-04-04T12:55:00Z",
      "pricing": {
        "subTotal": 131.36,
        "taxes": 0,
        "total": 131.36,
        "currency": "UYU"
      }
    }
  ],
  "notificationMail": "email@email.com"
}
```

### Delivery Modes

- **EXPRESS**: Envío lo antes posible
- **SCHEDULED**: Envío en ventana horaria específica
- **CROSS_DOCKING**: Pickup y delivery en horarios distintos

### Phone Format
- Prefijo opcional con símbolo `+`
- Solo números (sin letras)
- Debe comenzar con número entre 1-9
- Luego 5 a 14 dígitos (0-9)

---

## 2. Confirm Estimate Order

**Endpoint:** `POST /v3/shippings/estimates/{estimateId}/confirm`

**URL:** `https://courier-api.pedidosya.com/v3/shippings/estimates/{estimateId}/confirm`

**Descripción:** Confirmar una estimación de envío seleccionando la modalidad preferida.

Una vez realizada la estimación, una de las ofertas de entrega disponibles puede ser confirmada. Una vez confirmada, recibirás un **código de confirmación** en la respuesta. Usa este 'Confirmation Code' cuando necesites contactar al call center de PedidosYa en caso de problemas con la entrega del pedido.

### Notas Importantes

- **Fecha-hora máxima de confirmación:** Cada modalidad de envío tiene un tiempo límite (`confirmationTimeLimit`) para poder cumplir con la promesa de entrega. Pasado ese tiempo, la modalidad ya no estará vigente.

- **Expiración de estimaciones:** No necesitas descartar o cancelar estimaciones. Las mismas expiran automáticamente cuando sus modalidades ya no están vigentes y no se han confirmado a tiempo.

- **Después del tiempo límite:** Si pasó el `confirmationTimeLimit`, deberás utilizar otra modalidad o volver a estimar tu envío.

- **Código de confirmación:** Guarda el `confirmationCode` devuelto para comunicarte con soporte de PedidosYa.

### Path Parameters

- **estimateId** (required): `string` <= 255 characters, pattern: `[0-9]+` - Identificador de la estimación

### Request Body Schema

```json
{
  "deliveryOfferId": "string (optional, <= 255 chars)"
}
```

**Campos:**
- `deliveryOfferId` (opcional): ID de la oferta de entrega. Si no se especifica, se considerará válida la primera oferta disponible.

### Request Example

```json
{
  "deliveryOfferId": "679db4989914e48805f3303eb29c4dec"
}
```

### Response Schema

```json
{
  "estimateId": "string (<= 255 chars, pattern: [0-9]+)",
  "shippingId": "string (<= 255 chars)",
  "confirmationCode": "string (<= 255 chars)",
  "isTest": "boolean (default: false)",
  "referenceId": "string (<= 255 chars)",
  "status": "string (enum: REJECTED|CONFIRMED|IN_PROGRESS|NEAR_PICKUP|PICKED_UP|NEAR_DROPOFF|COMPLETED|CANCELLED)",
  "proofOfDelivery": "boolean",
  "shareLocationUrl": "string (<= 255 chars)",
  "notificationMail": "string (<= 255 chars)",
  "onlineSupportUrl": "string (DEPRECATED)",
  "items": [
    {
      "type": "string (enum: STANDARD|FRAGILE|COLD)",
      "value": "number (0-1000000)",
      "description": "string (<= 235 chars)",
      "sku": "string (<= 50 chars)",
      "quantity": "integer (1-10000)",
      "volume": "number (0-80840)",
      "weight": "number (0-10)"
    }
  ],
  "waypoints": [
    {
      "type": "string (enum: PICK_UP|DROP_OFF)",
      "addressStreet": "string (<= 255 chars)",
      "addressAdditional": "string (<= 150 chars)",
      "latitude": "number",
      "longitude": "number",
      "phone": "string (<= 14 chars)",
      "name": "string (<= 70 chars)",
      "instructions": "string (<= 255 chars)",
      "city": "string (<= 255 chars)",
      "collectMoney": "number (optional, DROP_OFF only)",
      "payMoney": "number (optional, PICK_UP only)",
      "collectDeliveryFeeMoney": "number (optional, DROP_OFF only)",
      "payDeliveryFeeMoney": "number (optional, PICK_UP only)"
    }
  ],
  "route": {
    "deliveryMode": "string (enum: EXPRESS|SCHEDULED|CROSS_DOCKING)",
    "estimatedPickUpTime": "string (date-time, ISO 8601)",
    "estimatedDeliveryTime": "string (date-time, ISO 8601)",
    "distance": "number (meters)",
    "pricing": {
      "subTotal": "number",
      "taxes": "number",
      "total": "number",
      "currency": "string (ISO 4217)"
    }
  },
  "createdAt": "string (date-time, ISO 8601)"
}
```

### Shipping Status Values

| Status | Descripción |
|--------|-------------|
| `REJECTED` | Orden de envío solicitada pero rechazada por datos inválidos |
| `CONFIRMED` | Orden de envío confirmada y esperando despacho |
| `IN_PROGRESS` | Transporte asignado |
| `NEAR_PICKUP` | Transporte cerca del punto de recogida |
| `PICKED_UP` | Transporte recogió los artículos |
| `NEAR_DROPOFF` | Transporte cerca del punto de entrega |
| `COMPLETED` | Transporte entregó los artículos |
| `CANCELLED` | Orden de envío cancelada |

### Response Example

```json
{
  "estimateId": "23562302281727155893283",
  "shippingId": "15562302281527156893283",
  "confirmationCode": "9869921368",
  "isTest": true,
  "referenceId": "Order 12344",
  "status": "CONFIRMED",
  "proofOfDelivery": false,
  "shareLocationUrl": "https://example.pedidosya.com.uy/tracking/MTUE1NTY=",
  "notificationMail": "notification@email.com",
  "onlineSupportUrl": "[DEPRECATED]",
  "items": [
    {
      "categoryId": 11986575,
      "categoryName": "Envío",
      "value": 500,
      "description": "Teclado",
      "sku": "ABC123",
      "volume": 1,
      "weight": 1,
      "quantity": 2,
      "type": "STANDARD"
    },
    {
      "categoryId": 11986575,
      "categoryName": "Envío",
      "value": 100,
      "description": "Teclado",
      "volume": 1,
      "weight": 1,
      "quantity": 2,
      "type": "STANDARD"
    }
  ],
  "waypoints": [
    {
      "type": "PICK_UP",
      "addressStreet": "Marco Bruto 1210",
      "city": "Montevideo",
      "latitude": -34.9057308,
      "longitude": -56.1381682,
      "phone": "+5981135344343",
      "name": "Jorge Gutierrez",
      "instructions": "prueta verde "
    },
    {
      "type": "DROP_OFF",
      "addressStreet": "Andes 1111",
      "city": "Montevideo",
      "latitude": -34.9108124,
      "longitude": -56.1979015,
      "phone": "+541144154415",
      "name": "Martin Novo"
    }
  ],
  "route": {
    "deliveryMode": "CROSS_DOCKING",
    "estimatedPickUpTime": "2023-04-04T13:00:00Z",
    "estimatedDeliveryTime": "2023-04-04T23:00:00Z",
    "distance": 6030,
    "pricing": {
      "subTotal": 180,
      "taxes": 0,
      "total": 180,
      "currency": "UYU"
    }
  },
  "createdAt": "2023-02-28T15:27:15Z"
}
```

### Campos Importantes de la Respuesta

- **confirmationCode**: Úsalo para contactar al call center en caso de problemas
- **shippingId**: Identificador único del envío
- **shareLocationUrl**: URL para rastrear el envío (solo para pedidos reales, no de prueba)
- **proofOfDelivery**: Indica si hay prueba de entrega (firma o foto)
- **onlineSupportUrl**: Campo DEPRECADO. Para soporte, ingresa a https://envios.pedidosya.com

---

## 3. Create Shipping Order

**Endpoint:** `POST /v3/shippings`

**URL:** `https://courier-api.pedidosya.com/v3/shippings`

**Descripción:** Creación de órdenes en un solo paso sin pasar por estimación y confirmación.

Puedes crear una orden de envío de forma directa. Puedes indicar un `deliveryTime` (fecha y hora) en formato UTC; si no se indica, se asumirá "lo antes posible". Si todas las validaciones son correctas, la orden quedará confirmada inmediatamente.

En la respuesta recibirás un **código de confirmación**. Usa este 'Confirmation Code' cuando necesites contactar al call center de PedidosYa en caso de problemas con el pedido de envío.

### Notas Importantes sobre deliveryTime

- **Si NO envías `deliveryTime`:** En casos donde los envíos se crean cerca del horario de cierre de la flota de riders, el envío será asignado para el próximo horario de apertura disponible, podría ser el día siguiente.

- **Si envías un `deliveryTime` específico:** Se calcula el tiempo estimado de pickup. Si este tiempo es después del cierre de la flota, tu envío será rechazado con el motivo: `INVALID_DELIVERY_TIME` (el tiempo de entrega está fuera del horario de la flota).

### Proceso de Creación

#### 1. Documento con Datos del Envío
Debes enviar un JSON con:
- Lista de productos a enviar
- Direcciones de retiro y entrega
- Tiempo de entrega deseado (lo antes posible o fecha/horario dentro de 5 días)
- Peso y volumen del envío (pueden ser 0 si no hay datos disponibles)
- Indicador `isTest` si es una prueba

#### 2. Validación de Datos
PedidosYa validará:
- Direcciones dentro de zona de trabajo de la flota
- Peso y volumen dentro de lo determinado
- Tiempo de entrega posible (ajustará y comunicará en caso de demora)

#### 3. Creación del Envío
PedidosYa devolverá:
- Identificador de envío (PedidosYa ID / shippingId)
- Código de confirmación
- Costo del envío creado
- Tiempo de entrega estimado

### Cobro de Efectivo (Cash Collection)

**Disponible previo acuerdo con equipo comercial**

Puedes cobrar efectivo usando el campo `collectMoney` para la dirección de entrega (DROP_OFF).

**Funcionamiento:**
- Existe un monto máximo a cobrar por envío
- Sin costo adicional
- PedidosYa te hace llegar el dinero en el momento

### Request Body Schema

```json
{
  "referenceId": "string (required, <= 255 chars)",
  "deliveryTime": "string (optional, date-time, default: YYYY-MM-DDTHH:MM:SSZ - as soon as possible)",
  "isTest": "boolean (optional, default: false)",
  "items": [
    {
      "type": "string (optional, default: STANDARD, enum: STANDARD|FRAGILE|COLD)",
      "value": "number (required, 0-1000000)",
      "description": "string (required, <= 235 chars)",
      "sku": "string (optional, <= 50 chars)",
      "quantity": "integer (required, 1-10000)",
      "volume": "number (required, 0-80840 cm³)",
      "weight": "number (required, 0-10 kg)"
    }
  ],
  "waypoints": [
    {
      "type": "string (required, enum: PICK_UP|DROP_OFF)",
      "addressStreet": "string (required, <= 255 chars)",
      "addressAdditional": "string (optional, <= 150 chars)",
      "latitude": "number (optional)",
      "longitude": "number (optional)",
      "phone": "string (required, <= 14 chars)",
      "name": "string (required, <= 70 chars)",
      "instructions": "string (optional, <= 255 chars)",
      "city": "string (required, <= 255 chars)",
      "collectMoney": "number (optional, only for DROP_OFF)"
    }
  ],
  "notificationMail": "string (optional, <= 255 chars)",
  "requirements": {
    "includeDeliveryFee": "boolean (optional, default: false)"
  }
}
```

**Campos Importantes:**
- **items**: Mínimo 1, máximo 100 items. La suma de valores declarados debe ser menor a 1 millón
- **waypoints**: Exactamente 2 (uno PICK_UP, uno DROP_OFF)
- **collectMoney**: Solo para DROP_OFF. Funcionalidad no activada por defecto
- **includeDeliveryFee**: Si cobro de efectivo está habilitado, incluye costo de envío en el total a cobrar
- **notificationMail**: Email para enviar notificaciones de estado (confirmación, en progreso, completado, cancelación)

### Request Example

```json
{
  "referenceId": "Client Internal Reference",
  "isTest": true,
  "notificationMail": "email@email.com",
  "items": [
    {
      "type": "STANDARD",
      "value": 1250.6,
      "description": "Some book.",
      "sku": "ABC123",
      "quantity": 1,
      "volume": 10.01,
      "weight": 0.5
    },
    {
      "type": "STANDARD",
      "value": 250,
      "description": "T-Shirt",
      "sku": "ABC124",
      "quantity": 1,
      "volume": 10.01,
      "weight": 0.3
    }
  ],
  "waypoints": [
    {
      "type": "PICK_UP",
      "addressStreet": "Plaza Independencia 755",
      "addressAdditional": "Piso 6 Recepción",
      "city": "Montevideo",
      "latitude": -34.905988,
      "longitude": -56.199592,
      "phone": "+59898765432",
      "name": "Oficina Ciudad Vieja",
      "instructions": "El ascensor esta roto."
    },
    {
      "type": "DROP_OFF",
      "latitude": -34.9138414,
      "longitude": -56.1837661,
      "addressStreet": "La Cumparsita 1475",
      "addressAdditional": "Piso 1, Oficina Delivery",
      "city": "Montevideo",
      "phone": "+59812345678",
      "name": "Agustin",
      "instructions": "Entregar en mano",
      "collectMoney": 200
    }
  ],
  "requirements": {
    "includeDeliveryFee": true
  }
}
```

### Response Schema

```json
{
  "shippingId": "string (<= 255 chars)",
  "confirmationCode": "string (<= 255 chars)",
  "isTest": "boolean (default: false)",
  "referenceId": "string (<= 255 chars)",
  "status": "string (enum: REJECTED|CONFIRMED|IN_PROGRESS|NEAR_PICKUP|PICKED_UP|NEAR_DROPOFF|COMPLETED|CANCELLED)",
  "proofOfDelivery": "boolean",
  "shareLocationUrl": "string (<= 255 chars)",
  "notificationMail": "string (<= 255 chars)",
  "onlineSupportUrl": "string (DEPRECATED)",
  "items": [
    {
      "type": "string (enum: STANDARD|FRAGILE|COLD)",
      "value": "number (0-1000000)",
      "description": "string (<= 235 chars)",
      "sku": "string (<= 50 chars)",
      "quantity": "integer (1-10000)",
      "volume": "number (0-80840)",
      "weight": "number (0-10)"
    }
  ],
  "waypoints": [
    {
      "type": "string (enum: PICK_UP|DROP_OFF)",
      "addressStreet": "string (<= 255 chars)",
      "addressAdditional": "string (<= 150 chars)",
      "latitude": "number",
      "longitude": "number",
      "phone": "string (<= 14 chars)",
      "name": "string (<= 70 chars)",
      "instructions": "string (<= 255 chars)",
      "city": "string (<= 255 chars)",
      "collectMoney": "number (optional, DROP_OFF only)",
      "payMoney": "number (optional, PICK_UP only)",
      "collectDeliveryFeeMoney": "number (optional, DROP_OFF only)",
      "payDeliveryFeeMoney": "number (optional, PICK_UP only)"
    }
  ],
  "route": {
    "deliveryMode": "string (enum: EXPRESS|SCHEDULED|CROSS_DOCKING)",
    "estimatedPickUpTime": "string (date-time, ISO 8601)",
    "deliveryTimeFrom": "string (date-time, ISO 8601)",
    "deliveryTimeTo": "string (date-time, ISO 8601)",
    "distance": "number (meters)",
    "pricing": {
      "subTotal": "number",
      "taxes": "number",
      "total": "number",
      "currency": "string (ISO 4217)"
    }
  },
  "createdAt": "string (date-time, ISO 8601)"
}
```

### Response Example

```json
{
  "shippingId": "15562302281527156893283",
  "confirmationCode": "9869921368",
  "isTest": true,
  "referenceId": "Order 12344",
  "status": "CONFIRMED",
  "proofOfDelivery": false,
  "shareLocationUrl": "https://example.pedidosya.com.uy/tracking/MTUE1NTY=",
  "notificationMail": "notification@email.com",
  "onlineSupportUrl": "[DEPRECATED]",
  "items": [
    {
      "categoryId": 11986575,
      "categoryName": "Envío",
      "value": 500,
      "description": "Teclado",
      "sku": "ABC123",
      "volume": 1,
      "weight": 1,
      "quantity": 2,
      "type": "STANDARD"
    },
    {
      "categoryId": 11986575,
      "categoryName": "Envío",
      "value": 100,
      "description": "Teclado",
      "volume": 1,
      "weight": 1,
      "quantity": 2,
      "type": "STANDARD"
    }
  ],
  "waypoints": [
    {
      "type": "PICK_UP",
      "addressStreet": "Marco Bruto 1210",
      "city": "Montevideo",
      "latitude": -34.9057308,
      "longitude": -56.1381682,
      "phone": "+5981135344343",
      "name": "Jorge Gutierrez",
      "instructions": "prueta verde ",
      "payMoney": 200,
      "payDeliveryFeeMoney": 180
    },
    {
      "type": "DROP_OFF",
      "addressStreet": "Andes 1111",
      "city": "Montevideo",
      "latitude": -34.9108124,
      "longitude": -56.1979015,
      "phone": "+541144154415",
      "name": "Martin Novo",
      "collectMoney": 200,
      "collectDeliveryFeeMoney": 180
    }
  ],
  "route": {
    "deliveryMode": "CROSS_DOCKING",
    "estimatedPickUpTime": "2023-03-01T13:00:00Z",
    "estimatedDrivingTime": 120,
    "deliveryTimeFrom": "2023-03-01T15:00:00Z",
    "deliveryTimeTo": "2023-03-01T18:00:00Z",
    "distance": 6030,
    "pricing": {
      "subTotal": 180,
      "taxes": 0,
      "total": 180,
      "currency": "UYU"
    }
  },
  "createdAt": "2023-02-28T15:27:15Z"
}
```

### Campos Importantes de la Respuesta

- **shippingId**: Identificador único del envío
- **confirmationCode**: Úsalo para contactar al call center en caso de problemas
- **shareLocationUrl**: URL para rastrear el envío (solo para pedidos reales, no de prueba)
- **status**: Estado inicial típicamente es `CONFIRMED`
- **route.deliveryMode**: Modalidad asignada (EXPRESS, SCHEDULED o CROSS_DOCKING)
- **payMoney / collectMoney**: Montos a cobrar en pickup/dropoff respectivamente
- **payDeliveryFeeMoney / collectDeliveryFeeMoney**: Costo de envío a cobrar separadamente

---

## 4. Cancel Shipping Order

**Endpoint:** `POST /v3/shippings/{shippingId}/cancel`

**URL:** `https://courier-api.pedidosya.com/v3/shippings/{shippingId}/cancel`

**Descripción:** Cancelar una orden de envío según su estado actual.

**Restricción importante:** Solo los envíos con estado `CONFIRMED` pueden ser cancelados usando este endpoint. Una vez que el envío tiene estado `IN_PROGRESS`, es necesario contactar a PedidosYa para la solicitud de cancelación.

Más información sobre cancelaciones [aquí](https://developers.pedidosya.com/courier-doc/shipping-creation#shipping-cancelation).

### Tipos de Cancelación

#### Cancelación de Envío Confirmado (Por API)
**Estado:** `CONFIRMED`
- Envío creado pero sin repartidor asignado
- Se puede cancelar directamente por API usando este endpoint
- Campo `reasonText` es **requerido**

#### Cancelación de Envío en Curso (Por Soporte)
**Estados:** `IN_PROGRESS`, `NEAR_PICKUP`, `PICKED_UP`, `NEAR_DROPOFF`
- Envío con repartidor asignado llevando el paquete
- **NO se puede cancelar por API**
- Debes chatear con equipo de PedidosYa:
  - Opción 1: Usar campo de soporte devuelto al crear el envío
  - Opción 2: Desde plataforma web "Mis Envíos" → botón "Solicitar ayuda"

### Recomendación
Siempre comunicar el motivo de cancelación para mejorar el servicio.

**Referencia:** Ver [Estados de un envío](https://developers.pedidosya.com/courier-doc/shipping-tracking) para más detalles.

### Path Parameters

- **shippingId** (required): `string` <= 255 characters, pattern: `[a-zA-Z0-9-]+` - Identificador del envío

### Request Body Schema

```json
{
  "reasonText": "string (required, <= 255 chars)"
}
```

**Campos:**
- `reasonText` (requerido): Breve razón de cancelación. Ejemplos: "canceled by end user", "wrong shipping info", etc.

### Request Example

```json
{
  "reasonText": "Reason explanation for cancellation request"
}
```

### Response Schema

```json
{
  "shippingId": "string (<= 255 chars)",
  "isTest": "boolean (default: false)",
  "referenceId": "string (<= 255 chars)",
  "createdAt": "string (date-time, ISO 8601)",
  "lastUpdated": "string (date-time, ISO 8601)",
  "status": "string (enum: REJECTED|CONFIRMED|IN_PROGRESS|NEAR_PICKUP|PICKED_UP|NEAR_DROPOFF|COMPLETED|CANCELLED)",
  "confirmationCode": "string (<= 255 chars)",
  "cancelCode": "string (CancelCode enum)",
  "cancelReason": "string (<= 255 chars)",
  "proofOfDelivery": "boolean",
  "shareLocationUrl": "string (<= 255 chars)",
  "notificationMail": "string",
  "onlineSupportUrl": "string (DEPRECATED)",
  "items": [...],
  "waypoints": [...],
  "route": {...}
}
```

### Cancel Codes (Códigos de Cancelación)

La respuesta incluirá un `cancelCode` y su correspondiente `cancelReason` en español:

| Cancel Code | Cancel Reason (Español) |
|-------------|-------------------------|
| `ADDRESS_DATA_MISSING` | Rider no encuentra el pickup/dropoff |
| `NO_RIDER_AVAILABLE` | No hay cadete disponible en este momento |
| `OUT_OF_DELIVERY_ZONE` | Fuera de área de cobertura del servicio |
| `DELAYED_DELIVERY_SCHEDULE` | Cancelado debido a horario de entrega retrasado |
| `COORDINATE_ERROR` | Coordenadas no concuerdan con la dirección ingresada |
| `PACKAGE_DAMAGE_LOOSE` | Se produjo un problema con el producto o paquete |
| `ORDER_NOT_DELIVERED` | Pedido no entregado |
| `INAPPROPRIATE_CONDUCT` | Cancelado por problemas con el rider |
| `UNREACHABLE_RIDER` | Cancelado por problemas con el rider |
| `TYC_PACKAGE_CONTRADICTION` | Pedido incorrecto. Paquete o producto no respeta TyC. |
| `PURCHASE_REQUESTED` | Pedido realizado por error |
| `USER_CANNOT_PAY` | Solicitud de envío pendiente de pago. El usuario no puede pagar el pedido. |
| `COUPON_NOT_APPLIED` | No fue posible aplicar el cupón. |
| `DUPLICATED_ORDER` | Pedido duplicado |
| `UNREACHABLE_USER_DROPOFF` | No es posible contactar al cliente en Punto de Entrega |
| `SUSPICIOUS_CLIENT` | Pedido incorrecto. |
| `USER_CANCELLED` | Cancelado a solicitud del usuario |
| `TECHNICAL_PROBLEM` | Cancelado por problemas técnicos |
| `BAD_WEATHER` | Condiciones climáticas adversas |
| `UNREACHABLE_USER_PICKUP` | No es posible contactar al cliente en Punto de Retiro |
| `CONTENT_WRONG` | Producto despachado no es correcto. |
| `ORDER_MODIFICATION` | No es posible modificar punto de origen o destino |
| `OUT_OF_FLEET_TIME` | Fuera de horario de servicio |
| `TEST_ORDER` | Orden de prueba - TEST |
| `CONTENT_WRONG_RIDER` | Producto despachado no es correcto |

### Response Example

```json
{
  "shippingId": "15562302161933300562594",
  "isTest": false,
  "referenceId": "Order 1234",
  "createdAt": "2023-02-16T19:33:30Z",
  "lastUpdated": "2023-02-16T22:55:42Z",
  "status": "CANCELLED",
  "confirmationCode": "141150634",
  "cancelReason": "Cancelado por el usuario",
  "cancelCode": "USER_CANCELLED",
  "proofOfDelivery": false,
  "shareLocationUrl": "https://example-courier-web.pedidosya.com.uy/tracking/QVBJIzE1NTY=",
  "notificationMail": "example@example.com",
  "onlineSupportUrl": "[DEPRECATED]",
  "items": [
    {
      "value": 500,
      "description": "Teclado mecánico Anne Pro 2",
      "sku": "ABC123",
      "volume": 1,
      "weight": 1,
      "quantity": 2,
      "type": "STANDARD"
    },
    {
      "value": 100,
      "description": "Teclado mecánico Anne Pro 2",
      "sku": "ABC122",
      "volume": 1,
      "weight": 1,
      "quantity": 2,
      "type": "STANDARD"
    }
  ],
  "waypoints": [
    {
      "type": "PICK_UP",
      "addressStreet": "Marco Bruto 1210",
      "city": "Montevideo",
      "latitude": -34.9057308,
      "longitude": -56.1381682,
      "phone": "+5981135344343",
      "name": "jorge guitierrez",
      "instructions": "prueta verde "
    },
    {
      "type": "DROP_OFF",
      "addressStreet": "Marco Bruto 1200",
      "city": "Montevideo",
      "latitude": -34.9061331,
      "longitude": -56.1381033,
      "phone": "+541144154415",
      "name": "martin test"
    }
  ],
  "route": {
    "deliveryMode": "CROSS_DOCKING",
    "estimatedPickUpTime": "2023-02-17T13:00:00Z",
    "estimatedDrivingTime": 120,
    "deliveryTimeFrom": "2023-02-17T15:00:00Z",
    "deliveryTimeTo": "2023-02-17T18:00:00Z",
    "distance": 54,
    "pricing": {
      "subTotal": 180,
      "taxes": 0,
      "total": 180,
      "currency": "UYU"
    }
  }
}
```

### Campos Importantes de la Respuesta

- **status**: Será `CANCELLED` si la cancelación fue exitosa
- **cancelCode**: Código de cancelación del enum
- **cancelReason**: Mensaje en español explicando el motivo
- **lastUpdated**: Fecha/hora de última actualización (cuando se canceló)
- Los campos `cancelCode` y `cancelReason` solo están presentes si `status` es `CANCELLED`

---

## Notas Importantes

- Todos los timestamps deben estar en formato UTC ISO 8601: `YYYY-MM-DDTHH:MM:SSZ`
- El header de autenticación usa: `X-PedidosYa-Token`
- Los valores monetarios tienen 2 decimales
- Volumen en cm³, peso en kg, distancia en metros
