Introducción y conceptos base
URL base: https://api.apisperu.pro. Todas las
rutas de este documento cuelgan de /api/v2/...
salvo donde se indique lo contrario. No existe un ambiente de pruebas
separado para la API en sí (SUNAT beta se selecciona por Empresa, ver
abajo).
Dos credenciales, nunca intercambiables. Cada una responde
403 en las rutas de la otra.
| Credencial | Qué controla | Rutas que acepta |
|---|---|---|
| Cuenta (scope=account) | Listar/crear Empresas, consultas públicas (RUC/DNI/tipo de cambio/establecimientos) | GET/POST /companies, GET /account/context, GET /consultas/* |
| Empresa (scope=company) | Operar UNA empresa específica: su ficha, sus credenciales SUNAT, sus comprobantes | GET/PATCH /company, PUT /company/sunat-credentials, PUT /company/gre-credentials, POST /company/digital-certificate, POST/GET /cpe, POST/GET /daily-summaries, POST /dispatch-guides |
La Empresa que emite se resuelve siempre desde la
credencial autenticada (ApiClient.team_id),
nunca desde un company_code en la URL
o el cuerpo: quien tiene la credencial de Empresa no puede elegir sobre cuál
Empresa opera.
Formato de respuesta estándar en todos los endpoints v2:
{ "success": true, "message": "...", "data": { ... } }
Un error de validación (422) reemplaza
data por
errors (mapa de campo → lista de
mensajes). Los endpoints de emisión (/cpe,
/dispatch-guides) agregan además
stored,
retryable y, en éxito,
replay.
Los montos y cantidades se envían siempre como STRING, nunca
como número JSON ("100.000000", no
100): preserva la precisión decimal
exacta que exige un comprobante tributario.
Autenticación
Tokens Sanctum, emitidos con client_id/client_secret
propios de cada credencial (Cuenta o Empresa, generados desde el panel). No
hay OAuth ni flujo de contraseña de usuario: la integración guarda el
client_id/client_secret
como un secreto de servidor.
curl -X POST https://api.apisperu.pro/api/v1/auth/token \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"client_id": "CLI_XXXXXXXXXXXX", "client_secret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}'
{ "success": true, "data": { "access_token": "1|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "token_type": "Bearer" } }
El token resultante se envía en cada llamada como
Authorization: Bearer <access_token>.
Un token de credencial de Cuenta y uno de credencial de Empresa son objetos
distintos con abilities distintas: no son intercambiables entre sí (ver
tabla de la sección anterior).
Un token cuyo client_id/client_secret
ya no existe, o cuya integración fue desactivada/revocada, responde
401 en cualquier ruta protegida.
Cuenta: contexto y consultas
Credencial de Cuenta. Ninguna de estas rutas exige que la Cuenta tenga un plan activo (a diferencia de las consultas, ver abajo): una Cuenta nueva sin Empresas todavía debe poder usarlas.
| Método | Ruta | Para qué |
|---|---|---|
| GET | /api/v2/account/context | Datos de la Cuenta autenticada y resumen de sus Empresas (total/activas/inactivas/borrador) |
| GET | /api/v2/companies | Listado paginado de las Empresas de la Cuenta |
| POST | /api/v2/companies | Registrar una Empresa nueva (puede quedar en borrador, campos opcionales) |
Consultas (exigen plan activo, EnsureAccountHasActivePlan):
| Método | Ruta | Para qué |
|---|---|---|
| GET | /api/consultas/v1/ruc/{ruc} | Ficha de un contribuyente por RUC |
| GET | /api/consultas/v1/dni/{dni} | Datos de una persona por DNI |
| GET | /api/consultas/v1/establecimientos/{ruc} | Locales anexos declarados para un RUC |
| GET | /api/consultas/v1/tipo-cambio?fecha=YYYY-MM-DD | Tipo de cambio SBS de una fecha (por defecto, hoy); informativo — no interviene en la emisión, el emisor sigue enviando el suyo |
GET /consultas/v1/ruc/{ruc} y
GET /consultas/v1/dni/{dni} devuelven
la respuesta plana (sin envolver en
data, a diferencia del resto de la
API); un RUC/DNI inexistente responde 404
con el mismo formato de error. Ambos comparten la misma estructura de campos:
los que no aplican al tipo de documento vienen en
null.
{
"success": true,
"message": "RUC consultado correctamente.",
"document_type": "6",
"document_number": "20131312955",
"entity_type": "company",
"display_name": "SUPERINTENDENCIA NACIONAL DE ADUANAS Y DE ADMINISTRACION TRIBUTARIA - SUNAT",
"business_name": "SUPERINTENDENCIA NACIONAL DE ADUANAS Y DE ADMINISTRACION TRIBUTARIA - SUNAT",
"status": "ACTIVO",
"condition": "HABIDO",
"ubigeo_code": "150101",
"department": "LIMA",
"province": "LIMA",
"district": "LIMA",
"address": "AV. GARCILASO DE LA VEGA NRO. 1472",
"fiscal_address": "AV. GARCILASO DE LA VEGA NRO. 1472 LIMA - LIMA - LIMA",
"location_text": "LIMA - LIMA - LIMA"
}
address se compone a partir de las
piezas sueltas del padrón SUNAT (vía, número, interior, manzana, lote...);
cuando el padrón no las declara para ese contribuyente, viene en
null — dato disperso real, no un
campo ausente de la API.
{
"success": true,
"message": "DNI consultado correctamente.",
"document_type": "1",
"document_number": "41375341",
"entity_type": "person",
"display_name": "MARITZA ABANTO ABANTO",
"full_name": "MARITZA ABANTO ABANTO",
"first_names": "MARITZA",
"last_names": "ABANTO ABANTO",
"paternal_surname": "ABANTO",
"maternal_surname": "ABANTO",
"ubigeo_code": "010101",
"department": "AMAZONAS",
"province": "CHACHAPOYAS",
"district": "CHACHAPOYAS",
"location_text": "AMAZONAS - CHACHAPOYAS - CHACHAPOYAS",
"voting_group": "000001"
}
Un DNI nunca trae address,
status ni
condition; un RUC nunca trae
first_names,
last_names ni
voting_group.
Empresas: ficha y aprovisionamiento
GET/POST /api/v2/companies
(credencial de Cuenta) listan/crean Empresas. Todo lo
demás —ficha, edición y las tres credenciales que una Empresa necesita para
emitir— exige la credencial de esa propia Empresa, sin
company_code: la Empresa se resuelve
desde la credencial.
| Método | Ruta | Para qué |
|---|---|---|
| GET | /api/v2/company | Ficha de la Empresa (datos fiscales + indicadores de configuración) |
| PATCH | /api/v2/company | Actualizar datos fiscales (JSON Merge Patch: campo ausente conserva, presente actualiza) |
| PUT | /api/v2/company/sunat-credentials | Usuario y Clave SOL |
| PUT | /api/v2/company/gre-credentials | client_id/client_secret de la API REST GRE (ver sección Guía de Remisión) |
| POST | /api/v2/company/digital-certificate | Certificado digital PKCS#12 (.pfx/.p12), requisito para emitir en producción |
Las tres rutas de credenciales comparten el mismo patrón: en el primer
guardado ambos campos son obligatorios; en guardados posteriores, la
clave/secreto es opcional —si se omite, se conserva la actual—. Ninguna
respuesta incluye nunca la clave, el secreto ni la contraseña del
certificado: solo un indicador
connected/is_configured
y metadatos públicos.
Emisión de comprobantes: POST /api/v2/cpe
Un solo endpoint para Factura (01),
Boleta (03) y Notas de Crédito/Débito
(07/08).
Credencial de Empresa. Síncrono: prepara el XML, lo firma,
lo transmite a SUNAT y responde en la misma llamada.
{
"external_reference": "erp-venta-2026-000456",
"document_type_code": "01",
"series": "F001",
"number": "123",
"issue_date": "2026-09-24",
"currency_code": "PEN",
"country_code": "PE",
"sunat_establishment_code": "0000",
"operation_type_code": "0101",
"issuer": { "ruc": "20600000001" },
"customer": {
"document_type_code": "6",
"document_number": "20600000001",
"name": "Cliente de Prueba SAC",
"address": "AV. CENTENARIO NRO. 156"
},
"items": [{
"code": "P001",
"description": "Producto de prueba",
"quantity": "2.000000",
"unit_code": "NIU",
"unit_value": "100.000000",
"line_value": "200.000000",
"igv_type_code": "10",
"igv_percentage": "18.000000",
"igv_amount": "36.000000",
"line_total": "236.000000"
}],
"totals": {
"taxable_amount": "200.000000",
"exonerated_amount": "0.000000",
"unaffected_amount": "0.000000",
"igv_amount": "36.000000",
"total_amount": "236.000000"
},
"payment": { "type": "contado" }
}
Series por tipo: Factura ^F[A-Z0-9]{3}$,
Boleta ^B[A-Z0-9]{3}$, Nota debe
empezar con el prefijo del documento que corrige (F
o B).
customer.address es opcional.
Cuando se envía, se mapea al bloque de dirección del cliente en el XML UBL;
omitido o vacío, el XML se genera sin ese bloque.
Pago a crédito: con payment.type = "contado"
no se envía nada más. Con payment.type = "credito",
payment.installments es obligatorio: de 1 a 36
cuotas, cada una con amount (string) y
due_date (YYYY-MM-DD).
La suma de installments[].amount debe cuadrar
con totals.total_amount.
{
"payment": {
"type": "credito",
"installments": [
{ "amount": "2950.000000", "due_date": "2026-09-15" },
{ "amount": "2950.000000", "due_date": "2026-10-15" }
]
}
}
Nota de Crédito/Débito agrega
reference_document
(document_type_code/series/number
del comprobante que corrige) y reason_code
(catálogo SUNAT 09 o 10).
Idempotencia: external_reference
(identificador propio del consumidor) + identidad tributaria
(document_type_code+series+number)
son las dos dimensiones. Un reintento exacto es un replay
(200, replay: true,
mismo resultado ya almacenado); una divergencia entre ambas es un conflicto
409. La primera emisión responde
201, replay: false.
Resultado: data.document.status
es accepted,
accepted_with_observations o
rejected — un rechazo de
SUNAT también responde 201,
es un desenlace válido, no un error HTTP.
data.artifacts expone XML sin firmar,
XML firmado, ZIP y CDR (available,
filename, sha256
de cada uno).
Consulta y descarga de comprobantes
Credencial de Empresa, acotado siempre a los comprobantes de esa Empresa.
| Método | Ruta | Para qué |
|---|---|---|
| GET | /api/v2/cpe | Catálogo paginado, con filtros |
| GET | /api/v2/cpe/{uuid} | Detalle (incluye flags available de cada artifact, sin los bytes) |
| GET | /api/v2/cpe/{uuid}/xml | XML UBL 2.1 firmado, bytes reales (Content-Type: application/xml) |
| GET | /api/v2/cpe/{uuid}/cdr | CDR oficial de SUNAT, bytes reales (Content-Type: application/zip) |
Un uuid inexistente o de otra Empresa
responde 404 genérico. Un comprobante
rechazado sin CDR (excepción de servicio SUNAT, sin XML de respuesta)
responde 404 en
/cdr con un mensaje distinto ("este
comprobante no tiene un CDR disponible").
Resumen Diario de Boletas
Vía alternativa para agrupar Boletas (no obligatoria:
POST /api/v2/cpe con
document_type_code: "03" ya emite una
Boleta individual de forma síncrona). Credencial de Empresa.
Asíncrono: SUNAT devuelve un ticket, y el estado final se consulta después.
| Método | Ruta | Para qué |
|---|---|---|
| POST | /api/v2/daily-summaries | Generar y transmitir el Resumen Diario de un conjunto de Boletas |
| GET | /api/v2/daily-summaries | Catálogo paginado |
| GET | /api/v2/daily-summaries/{uuid} | Detalle |
| POST | /api/v2/daily-summaries/{uuid}/status-check | Consultar el estado del ticket ya transmitido (getStatus); no reenvía, no hace polling automático |
El ticket puede quedar processing
varias consultas antes de resolver a un resultado final; el consumidor debe
volver a llamar a status-check
periódicamente (no hay webhooks).
Guía de Remisión Electrónica (GRE)
Emisión de una Guía de Remisión Remitente (09).
Usa el servicio REST nuevo de SUNAT (no el SOAP de
Factura/Boleta) y es asíncrona: una respuesta exitosa
entrega un ticket para procesamiento, no un resultado tributario final.
Alcance actual:
- Motivo de traslado libre (catálogo SUNAT 20).
- Transporte privado (vehículo y conductor propios de la Empresa) o público (transportista tercero), según
transport_mode_code(catálogo SUNAT 18). - Solo Guía Remitente (
09). Guía Transportista (31): no soportada todavía. - No existe host de pruebas separado documentado por SUNAT para este servicio REST: toda emisión es contra producción real, protegida por un interruptor de servidor que el operador de apis.admin activa explícitamente.
Requisitos previos
Dos contenedores de credenciales de la Empresa deben estar configurados
antes de poder emitir, o la respuesta es 409:
- Credenciales SOL (
PUT /api/v2/company/sunat-credentials) — las mismas de Factura/Boleta. - Credenciales GRE (
PUT /api/v2/company/gre-credentials) —client_id/client_secretque la Empresa genera en el menú SOL específicamente para el servicio API SUNAT, distintas del Usuario/Clave SOL.
Quién habla con SUNAT
El sistema que integra con apis.admin nunca llama a SUNAT
directamente ni maneja el client_id/client_secret
GRE en su propio código: eso es interno de apis.admin, que autentica contra
SUNAT por su cuenta usando las credenciales ya guardadas de la Empresa. El
sistema externo solo necesita su token Sanctum de siempre (credencial de
Empresa, ver sección Autenticación) para llamar a
POST /api/v2/dispatch-guides.
PUT /api/v2/company/gre-credentials
{ "client_id": "client-abc", "client_secret": "secret-123" }
Primer guardado: ambos campos obligatorios. Guardados posteriores:
client_secret opcional —si se omite,
se conserva el actual—.
{
"success": true,
"message": "Credenciales GRE guardadas correctamente.",
"data": { "connected": true, "is_configured": true, "configured_at": "2026-09-23T10:00:00+00:00" }
}
Nunca incluye client_id ni
client_secret en la respuesta.
POST /api/v2/dispatch-guides
{
"external_reference": "erp-guia-2026-000456",
"series": "T001",
"number": "123",
"issue_date": "2026-09-24",
"country_code": "PE",
"sunat_establishment_code": "0000",
"transfer_reason_code": "01",
"transfer_description": null,
"gross_weight": "150.500",
"weight_unit_code": "KGM",
"total_packages": 3,
"transfer_start_date": "2026-09-24",
"recipient": {
"document_type_code": "6",
"document_number": "20100047218",
"name": "BANCO DE CREDITO DEL PERU"
},
"departure": { "ubigeo": "150101", "address": "Av. Siempre Viva 123" },
"arrival": { "ubigeo": "150102", "address": "Jr. Destino 456" },
"transport_mode_code": "02",
"vehicle": { "plate": "ABC-123", "circulation_permit": null },
"drivers": [{
"type": "Principal",
"document_type_code": "1",
"document_number": "45678912",
"first_name": "Juan",
"last_name": "Perez Quispe",
"license": "Q12345678"
}],
"items": [{
"code": "PROD-001",
"description": "Producto de prueba",
"quantity": "10.000000",
"unit_code": "NIU",
"sunat_product_code": null
}]
}
Transporte privado o público —
transport_mode_code (catálogo SUNAT
18) es opcional; si se omite, se asume 02
(privado). En 02, vehicle
y drivers son obligatorios y
carrier se rechaza con
422 si se envía. En
01 (público) es al revés:
carrier obligatorio
(document_type_code,
document_number,
name — razón social del
transportista tercero —, mtc_registration_number
opcional) y vehicle/drivers
se rechazan si se envían.
{
"transport_mode_code": "01",
"carrier": {
"document_type_code": "6",
"document_number": "20600000001",
"name": "Transportes El Rápido SAC",
"mtc_registration_number": null
}
}
Campos clave:
| Campo | Notas |
|---|---|
| series | Prefijo T fijo, 4 caracteres (^T[A-Z0-9]{3}$) — convención oficial SUNAT para Guía Remitente |
| transfer_reason_code | Catálogo SUNAT 20 (motivo de traslado); libre en este alcance |
| drivers | Al menos un conductor; obligatorio solo con transporte privado (transport_mode_code = 02) |
| vehicle.plate | Siempre obligatorio |
No se envía company_code
(422 si se incluye) ni bloque
issuer: a diferencia de
/cpe, no hay ningún dato declarado
por el consumidor que deba coincidir con la Empresa —se resuelve
íntegramente desde la credencial—.
Respuesta exitosa (201,
o 200 en replay):
{
"success": true,
"message": "Guía de remisión enviada a SUNAT correctamente.",
"stored": true,
"retryable": false,
"replay": false,
"data": {
"dispatch_guide": {
"uuid": "290a3111-0d71-4c48-89a1-0f93367bcb47",
"external_reference": "erp-guia-2026-000456",
"company_code": "EMP-000123",
"document_type_code": "09",
"series": "T001",
"number": 123,
"status": "ticket_received",
"accepted": true
},
"provider": {
"name": "sunat",
"environment": "production",
"ticket": "1234567890",
"response_code": null,
"description": null
}
}
}
status es
ticket_received (SUNAT aceptó el
envío para su cola de proceso —no es la decisión tributaria
final—) o rejected (rechazo real de
validación, sin ticket; accepted: false).
Idempotencia
Mismo criterio que /cpe: un reintento
exacto (mismo external_reference,
misma identidad series+number,
mismo contenido) es un replay (200,
replay: true); una divergencia es un
conflicto 409
(external_reference_conflict o
document_identity_conflict).
A diferencia de /cpe, este endpoint
no usa un candado distribuido entre servidores: la protección contra
duplicados sigue siendo fuerte a nivel de base de datos, pero dos
solicitudes idénticas verdaderamente concurrentes podrían, en un caso
extremo, disparar dos llamadas a SUNAT antes de que la segunda falle al
guardar. Para un sistema que integra: evitar reintentos automáticos
concurrentes de la misma external_reference
mientras la primera respuesta aún no vuelve.
Errores de POST /api/v2/dispatch-guides
| Código | Caso | code |
|---|---|---|
| 401 | Sin token, o token cuyo registro ya no existe | — |
| 403 | Credencial de Cuenta en vez de Empresa | — |
| 409 | Credenciales GRE/SOL sin configurar, o conflicto de idempotencia | external_reference_conflict / document_identity_conflict |
| 422 | Validación de forma fallida (serie sin prefijo T, sin conductores, campo reservado enviado) | — |
| 429 | Límite de solicitudes excedido | — |
| 502 | SUNAT respondió pero no de forma confiable (autenticación OAuth2 rechazada) | gre_provider_invalid_response |
| 503 | SUNAT no responde, o el envío a producción está deshabilitado en el servidor | gre_provider_unavailable |
| 500 | SUNAT respondió pero el resultado no pudo guardarse (nunca se reintenta el envío) | gre_finalization_failed |
Ejemplo completo (curl)
# 1. Configurar credenciales GRE (una sola vez por Empresa)
curl -X PUT https://api.apisperu.pro/api/v2/company/gre-credentials \
-H "Authorization: Bearer $TOKEN_EMPRESA" \
-H "Content-Type: application/json" \
-d '{"client_id": "client-abc", "client_secret": "secret-123"}'
# 2. Emitir la guia
curl -X POST https://api.apisperu.pro/api/v2/dispatch-guides \
-H "Authorization: Bearer $TOKEN_EMPRESA" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"external_reference": "erp-guia-2026-000456",
"series": "T001",
"number": "123",
"issue_date": "2026-09-24",
"country_code": "PE",
"sunat_establishment_code": "0000",
"transfer_reason_code": "01",
"gross_weight": "150.500",
"weight_unit_code": "KGM",
"total_packages": 3,
"transfer_start_date": "2026-09-24",
"recipient": {"document_type_code": "6", "document_number": "20100047218", "name": "BANCO DE CREDITO DEL PERU"},
"departure": {"ubigeo": "150101", "address": "Av. Siempre Viva 123"},
"arrival": {"ubigeo": "150102", "address": "Jr. Destino 456"},
"vehicle": {"plate": "ABC-123"},
"drivers": [{"type": "Principal", "document_type_code": "1", "document_number": "45678912", "first_name": "Juan", "last_name": "Perez Quispe", "license": "Q12345678"}],
"items": [{"code": "PROD-001", "description": "Producto de prueba", "quantity": "10.000000", "unit_code": "NIU"}]
}'
Consulta de estado del ticket
POST /api/v2/dispatch-guides/{uuid}/status-check.
Credencial de Empresa. Solo aplica a una guía en
ticket_received; en cualquier otro
estado responde 409 gre_status_check_not_available.
El sistema llama a consultarEnvio(ticket)
de SUNAT y traduce el cod_respuesta
recibido:
| cod_respuesta | Efecto | HTTP |
|---|---|---|
| 98 (procesando) | No cambia status; incrementa status_check_count y actualiza last_status_checked_at | 202 |
| 0 (aceptado) | status pasa a accepted (resultado final) | 200 |
| 99 (rechazado) | status pasa a ticket_rejected (resultado final, distinto del rejected de validación al emitir) | 200 |
Una guía ya en estado final (accepted
o ticket_rejected) nunca vuelve a
llamar a SUNAT: la respuesta es un replay
con el resultado ya almacenado.
Si SUNAT adjunta el CDR (arc_cdr,
base64) junto con un resultado final, se decodifica y persiste; queda
disponible en GET .../cdr (ver abajo).
ind_cdr_generado puede venir en
true sin que SUNAT adjunte
arc_cdr en esa respuesta puntual; en
ese caso no queda nada que descargar todavía.
Como con el resto de la API, el cliente es responsable de invocar este endpoint cuando lo necesite — no hay webhook ni reintento automático del lado del servidor.
Descarga de XML y CDR
GET /api/v2/dispatch-guides/{uuid}/xml —
XML UBL 2.1 tal como se transmitió a SUNAT (bytes reales,
Content-Type: application/xml). Siempre
disponible tras la emisión, en ambos desenlaces deterministas
(ticket_received y
rejected): SUNAT ya lo recibió de
todas formas.
GET /api/v2/dispatch-guides/{uuid}/cdr —
CDR tal como lo devolvió SUNAT (bytes reales,
Content-Type: application/zip). Es el
único artifact opcional: responde 404
con gre_cdr_not_available hasta que una
consulta de estado lo adjunte. Ambas rutas comparten el mismo ownership que
el resto: un uuid inexistente o de
otra Empresa responde 404 genérico.
curl https://api.apisperu.pro/api/v2/dispatch-guides/{uuid}/xml \
-H "Authorization: Bearer $TOKEN_EMPRESA" \
-o guia.xml
curl https://api.apisperu.pro/api/v2/dispatch-guides/{uuid}/cdr \
-H "Authorization: Bearer $TOKEN_EMPRESA" \
-o cdr.zip
Catálogo y detalle propio
GET /api/v2/dispatch-guides — catálogo
paginado, propiedad de la Empresa de la credencial (nunca de todas las
Empresas de la Cuenta, a diferencia de GET /api/v2/cpe).
Filtros: status
(ticket_received/rejected/accepted/ticket_rejected),
search (UUID, serie-número
o external_reference exactos),
issued_from/issued_to,
received_from/received_to
(rango máx. 366 días), sort/direction,
page/per_page
(máx. 100).
GET /api/v2/dispatch-guides/{uuid} —
detalle de una única Guía. En ambos, artifacts.xml
es siempre true; artifacts.cdr
en el detalle confirma la existencia física del archivo (un solo golpe a
disco), mientras que en el listado se deriva de una columna, sin tocar disco
por fila.
curl "https://api.apisperu.pro/api/v2/dispatch-guides?status=ticket_received&per_page=10" \
-H "Authorization: Bearer $TOKEN_EMPRESA"
curl https://api.apisperu.pro/api/v2/dispatch-guides/{uuid} \
-H "Authorization: Bearer $TOKEN_EMPRESA"
Fuera de alcance (hoy)
| Área | Qué falta |
|---|---|
| Guía de Remisión | Guía Transportista (31) |
| General | Webhooks (todo es sincrónico o por consulta explícita de estado, nunca hay push del servidor) |
| General | Retry automático del lado del servidor (un fallo de proveedor/timeout nunca se reintenta solo; el consumidor decide) |
Cualquiera de estas áreas puede ampliarse; este documento se actualiza cuando eso ocurra.