---
title: "Solicitar la recolección de un envío propio"
method: POST
path: "/pickups"
tags: ["pickups"]
---

# Solicitar la recolección de un envío propio

`POST /pickups`

## Request

- Base URL: `https://api.enviadores.com.mx/api/v1`
- URL: `https://api.enviadores.com.mx/api/v1/pickups`
- Auth: HTTP bearer

**Solicita** que la paquetería pase por el paquete al domicilio del remitente, en lugar de que el remitente lo lleve a sucursal.

**Esto es una solicitud, no una reserva.** No agendamos con la paquetería de forma automática: el equipo de Enviadores la gestiona y **avisa por correo** al solicitante cuando queda. Por eso la respuesta siempre regresa `status: awaiting_confirmation` — nunca reportes al usuario que ya hay mensajero confirmado. Consulta `GET /pickups/{id}` para el estado final, o espera el correo.

**Por qué.** Un 200 de una paquetería no es prueba de que el mensajero vaya a llegar, y el peor error posible aquí es decirle a alguien que su recolección está confirmada y dejarlo esperando. Preferimos ser lentos y ciertos.

Disponible sólo para **Estafeta, DHL, FedEx y Paquetexpress** (`422 PICKUP_CARRIER_NOT_ELIGIBLE` para el resto; el paquete siempre puede entregarse en sucursal). **Una sola recolección abierta por envío.**

`pickup_date`, `ready_time` y `close_time` son **hora local de México (America/Mexico_City)**; la respuesta devuelve las ventanas en UTC (Z).

La recolección **no cobra saldo**; cualquier cargo de la paquetería llega después por la vía de sobrecargos, igual que en el carril web.

La dirección de recolección es la del propio envío — este endpoint no la cambia. Requiere scope `pickups:write`.

## Request body

- object
  - `shipment_id` string, required: Id de un envío propio con guía, no entregado ni cancelado.
  - `pickup_date` string, required: Fecha local (America/Mexico_City). Hoy o después.
  - `ready_time` string, required: HH:MM 24h local — desde cuándo está listo el paquete.
  - `close_time` string, required: HH:MM 24h local — hasta cuándo puede pasar el mensajero. Debe ser posterior a ready_time.
  - `notes` string: Indicación para el mensajero.

## Response `201`

Solicitud registrada — `status` siempre es `awaiting_confirmation`. Un 201 significa que recibimos la solicitud, NO que haya mensajero confirmado.

- object
  - `success` unknown, required
  - `data` object, required
    - `pickup` Pickup, required
      - `id` integer, required: Id numérico de la recolección.
      - `display_id` string, required: Live: formato `PR%08d`. Sandbox: `SBX-PU-<id>`.
      - `shipment_id` string, nullable, required
      - `status` 'pending' | 'scheduled' | 'awaiting_confirmation' | 'failed' | 'cancelled', required: Una solicitud SIEMPRE nace en `awaiting_confirmation` (se está gestionando; NO la presentes como confirmada). Pasa a `scheduled` cuando el equipo la confirma con la paquetería — ahí llegan `confirmed_window_*` y `confirmation_number`, y se envía el correo al solicitante. `failed` = no se pudo agendar (entregar en sucursal). `cancelled` = la canceló quien la pidió. `pending` no se usa. El sandbox devuelve `awaiting_confirmation`, igual que producción.
      - `carrier` string, nullable: Paquetería física que hará la recolección.
      - `requested_window_start` string, nullable: ISO-8601 UTC (Z). Inicio de la ventana solicitada.
      - `requested_window_end` string, nullable: ISO-8601 UTC (Z). Fin de la ventana solicitada.
      - `confirmed_window_start` string, nullable: ISO-8601 UTC (Z). Ventana confirmada por la paquetería, cuando la devuelve.
      - `confirmed_window_end` string, nullable: ISO-8601 UTC (Z).
      - `confirmation_number` string, nullable: Folio/referencia de recolección de la paquetería.
      - `created_at` string, nullable
      - `updated_at` string, nullable
  - `requestId` string, required: Correlación de logs; también en el header `X-Request-Id`.

## Other responses

- `401`: `UNAUTHORIZED` — credencial Bearer ausente/mal formada o llave desconocida/revocada (respuesta idéntica en ambos casos).
- `403`: `PICKUP_UNAVAILABLE` — la programación de recolecciones aún no está habilitada en esta cuenta (el paquete puede entregarse en sucursal; escríbenos para agendarla manualmente). · `PICKUP_UNLOCK_REQUIRED` — la cuenta todavía sólo puede usar servicios sin recolección; se desbloquea al verificar identidad (INE) en Mi cuenta o al acumular $2,500 MXN en recargas. · `FORBIDDEN` · `INSUFFICIENT_SCOPE` · `PDV_NOT_ALLOWED`.
- `404`: `NOT_FOUND` — el envío no existe o no es de esta llave (respuesta idéntica, sin oráculo de existencia).
- `409`: `CONFLICT` — ya existe una recolección abierta para este envío (`details.existing_request_id`).
- `422`: `VALIDATION_ERROR` (campos en `details.fields`) · `PICKUP_CARRIER_NOT_ELIGIBLE` — la paquetería del envío no está en la lista (`details.eligible_carriers`); el paquete puede entregarse en sucursal · `REQUEST_FAILED` — el envío no admite recolección (sin guía, entregado, cancelado, o fecha/hora imposible).
- `429`: `RATE_LIMITED` — bucket de la llave agotado. Espera `Retry-After` s (`details.retry_after_ms` para el hint fino). El limitador corre antes del gate de scope, por lo que un 429 tiene precedencia sobre un 403 `INSUFFICIENT_SCOPE`.
- `500`: `REQUEST_ERROR`.

---

[API](https://skmtc.dev/enviadores/apis/enviadores-public-api.md) · [All operations](https://skmtc.dev/enviadores/apis/enviadores-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/enviadores/apis/enviadores-public-api/revisions/3633f08c889c?raw)
