Antes de registrar un pedido necesitas saber qué distritos cubre GSG, qué tamaños existen, qué agencias y sucursales puedes usar y cuánto costará el servicio. El catálogo entrega todo eso en una sola llamada; la cotización calcula la tarifa exacta de tu negocio con las mismas reglas que el registro.
GET /api/v1/integration/catalogs
Devuelve los catálogos de referencia. Sin store_token (plataformas) las tarifas son las
públicas; con tienda (o integración directa) además incluye your_courier_cost con el descuento
del negocio y el bloque business. Respuesta con Cache-Control: private, max-age=300.
curl "https://{BASE_URL}/api/v1/integration/catalogs" \
-H "X-API-Key: gsg_PREFIJO_SECRETO" \
-H "X-Store-Token: st_TOKEN_DE_TIENDA"
{
"message": { "description": "Ok", "title": "OK OK", "code": "90200" },
"data": {
"api_version": "1.4",
"generated_at": "2026-09-03T15:00:00.000Z",
"ttl_seconds": 300,
"currency": "PEN",
"includes_igv": true,
"features": { "xl_enabled": true, "xl_auto_classification": true, "package_pricing": true, "agency_catalog": true },
"route_types": [
{ "id": 1, "code": "DELIVERY", "name": "Entrega a domicilio", "tracking_prefix": "GSG-E-",
"requires": ["district", "address"],
"notes": "Courier (moto) o GSG XL (van) según el tamaño enviado." },
{ "id": 2, "code": "AGENCY", "name": "Envío por agencia", "tracking_prefix": "GSG-A-",
"requires": ["number_document", "agency_code | agency_id | agency_name", "pay_at_destination"],
"notes": "Agencia partner (Shalom, Olva, Marvisur): sin dirección ni distrito, GSG la lleva a la sucursal. Otra agencia: destination_address + district de la agencia." },
{ "id": 3, "code": "EXCHANGE", "name": "Cambio", "tracking_prefix": "GSG-C-",
"requires": ["district", "address", "number_packages_in"],
"notes": "Se entrega el paquete nuevo y se recogen number_packages_in bultos del destinatario." },
{ "id": 4, "code": "GSG_OFFICE", "name": "Recojo en sede GSG", "tracking_prefix": "GSG-L-",
"requires": ["sede"],
"notes": "El destinatario retira en la sede GSG indicada; address y district los fija la sede." },
{ "id": 7, "code": "FLEX_DELIVERY", "name": "Entrega Flex", "tracking_prefix": "GSG-F-",
"requires": ["district", "address"],
"notes": "Entrega de última milla estilo Mercado Libre Flex; mismo cuerpo que Entrega." }
],
"package_sizes": [
{ "code": "S", "name": "Chico", "service": "COURIER",
"max_dimensions_cm": { "width": 30, "height": 20, "depth": 12 },
"max_weight_kg": null, "max_side_cm": null, "max_volume_m3": null,
"max_weight_kg": 3, "max_side_cm": null, "max_volume_m3": null,
"extra_cost": 0, "legacy_only": false, "aliases": ["PEQUEÑO", "PEQUENO", "PEQUENIO", "CHICO"] },
{ "code": "M", "name": "Mediano", "service": "COURIER", "max_dimensions_cm": { "width": 35, "height": 25, "depth": 20 },
"max_weight_kg": 3, "max_side_cm": null, "max_volume_m3": null, "extra_cost": 5, "legacy_only": false, "aliases": ["MEDIANO"] },
{ "code": "L", "name": "Grande", "service": "COURIER", "max_dimensions_cm": { "...": "..." },
"max_weight_kg": 3, "max_side_cm": null, "max_volume_m3": null, "extra_cost": 5, "legacy_only": true, "aliases": ["GRANDE"] },
{ "code": "XL_GRANDE", "name": "XL Grande", "service": "XL", "max_dimensions_cm": null,
"max_weight_kg": 10, "max_side_cm": 60, "max_volume_m3": 0.216, "extra_cost": null, "legacy_only": false, "aliases": ["XL GRANDE"] },
{ "code": "XL_PLUS", "name": "XL Plus", "service": "XL", "max_dimensions_cm": null,
"max_weight_kg": 15, "max_side_cm": 80, "max_volume_m3": 0.512, "extra_cost": null, "legacy_only": false, "aliases": ["XL PLUS"] },
{ "code": "XL_MAX", "name": "XL Max", "service": "XL", "max_dimensions_cm": null,
"max_weight_kg": 25, "max_side_cm": 100, "max_volume_m3": 1, "extra_cost": null, "legacy_only": false, "aliases": ["XL MAX"] }
],
"districts": [
{ "id": 22, "name": "MIRAFLORES", "courier_cost": 10, "sending": "Todos los días",
"zone": { "code": "BASE", "name": "Base" },
"xl": { "XL_GRANDE": 20, "XL_PLUS": 25, "XL_MAX": 30 },
"your_courier_cost": 9 },
{ "id": 9, "name": "CIENEGUILLA", "courier_cost": 25, "sending": "Lunes, Miercoles y Sabado",
"zone": { "code": "LEJANA", "name": "Lejana" },
"xl": { "XL_GRANDE": 35, "XL_PLUS": 50, "XL_MAX": 60 }, "your_courier_cost": 24 }
],
"sedes": [
{ "name": "ATE", "address": "Centro Comercial Jessie - Ctra. Central 51, Ate 15023" },
{ "name": "LOS OLIVOS", "address": "El Amargon 3830" },
{ "name": "LA VICTORIA", "address": "GAMA Moda Plaza - Av. Aviación 2571" }
],
"agencies": [
{ "id": 1, "code": "SHALOM", "name": "Shalom", "partner": true,
"aliases": ["SHALOM", "SHALOM SANTA ANITA"],
"branches": [
{ "id": 3, "code": "SHALOM_SANTA_ANITA", "name": "Santa Anita", "address": "Av. ... 123", "reference": "Frente a ..." }
] },
{ "id": 4, "code": "OTHER", "name": "Otra agencia", "partner": false, "aliases": [], "branches": [] }
],
"payment_methods": [
{ "code": "EFECTIVO", "name": "Efectivo" }, { "code": "PAGADO", "name": "Pagado" },
{ "code": "PLIN", "name": "Plin" }, { "code": "TARJETA", "name": "Tarjeta" },
{ "code": "TRANSFERENCIA", "name": "Transferencia" }, { "code": "YAPE", "name": "Yape" }
],
"order_cutoff": { "cutoff_time": "15:00", "timezone": "America/Lima" },
"open_policy": {
"options": [
{ "code": "SEALED", "name": "No se puede abrir", "short_name": "No abrir",
"description": "El destinatario recibe el paquete cerrado. Solo puede revisar el estado exterior antes de recibirlo.",
"driver_instructions": "Entrega el paquete cerrado. Si el cliente quiere abrirlo antes de recibirlo o pagar, no está permitido: puede rechazarlo.",
"max_wait_minutes": 0 },
{ "code": "INSPECT", "name": "Puede abrir y revisar", "short_name": "Puede revisar",
"description": "El destinatario puede abrir el paquete y revisar el producto antes de recibirlo o pagar, sin usarlo ni probárselo.",
"driver_instructions": "Deja que el cliente abra y revise el producto frente a ti. Si lo rechaza, toma foto del producto y regístralo como RECHAZADO.",
"max_wait_minutes": 3 },
{ "code": "TRY_ON", "name": "Puede abrir y probar", "short_name": "Puede probar",
"description": "El destinatario puede abrir el paquete y probarse el producto (ropa, calzado) antes de recibirlo o pagar.",
"driver_instructions": "Espera mientras el cliente se prueba el producto. Si no le queda o no lo quiere, recibe el producto completo, toma foto y regístralo como RECHAZADO.",
"max_wait_minutes": 5 }
],
"route_types": [1, 3, 4, 7],
"system_default": "SEALED"
},
"states": [
{ "id": 3, "code": "REGISTRADO", "name": "REGISTRADO", "detail": "Tu envío ha sido registrado…", "final": false },
{ "id": 14, "code": "ENTREGADO", "name": "ENTREGADO", "detail": "…", "final": true }
],
"logistic_states": [
{ "code": "AT_PROVIDER", "label": "Pendiente de ingreso a almacén GSG" },
{ "code": "IN_WAREHOUSE", "label": "En almacén GSG" }
],
"limits": {
"order_external_id_max": 120, "idempotency_key_max": 100, "full_name_max": 150,
"telephone_max": 15, "number_document_max": 30, "address_max": 200, "address_reference_max": 350,
"product_max": 500, "product_detail_max": 1000, "observation_max": 250, "pay_comments_max": 250,
"order_number_max": 120, "destination_address_max": 250, "list_page_max": 100, "list_range_days_max": 92
},
"business": { "id": 2120, "name": "Ctrl go", "discount": 1, "default_open_policy": "TRY_ON" }
}
}
Los valores de tarifa, dimensiones de M/L, agencias y sucursales del ejemplo son ilustrativos: usa siempre los que devuelve tu llamada.
features| Campo | Significado |
|---|---|
xl_enabled | Si es false, las categorías XL no aparecen en package_sizes, districts[].xl es null y un pedido XL responde 400. |
xl_auto_classificationv1.1 | Si es true, puedes enviar "size": "XL" con weight_kg, width_cm, height_cm y depth_cm por bulto y GSG elige la categoría (API de pedidos § 6). |
package_pricing | Si es true, el recargo extra_cost de los tamaños courier se suma a la tarifa (tipos 1, 2, 3, 7). Si es false, extra_cost llega en 0. |
agency_catalog | Catálogo de agencias activo (identificación por agency_code/agency_id). |
route_typesLos cinco tipos de ruta aceptados con su code (el mismo que devuelven route_type_code en pedidos y webhooks), el prefijo del code_tracking, los campos que requires y notas operativas. Detalle de obligatorios en API de pedidos § 7.
package_sizes| Campo | Significado |
|---|---|
code | Valor canónico para size/size_code del pedido. |
service | COURIER (moto) o XL (van). |
max_dimensions_cm | Ancho × alto × fondo máximos del tamaño courier. null en XL. |
max_weight_kg, max_side_cm, max_volume_m3 | Límites por bulto: en courier solo el peso (máximo que va en moto); en XL peso, lado mayor y volumen de la categoría. Son los que usa la clasificación automática. |
extra_cost | Recargo aditivo del tamaño courier (0 si package_pricing está apagado). null en XL: la tarifa por zona ya incluye la categoría. |
legacy_onlyv1.1 | true = se acepta solo por compatibilidad (hoy L). No lo ofrezcas en tu UI. |
aliases | Otros valores aceptados en size que se normalizan a este código. |
districts| Campo | Significado |
|---|---|
name | Nombre exacto a enviar en district (en mayúsculas; la comparación ignora tildes). |
courier_cost | Tarifa courier pública del distrito (S/, IGV incluido) para un bulto S. |
your_courier_cost | Tarifa courier de tu negocio: máx(0, courier_cost − business.discount). Sin tienda resuelta es igual a courier_cost. |
sending | Días de reparto del distrito (texto operativo, p. ej. "Todos los días", "Lunes, Miercoles y Sabado"). Úsalo para no programar date_route en días sin reparto. |
zonev1.1 | Zona tarifaria del distrito ({ "code": "BASE", "name": "Base" }; hoy BASE, INTERMEDIA, LEJANA, MUY_LEJANA). Define la tarifa XL. null si el distrito no tiene zona asignada. |
xl | Tarifa XL por bulto según la zona del distrito y la categoría ({ "XL_GRANDE": 20, "XL_PLUS": 25, "XL_MAX": 30 }) o null si el distrito no tiene cobertura XL. Puede faltar alguna categoría: en ese caso un pedido con esa categoría responde 400. |
Solo se listan distritos con cobertura vigente; un distrito que no aparece aquí devuelve 400 al registrar.
sedesSedes GSG para el tipo 4 (recojo en sede): name es el valor a enviar en sede; address es la dirección que verá el destinatario.
agencies| Campo | Significado |
|---|---|
code, id | Identificadores para agency_code (recomendado) o agency_id. |
partner | true: GSG lleva el paquete a la sucursal de la agencia; no exige district, destination_address ni telephone. false (p. ej. OTHER): GSG entrega en la dirección de la agencia (destination_address + district obligatorios). |
aliases | Nombres con los que se reconoce la agencia si la envías por agency_name (comparación sin tildes ni mayúsculas). |
branches | Sucursales seleccionables (id para agency_branch_id, code, name, address, reference). Vacío en agencias no partner. |
payment_methodsCódigos aceptados en code_pay_method. PAGADO fuerza los montos de cobro a 0.
open_policyv1.2Opciones de apertura del paquete para el campo open_policy del pedido (API de pedidos § 5.5): ¿el destinatario puede abrir el paquete antes de recibirlo o pagarlo? Son los mismos textos que ven el panel GSG, la app del negocio y el motorizado.
| Campo | Significado |
|---|---|
options[].code | Valor a enviar en open_policy: SEALED (no se puede abrir), INSPECT (puede abrir y revisar, sin usar ni probar), TRY_ON (puede abrir y probar; ropa, calzado). |
options[].name, short_name, description | Textos para mostrar en tu sistema (selector y ayuda). |
options[].driver_instructions | Instrucción que recibe el motorizado. Si el destinatario rechaza tras abrir o probar, se registra RECHAZADO con foto del producto. |
options[].max_wait_minutes | Espera máxima del motorizado en el punto mientras el destinatario revisa o prueba (hoy 3 en INSPECT y 5 en TRY_ON). La configura GSG: léela del catálogo, no la fijes en tu código. |
route_types | Tipos de ruta donde aplica (1, 3, 4 y 7). En tipo 2 (Agencia) GSG guarda null. |
system_default | Valor que se aplica si el negocio no configuró su predeterminado: SEALED. |
order_cutoffv1.3Hora límite para registrar pedidos del mismo día: cutoff_time (HH:mm, o null si GSG no tiene hora límite) en la zona timezone (America/Lima). Hasta esa hora inclusive un pedido para hoy entra normal; desde el minuto siguiente se acepta igual, pero responde after_cutoff: true y queda fuera de hora (GSG puede despacharlo el siguiente día hábil). Úsala para proponer al negocio la fecha del día siguiente pasada la hora. Detalle en API de pedidos § 5.4.1.
states y logistic_statesCatálogo de los 18 estados de seguimiento (id, code, name, detail pensado para mostrar al comprador, final) y de los estados logísticos (code, label). Significado de cada uno en Seguimiento § 5.
limitsLargos máximos de los campos de texto del pedido, tamaño máximo de página del listado (list_page_max) y rango máximo de fechas del listado (list_range_days_max). Úsalos para validar en tu lado antes de llamar.
businessnull si no hay tienda resuelta. Con tienda: id, name, discount (descuento en soles que GSG aplica a la tarifa courier del negocio) y
default_open_policyv1.2: la apertura que se aplica cuando el pedido no envía open_policy (la que el negocio configuró en su perfil GSG o, si no configuró ninguna, SEALED). Úsala para preseleccionar la opción en tu formulario.
La tarifa del servicio es lo que GSG cobra al negocio por el envío (IGV incluido). No tiene relación con cost/advance, que es lo que el destinatario paga por el producto.
| Caso | Base | Descuento del negocio | Recargos | pricing_rule |
|---|---|---|---|---|
| Tipos 1, 3, 7 · tamaño courier (S/M/L) | districts[].courier_cost | Sí (your_courier_cost) | package_sizes[].extra_cost del tamaño si features.package_pricing | DISTRICT_BASE_V1 |
| Tipos 1, 3, 7 · tamaño XL | districts[].xl[categoría] × number_packages (tarifa de la zona del distrito) | No (precio cerrado) | Ninguno | XL_ZONE_TARIFF_V1 |
| Cualquier caso con convenio por empresa | Precio pactado con GSG para ese tamaño (por envío en courier, por bulto en XL y agencia partner) | No (el convenio es final) | Ninguno | BUSINESS_AGREEMENT_V1 |
| Tipo 2 · agencia partner · courier | Tarifa por agencia (fija o mínimo sobre el distrito de la sede GSG) | Según la tarifa de la agencia | + S/ 2.00 si package_registered = 0, + S/ 0.50 si package_labeled = 0; tamaño según tarifa | AGENCY_FIXED_V1 / AGENCY_MINIMUM_V1 |
| Tipo 2 · agencia partner · XL | Tarifa XL fija de la agencia por categoría × bultos (o tarifa de la zona del distrito si la agencia no tiene tarifa fija) | No | Registro / rotulado como arriba | AGENCY_FIXED_XL_V1 / XL_ZONE_TARIFF_V1 |
| Tipo 2 · otra agencia | Tarifa del district de la agencia (courier con descuento, o matriz XL) | Solo courier | + recargo de gestión en agencia externa (agency_handling_cost) | AGENCY_DISTRICT_SURCHARGE_V1 |
| Tipo 4 · recojo en sede GSG | Tarifa plana de recojo (S/ 8.00) | No | — | GSG_OFFICE_V1 |
total = your_courier_cost + extra_cost(tamaño). Ejemplo: MIRAFLORES (10) con descuento 1 y tamaño M (extra 2) → 9 + 2 = 11.total = districts[].xl[categoría]. Ejemplo: MIRAFLORES + XL_PLUS → 28, sin descuento ni recargo de tamaño.POST /quote para conocer el monto exacto de un envío por agencia.POST /quote (misma lógica y misma base de datos) y se confirma en service_cost de la respuesta del registro.POST /api/v1/integration/quote — cotización previa
Calcula la tarifa del servicio GSG para un envío usando la tarifa real del negocio. Acepta los mismos campos del
pedido que afectan el precio; no exige identidad del destinatario ni modalidad de cobro. No crea nada ni
consume order_external_id.
| Campo | Obligatorio | Notas |
|---|---|---|
route_type | Sí | 1, 2, 3, 4 o 7. |
district | Según tipo | Obligatorio en 1, 3, 7 y en agencia no partner / por agency_name. No en tipo 4 ni en partner por agency_code/agency_id. |
size o size_code | No | S/M/L o XL_*. Default S. |
sede | Tipo 4 | ATE, LOS OLIVOS, LA VICTORIA. |
agency_code | agency_id | agency_name | Tipo 2 | Igual que en el registro. |
agency_branch_id, destination_address | No | destination_address es obligatorio si la agencia resuelta no es partner. |
package_registered, package_labeled | No | 0/1; solo afectan a partners. |
number_packages_in | No | Solo en el registro (tipo 3). En la cotización no se exige porque no afecta el precio; si lo envías debe ser entero ≥ 1. |
POST {BASE_URL}/api/v1/integration/quote
X-API-Key: gsg_PREFIJO_SECRETO
X-Store-Token: st_TOKEN_DE_TIENDA
Content-Type: application/json
{ "route_type": 1, "district": "MIRAFLORES", "size": "XL_PLUS" }
{
"message": { "description": "Ok", "title": "OK OK", "code": "90200" },
"data": {
"route_type": 1,
"route_type_code": "DELIVERY",
"service": "XL",
"size_code": "XL_PLUS",
"district": "MIRAFLORES",
"currency": "PEN",
"includes_igv": true,
"pricing_rule": "XL_ZONE_TARIFF_V1",
"base_cost": 28,
"package_extra_cost": 0,
"agency_handling_cost": 0,
"agency_registration_cost": 0,
"agency_labeling_cost": 0,
"total_service_cost": 28,
"agency": null,
"components": [
{ "code": "BASE", "amount": 28 },
{ "code": "PACKAGE_SIZE", "amount": 0 }
],
"notes": [
"Tarifa del servicio GSG (lo que GSG cobra al negocio por este envío), IGV incluido. No incluye el monto que el destinatario paga por el producto.",
"Tarifa GSG XL cerrada por distrito y categoría; no aplica descuento del negocio."
]
}
}
{ "route_type": 2, "agency_code": "SHALOM", "agency_branch_id": 3, "size": "M", "package_registered": 0, "package_labeled": 1 }
{
"message": { "description": "Ok", "title": "OK OK", "code": "90200" },
"data": {
"route_type": 2, "route_type_code": "AGENCY", "service": "COURIER", "size_code": "M", "district": null,
"currency": "PEN", "includes_igv": true, "pricing_rule": "AGENCY_FIXED_V1",
"base_cost": 4, "package_extra_cost": 2, "agency_handling_cost": 0,
"agency_registration_cost": 2, "agency_labeling_cost": 0,
"total_service_cost": 8,
"agency": { "id": 1, "code": "SHALOM", "name": "Shalom", "partner": true },
"components": [
{ "code": "BASE", "amount": 4 },
{ "code": "PACKAGE_SIZE", "amount": 2 },
{ "code": "AGENCY_REGISTRATION", "amount": 2 }
],
"notes": [
"Tarifa del servicio GSG (lo que GSG cobra al negocio por este envío), IGV incluido. No incluye el monto que el destinatario paga por el producto.",
"Agencia partner: GSG traslada el paquete a la sucursal; el flete de la agencia no está incluido."
]
}
}
| Campo | Significado |
|---|---|
service, size_code | Servicio y tamaño resueltos (tras normalizar alias). |
pricing_rule | Regla aplicada (ver tabla de § 3). |
base_cost | Base: tarifa del distrito (con descuento), matriz XL, tarifa de agencia o tarifa de recojo. |
package_extra_cost | Recargo por tamaño courier (o de categoría XL en recojo en sede). |
agency_handling_cost | Recargo de gestión en agencia externa (otra agencia). |
agency_registration_cost, agency_labeling_cost | Recargos partner cuando envías package_registered = 0 / package_labeled = 0. |
total_service_cost | Suma de todos los componentes. Es el monto que aparecerá en service_cost.total al registrar. |
agency | Agencia resuelta (null fuera del tipo 2). |
components | Desglose: BASE, PACKAGE_SIZE y, si aplican, AGENCY_HANDLING, AGENCY_REGISTRATION, AGENCY_LABELING. |
notes | Textos explicativos para mostrar al usuario de tu sistema. |
Errores 400 con los mismos textos que el registro: distrito sin cobertura, distrito sin cobertura XL, agencia inexistente o no disponible, sede inválida, tamaño inválido, campos obligatorios del tipo de ruta. Ver Referencia de errores. Respuesta con Cache-Control: no-store.
ttl_seconds: 300, cabecera Cache-Control: private, max-age=300). Consultarlo más seguido no trae datos más frescos.generated_at para saber qué versión tienes en caché.POST /quote) no se cachea: llámala cuando necesites mostrar el costo exacto de un envío concreto.| Versión | Fecha | Cambios |
|---|---|---|
| 1.3 | 2026-09-29 | API 1.4: bloque order_cutoff (cutoff_time, timezone) con la hora límite de registro del día.
api_version pasa a "1.4". |
| 1.2 | 2026-09-25 | API 1.3: bloque open_policy (options[] con code, name, short_name, description,
driver_instructions, max_wait_minutes; route_types; system_default) y business.default_open_policy.
api_version pasa a "1.3". |
| 1.1 | 2026-09-15 | Modelo de zonas: districts[].zone; districts[].xl ahora deriva de la zona y se cobra por bulto
(XL_GRANDE, XL_PLUS, XL_MAX; XL_STD retirado del catálogo); features.xl_auto_classification;
package_sizes[].legacy_only y max_weight_kg en courier; /quote acepta size: "XL" + peso/medidas y number_packages;
reglas XL_ZONE_TARIFF_V1, GSG_OFFICE_XL_V1 y BUSINESS_AGREEMENT_V1. |
| 1.0 | 2026-09-03 | Revisión del mismo día: POST /quote no exige number_packages_in (solo el registro tipo 3); el rate limit se expresa por cliente de integración (300/min) más 900/min por IP. |
| 1.0 | 2026-09-03 | Versión inicial: GET /api/v1/integration/catalogs (route_types, package_sizes con XL, districts con
tarifa courier/XL y descuento, sedes, agencies con alias y sucursales, payment_methods, states, logistic_states,
limits, business) y POST /api/v1/integration/quote. |