Guías
Una guía es el documento central del flujo logístico de TPC. Representa un envío desde que se crea hasta que es entregado o devuelto.
Estados de una guía
SIN_RECOLLECTAR → RECOLECTADO → EN_BODEGA → EN_RUTA → ENTREGADO
↘ DEVOLUCION → DEVOLUCION_ENTREGADO
↘ SINIESTRO (robo/extravío)
↘ DANADA (dañada en tránsito)
ANULADA ← (solo desde SIN_RECOLLECTAR)
ENTREGADO_LIQUIDADO (post-liquidación)| Estado | Descripción |
|---|---|
SIN_RECOLLECTAR | Guía creada, pendiente de recolección |
RECOLECTADO | Recolectada en bodega del cliente |
EN_BODEGA | En bodega TPC, clasificando para despacho |
EN_RUTA | Asignada a mensajero, en camino al destinatario |
ENTREGADO | Entregada exitosamente al destinatario |
DEVOLUCION | En proceso de devolución al remitente |
DEVOLUCION_ENTREGADO | Devuelta y entregada al remitente |
ANULADA | Cancelada (solo posible en SIN_RECOLLECTAR) |
ENTREGADO_LIQUIDADO | Entregada y liquidada contablemente |
SINIESTRO | Robada o extraviada — reclamo de seguro abierto (ver módulo Reclamos) |
DANADA | Dañada en tránsito, nunca llegó a destino — reclamo de seguro abierto |
Una guía que se dañó después de ser entregada conserva su estado ENTREGADO/ENTREGADO_LIQUIDADO —
DANADA solo aplica cuando el paquete nunca llegó a su destino. El flete se sigue facturando
normalmente en ambos casos; el reclamo de seguro cubre el valor de la mercadería, por separado.
GET/api/v1/guiasListar guías
Lista todas las guías de tu empresa con soporte de filtros y paginación.
Query params
| Parámetro | Tipo | Default | Descripción |
|---|---|---|---|
estado | string | — | Filtrar por estado (ver tabla de estados) |
fechaDesde | YYYY-MM-DD | — | Guías creadas desde esta fecha (inclusive) |
fechaHasta | YYYY-MM-DD | — | Guías creadas hasta esta fecha (inclusive, hasta las 23:59:59 hora Guatemala) |
page | integer | 1 | Número de página (máx. 1000; para ir más atrás acota fechaDesde/fechaHasta) |
limit | integer | 20 | Resultados por página (máximo 100) |
Ejemplos
Todas las guías
curl "https://api.tpcxpress.com/api/v1/guias" \
-H "Authorization: Bearer TOKEN"Respuesta 200
{
"success": true,
"data": {
"guias": [
{
"id": "cluuid123",
"numeroGuia": "TPCP123456789",
"estado": "EN_RUTA",
"esCOD": false,
"montoTotal": null,
"direccionEntrega": "8va Avenida 12-34 zona 11",
"municipioDestino": "Mixco",
"destinatario": {
"nombre": "Juan Pérez",
"telefono": "55551234",
"ciudad": "Mixco"
},
"tipoServicio": "ESTANDAR",
"costoServicio": 30.00,
"createdAt": "2026-07-06T14:00:00.000Z",
"fechaEntrega": null
}
],
"meta": {
"total": 150,
"page": 1,
"limit": 20,
"totalPages": 8
}
}
}POST/api/v1/guiasCrear guía
Crea una nueva guía de envío. Si tu empresa es PREPAGO, consume 1 crédito, salvo que el destinatario pague el envío (COD_PRODUCTO_ENVIO, ENVIO_POR_COBRAR) o que el envío se descuente del cobro (COD_PRODUCTO con descontarEnvioDelCobro: true) — ver Créditos y Facturación.
Número de guía. TPCE + 9 dígitos si la guía cobra en la puerta, TPCP + 9 dígitos si es prepagada. Los dígitos no son consecutivos: no los uses para ordenar guías ni para inferir cuántas se crearon — usa createdAt.
Idempotency-Key (recomendado)
Si un request se corta por timeout no sabes si la guía se creó. Envía un header Idempotency-Key único por operación (por ejemplo un UUID que guardes junto a tu pedido) y reintenta con la misma clave:
Idempotency-Key: pedido-48213-2026-10-15- El mismo request con la misma clave, dentro de 24 h, devuelve la respuesta original (header
Idempotency-Replayed: true) sin crear ni cobrar otra guía. - La misma clave con un body distinto →
409 IDEMPOTENCY_KEY_REUSED. - Si el primero todavía se procesa →
409 IDEMPOTENCY_IN_PROGRESS; reintenta en unos segundos. - Si el request falló (validación, sin créditos…) la clave queda libre: corrige y reintenta con ella.
- Es opcional: sin el header todo funciona como antes, pero un reintento puede duplicar la guía.
Body
Campos requeridos
| Campo | Tipo | Descripción |
|---|---|---|
tipoServicio | "ESTANDAR" | "COD" | Tipo de servicio. Obsoleto — usa modalidadCobro, que cubre las cuatro formas de cobro. Se sigue aceptando. |
ciudadDestino | string (2–100 chars) | Municipio de destino |
nombreDestinatario | string (2–150 chars) | Nombre completo de quien recibe |
telefonoDestinatario | string (7–30 chars) | Teléfono de contacto del destinatario |
direccionDestinatario | string (5–300 chars) | Dirección completa de entrega |
Campos opcionales
| Campo | Tipo | Descripción |
|---|---|---|
modalidadCobro | ver abajo | Qué paga el destinatario en la puerta. Si se omite, se deduce de tipoServicio. |
costoProducto | number (positivo, máx. 1000000) | Requerido cuando la modalidad cobra producto (COD_PRODUCTO, COD_PRODUCTO_ENVIO). Valor del producto, sin el envío. |
correoDestinatario | string (email) | Correo electrónico del destinatario |
obsDestinatario | string (máx 500) | Instrucciones especiales de entrega |
telefonoAlternoDestinatario | string (máx 30) | Teléfono alternativo del destinatario |
descontarEnvioDelCobro | boolean | Solo COD_PRODUCTO. true = no consume crédito: el envío (y la comisión COD) se descuentan del cobro antes de depositarte. El producto debe cubrir el envío. Se ignora en otras modalidades y en empresas con plan personalizado. |
fechaRecoleccion | YYYY-MM-DD | Fecha preferida de recolección. Se interpreta como medianoche en hora de Guatemala (UTC-6). |
Modalidad de cobro
modalidadCobro define exactamente qué cobra el mensajero al entregar. Es lo que se
imprime en la etiqueta, así que determina cuánto efectivo se recoge en la puerta.
| Valor | Qué cobra el mensajero | costoProducto |
|---|---|---|
PREPAGADO | Nada. El envío ya está pagado. | — |
COD_PRODUCTO | El valor del producto. El envío lo pagas con 1 crédito, o con descontarEnvioDelCobro: true se descuenta de tu depósito (ej. cobramos Q100, envío Q35 → te depositamos Q65 menos comisión COD). | requerido |
COD_PRODUCTO_ENVIO | Producto + costo del envío. A ti se te deposita el producto íntegro. | requerido |
ENVIO_POR_COBRAR | Solo el costo del envío. No hay producto de por medio. | — |
{
"modalidadCobro": "COD_PRODUCTO_ENVIO",
"costoProducto": 450.00,
"ciudadDestino": "Mixco",
"nombreDestinatario": "María López",
"telefonoDestinatario": "5555-1234",
"direccionDestinatario": "5a Avenida 10-20, Zona 1"
}Empresas con plan personalizado. Si tu empresa factura por período
(POSTPAGO), el envío se liquida en tu factura y nunca se le cobra al
destinatario. Las modalidades que pasan el flete al destinatario se degradan
automáticamente a su equivalente sin flete: COD_PRODUCTO_ENVIO se guarda
como COD_PRODUCTO y ENVIO_POR_COBRAR como PREPAGADO. La guía se crea
igual; solo cambia lo que el mensajero cobra.
Compatibilidad. tipoServicio sigue funcionando: "ESTANDAR" equivale a
PREPAGADO y "COD" a COD_PRODUCTO. Si mandas ambos, manda modalidadCobro.
Las integraciones existentes no necesitan cambios.
Datos del remitente — se toman automáticamente de la configuración de tu empresa (nombre, teléfono, ciudad de origen).
Ejemplos
Servicio Estándar
curl -X POST https://api.tpcxpress.com/api/v1/guias \
-H "Authorization: Bearer TOKEN" \
-H "Content-Type: application/json" \
-d '{
"tipoServicio": "ESTANDAR",
"ciudadDestino": "Mixco",
"nombreDestinatario": "Ana García",
"telefonoDestinatario": "55554321",
"direccionDestinatario": "8va Avenida 12-34 zona 11",
"obsDestinatario": "Llamar 30 min antes de llegar"
}'Respuesta 201
{
"success": true,
"data": {
"numeroGuia": "TPCE123456789",
"estado": "SIN_RECOLLECTAR",
"pdfUrl": "https://api.tpcxpress.com/api/v1/guias/TPCE123456789/pdf",
"createdAt": "2026-07-06T14:30:00.000Z"
}
}El campo pdfUrl apunta al endpoint público de descarga. Requiere tu token en el header Authorization. Ver PDF de guía.
GET/api/v1/guias/{numeroGuia}Detalle
Retorna el detalle completo de una guía, incluyendo datos del destinatario, servicio y todos los timestamps relevantes.
curl https://api.tpcxpress.com/api/v1/guias/TPCP123456789 \
-H "Authorization: Bearer TOKEN"Respuesta 200
{
"success": true,
"data": {
"id": "cluuid123",
"numeroGuia": "TPCP123456789",
"estado": "EN_RUTA",
"pdfUrl": "https://api.tpcxpress.com/api/v1/guias/TPCP123456789/pdf",
"esCOD": false,
"montoTotal": null,
"municipioDestino": "Mixco",
"destinatario": {
"nombre": "Ana García",
"correo": "ana@example.com",
"telefono": "55554321",
"direccion": "8va Avenida 12-34 zona 11",
"ciudad": "Mixco",
"observaciones": "Llamar 30 min antes de llegar"
},
"servicio": {
"tipo": "ESTANDAR",
"costoEnvio": 30.00,
"costoProducto": null,
"cantidadPaquetes": "1"
},
"timestamps": {
"createdAt": "2026-07-06T14:00:00.000Z",
"recolectadoEn": "2026-07-06T09:00:00.000Z",
"asignadoEn": "2026-07-06T10:30:00.000Z",
"fechaProgramada": null,
"fechaEntrega": null
}
}
}| Campo | Descripción |
|---|---|
pdfUrl | URL del PDF de la guía — requiere token en Authorization |
esCOD | true si es servicio Cobro Contra Entrega |
montoTotal | Monto a cobrar al destinatario (solo COD) |
servicio.costoEnvio | Costo del servicio de mensajería (lo que paga la empresa) |
timestamps.recolectadoEn | Cuando TPC recolectó el paquete |
timestamps.asignadoEn | Cuando se asignó a un mensajero |
timestamps.fechaEntrega | Cuando se completó la entrega (null si no entregada) |
PATCH/api/v1/guias/{numeroGuia}Editar guía
Edita los datos del destinatario o dirección de una guía. Solo es posible mientras la guía está en estado SIN_RECOLLECTAR.
Una vez que TPC recolecta la guía (estado RECOLECTADO o posterior), los datos del destinatario no pueden modificarse via API. Contacta a soporte para correcciones urgentes.
Body
Al menos un campo es requerido. Solo se actualizan los campos enviados.
| Campo | Tipo | Descripción |
|---|---|---|
nombreDestinatario | string (2–150) | Nombre del destinatario |
telefonoDestinatario | string (7–30) | Teléfono principal |
telefonoAlternoDestinatario | string (máx 30) | null | Teléfono alternativo |
correoDestinatario | string (email) | "" | Correo del destinatario |
direccionDestinatario | string (5–300) | Dirección de entrega |
ciudadDestino | string (2–100) | Municipio de destino. Recalcula el precio — ver abajo. |
obsDestinatario | string (máx 500) | null | Instrucciones de entrega |
Cambiar ciudadDestino cambia el precio. Se valida la cobertura del
municipio nuevo y se recalcula costoServicio con su tarifa. Si el
destinatario paga el envío, el monto que cobra el mensajero se ajusta solo.
Si el municipio nuevo no tiene cobertura, el PATCH falla con
422 MUNICIPIO_NO_CUBIERTO y no se modifica nada.
Ejemplo
# Corregir dirección y agregar teléfono alterno
curl -X PATCH https://api.tpcxpress.com/api/v1/guias/TPCE123456789 \
-H "Authorization: Bearer TOKEN" \
-H "Content-Type: application/json" \
-d '{
"direccionDestinatario": "8va Avenida 15-20 zona 11, apto 3B",
"telefonoAlternoDestinatario": "44448888",
"obsDestinatario": "Portón azul, timbre 3B"
}'Respuesta 200
Retorna el objeto guía completo con los datos actualizados (mismo formato que GET /guias/{numeroGuia}).
Errores específicos
{
"success": false,
"error": {
"message": "No se puede editar una guía con estado \"RECOLECTADO\". Solo es posible editar guías en estado SIN_RECOLLECTAR.",
"code": "INVALID_STATE"
}
}El estado se vuelve a comprobar al guardar: si el mensajero recolecta la guía mientras tu request está en curso, responde el mismo 409 INVALID_STATE y no se aplica ningún cambio.
DELETE/api/v1/guias/{numeroGuia}Anular
Anula una guía. Solo es posible en estado SIN_RECOLLECTAR.
La anulación es irreversible — la guía pasa a estado ANULADA permanentemente y no puede reactivarse.
curl -X DELETE https://api.tpcxpress.com/api/v1/guias/TPCE123456789 \
-H "Authorization: Bearer TOKEN"Respuesta 200
{
"success": true,
"data": {
"numeroGuia": "TPCE123456789",
"estado": "ANULADA",
"creditoDevuelto": true
}
}creditoDevuelto es true cuando la guía había consumido un crédito (PREPAGO) y este volvió a tu saldo.
Error 409 Estado inválido
{
"success": false,
"error": {
"message": "No se puede anular una guía con estado \"EN_RUTA\". Solo es posible anular guías en estado SIN_RECOLLECTAR.",
"code": "INVALID_STATE"
}
}Preguntas frecuentes
¿Qué pasa con los créditos si anulo una guía? Si la guía consumió un crédito (PREPAGO), el crédito vuelve a tu saldo en el momento de anularla, en la misma operación. Las guías POSTPAGO o en las que el destinatario paga el envío no consumen crédito, así que no hay nada que devolver.
¿Puedo cambiar la modalidad de cobro de una guía ya creada?
No. La modalidad (y tipoServicio) son inmutables una vez creada la guía. Anula y crea una nueva si necesitas cambiarla.
Si cambio ciudadDestino con PATCH, ¿cambia el precio?
Sí. Al cambiar el destino se recalcula costoServicio con la tarifa del municipio nuevo, y si el destinatario paga el envío (COD_PRODUCTO_ENVIO o ENVIO_POR_COBRAR) también se ajusta el monto que cobra el mensajero. Si el municipio nuevo no tiene cobertura, el PATCH se rechaza con 422 MUNICIPIO_NO_CUBIERTO y la guía queda intacta.
¿Cómo sé si el municipio de destino tiene cobertura?
Consulta GET /api/v1/municipios para ver la lista de municipios activos. Si el municipio no tiene cobertura, la API rechazará la creación con 422 MUNICIPIO_NO_CUBIERTO.