Cómo Probar APIs Localhost con Servicios Webhook

Ashley Innocent

Ashley Innocent

28 January 2026

Cómo Probar APIs Localhost con Servicios Webhook

Probar APIs locales (localhost) que necesitan recibir webhooks o callbacks de servicios externos requiere exponer temporalmente tu servidor de desarrollo local a internet. Servicios de tunelización como ngrok, NPort, Cloudflare Tunnel y otros, crean conexiones seguras que le dan a tu localhost una URL pública.

💡
Descarga Apidog para seguir los flujos de trabajo de prueba de webhooks de esta guía. Esta guía cubre cómo elegir la herramienta adecuada, configurar la tunelización, probar webhooks de manera efectiva usando Apidog y manejar desafíos comunes como la autenticación, los límites de velocidad y la depuración.
botón

Por qué necesitas la tunelización de localhost

Estás construyendo una API que se integra con servicios de terceros. Todo funciona en tu laptop: los endpoints responden correctamente, los datos fluyen sin problemas. Luego intentas probar los callbacks de webhooks de Stripe, GitHub, Twilio o cualquier otro servicio externo.

Problema: Los servicios externos no pueden alcanzar localhost:3000. Tu servidor de desarrollo no es accesible desde internet.

Escenarios comunes donde esto interrumpe tu flujo de trabajo:

1. Pruebas de Webhooks

Servicios como Stripe envían confirmaciones de pago, GitHub envía eventos de repositorio, Slack envía eventos de interacción, todo como solicitudes POST a tu API. Durante el desarrollo, estos servicios necesitan una URL pública para enviar webhooks.

Diagrama de flujo de webhook

2. URLs de Callback de OAuth

Al implementar "Iniciar sesión con Google", "Iniciar sesión con GitHub" o cualquier flujo de OAuth, el proveedor de autenticación redirige a los usuarios de vuelta a tu aplicación con un código de autorización. La URL de redirección debe ser accesible públicamente y coincidir con la que registraste con el proveedor.

Diagrama de flujo de OAuth

3. Integración de API de Terceros

Algunas APIs requieren URLs de callback para operaciones asíncronas. Por ejemplo, los servicios de transcodificación de video notifican a tu API cuando el procesamiento se completa, o los procesadores de pago confirman transacciones.

4. Desarrollo de Aplicaciones Móviles

Probar tu API desde un dispositivo móvil en la misma red a menudo falla porque la aplicación móvil no puede resolver localhost. Un túnel te proporciona una URL que funciona desde cualquier dispositivo.

5. Demostraciones a Clientes

A veces necesitas mostrar trabajo en progreso a clientes o interesados. Desplegar a staging por cada pequeño cambio ralentiza la iteración. Una URL pública temporal permite a los clientes probar tu entorno de desarrollo.

Cómo funciona la tunelización de localhost

Los servicios de tunelización crean una conexión segura entre sus servidores en la nube y tu máquina local:

Servicio Externo → Servicio de Tunelización (URL pública) → Conexión Segura → Tu Localhost:3000

El proceso:

  1. Inicias un cliente de túnel en tu máquina apuntando a tu puerto local
  2. El cliente se conecta a la infraestructura en la nube del servicio de tunelización
  3. El servicio asigna una URL pública (por ejemplo, https://abc123.ngrok.io)
  4. Las solicitudes entrantes a esa URL pública se reenvían a través de la conexión cifrada a tu localhost
  5. Tu servidor local recibe la solicitud como si viniera directamente del cliente
  6. Las respuestas fluyen de vuelta a través del túnel al solicitante

Esto sucede de forma transparente. Tu servidor local no necesita saber que está detrás de un túnel.

Comparando Servicios de Tunelización Populares

Aquí están las opciones más populares en 2026, con sus fortalezas y limitaciones:

Ideal para: Proyectos establecidos, equipos que buscan fiabilidad

ngrok http 3000
Ejemplo de salida de la consola de ngrok

Ventajas:

Desventajas:

Capa Gratuita:

Planes de Pago: $8-$20/mes

Panel de control de ngrok

NPort (Alternativa Gratuita en Ascenso)

Ideal para: Desarrolladores que evitan costos de suscripción

Ejemplo de salida de la consola de NPort
nport start 3000

Ventajas:

Desventajas:

Capa Gratuita:

Esta es la herramienta que está ganando tracción en Dev.to, ya que los desarrolladores buscan alternativas a ngrok sin costos continuos.

Cloudflare Tunnel (Ideal para Entornos Cercanos a Producción)

Ideal para: Equipos que ya usan Cloudflare, túneles de larga duración

Interfaz de Cloudflare Tunnel
cloudflared tunnel --url http://localhost:3000

Ventajas:

Desventajas:

Capa Gratuita:

Localtunnel (El más Simple)

Ideal para: Pruebas rápidas y puntuales, sin instalación

npx localtunnel --port 3000

Ventajas:

Desventajas:

Capa Gratuita:

Tailscale Funnel (Ideal para Equipos)

Ideal para: Compartir en equipo de forma privada, demostraciones seguras

Tailscale Funnel
tailscale serve https / http://localhost:3000
tailscale funnel 443 on

Ventajas:

Desventajas:

Capa Gratuita:

Tabla Comparativa

CaracterísticangrokNPortCloudflare TunnelLocaltunnelTailscale
PrecioGratis/$10+GratisGratisGratisGratis/Pago
Límite de Sesión2 horasNingunoNingunoNingunoNinguno
Dominio PersonalizadoPagoGratisNo
Inspector de SolicitudesBásicoNoNoNo
Complejidad de ConfiguraciónBajaBajaMediaMuy BajaMedia
FiabilidadExcelenteBuenaExcelentePobreExcelente
Ideal ParaPruebas de producciónDesarrolladores conscientes del costoEmpresarialPruebas rápidasCompartir en equipo

Configurando Tu Primer Túnel Localhost

Recorramos la configuración con las herramientas más comunes. Usaremos una API Express de Node.js como ejemplo, pero esto funciona con cualquier servidor local.

Ejemplo: Servidor API Local

// server.js
const express = require('express');
const app = express();

app.use(express.json());

app.post('/webhook', (req, res) => {
  console.log('Webhook received:', req.body);
  res.json({ received: true });
});

app.get('/health', (req, res) => {
  res.json({ status: 'healthy' });
});

app.listen(3000, () => {
  console.log('Server running on http://localhost:3000');
});

Opción 1: Usando ngrok

Paso 1: Instalar ngrok

# macOS
brew install ngrok

# Windows (via Chocolatey)
choco install ngrok

# Linux
curl -s https://ngrok-agent.s3.amazonaws.com/ngrok.asc | \
  sudo tee /etc/apt/trusted.gpg.d/ngrok.asc >/dev/null && \
  echo "deb https://ngrok-agent.s3.amazonaws.com buster main" | \
  sudo tee /etc/apt/sources.list.d/ngrok.list && \
  sudo apt update && sudo apt install ngrok

Paso 2: Autenticar (opcional pero recomendado)

ngrok config add-authtoken YOUR_AUTH_TOKEN

Paso 3: Iniciar el túnel

ngrok http 3000

Salida:

Session Status                online
Account                       you@example.com (Plan: Free)
Version                       3.5.0
Region                        United States (us)
Forwarding                    https://abc123.ngrok.io -> http://localhost:3000

Tu API ahora es accesible en https://abc123.ngrok.io.

Paso 4: Probarlo

curl https://abc123.ngrok.io/health
# {"status":"healthy"}

Opción 2: Usando NPort (Alternativa Gratuita)

Paso 1: Instalar NPort

npm install -g nport-cli
# or
curl -sSL https://nport.io/install.sh | bash

Paso 2: Iniciar el túnel

nport start 3000 --subdomain myapi

Salida:

✓ Tunnel started successfully
Public URL: https://myapi.nport.io
Local URL:  http://localhost:3000

Paso 3: Probarlo

curl https://myapi.nport.io/health
# {"status":"healthy"}

Opción 3: Usando Cloudflare Tunnel

Paso 1: Instalar cloudflared

# macOS
brew install cloudflare/cloudflare/cloudflared

# Linux
wget -q https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared-linux-amd64.deb

Paso 2: Túnel rápido (no se requiere registro)

cloudflared tunnel --url http://localhost:3000

Salida:

2026-01-27T12:00:00Z INF Your quick tunnel is: https://xyz789.trycloudflare.com

Para túneles persistentes (requiere cuenta de Cloudflare):

# Login
cloudflared tunnel login

# Create tunnel
cloudflared tunnel create myapi

# Configure and run
cloudflared tunnel --config config.yml run myapi

Probando Webhooks con Apidog

Ahora que tu localhost es accesible públicamente, probemos los webhooks sistemáticamente usando Apidog.

¿Por qué combinar Tunelización + Apidog?

La tunelización resuelve el acceso; Apidog resuelve la verificación:

Configurando Pruebas de Webhooks en Apidog

Paso 1: Importar o Crear Tu API

  1. Abre Apidog
Interfaz de usuario de Apidog

2. Crea un nuevo proyecto

Nuevo proyecto en Apidog

3. Añade tu endpoint de webhook:

Configuración del endpoint de webhook en Apidog

Paso 2: Configurar Variables de Entorno

Configura dos entornos:

Desarrollo (Tunelizado):

{
  "base_url": "https://abc123.ngrok.io"
}

Producción:

{
  "base_url": "https://api.yourapp.com"
}

Esto te permite probar el mismo endpoint localmente y en producción con un solo clic.

Paso 3: Crear Escenarios de Prueba

Prueba qué sucede cuando llegan los webhooks:

Ejemplo: Prueba de Webhook de Pago de Stripe

// Request Body
{
  "type": "payment_intent.succeeded",
  "data": {
    "object": {
      "id": "pi_test123",
      "amount": 2000,
      "currency": "usd",
      "status": "succeeded"
    }
  }
}

Aserciones en Apidog:

  1. El código de estado es igual a 200
  2. La respuesta contiene received: true
  3. El tiempo de respuesta es < 1000ms
  4. El Content-Type es application/json

Paso 4: Simular Servicios de Terceros

En lugar de activar webhooks reales de Stripe o GitHub, simúlalos en Apidog:

  1. Copia ejemplos de payloads de webhook de la documentación del servicio
  2. Crea casos de prueba con varios escenarios (éxito, fallo, casos límite)
  3. Ejecuta todos los escenarios contra tu localhost tunelizado
  4. Verifica que tu API maneje cada caso correctamente

Probando Callbacks de OAuth

Escenario: Estás implementando "Iniciar sesión con Google"

Paso 1: Inicia el túnel con un subdominio personalizado

ngrok http 3000 --subdomain myapp
# URL: https://myapp.ngrok.io

Paso 2: Configura la redirección de OAuth en Google Console

Establece la URL de callback: https://myapp.ngrok.io/auth/google/callback

Paso 3: Prueba el flujo en Apidog

  1. Haz una solicitud a /auth/google para obtener la URL de autorización
  2. Sigue la redirección manual o programáticamente
  3. Verifica que el callback reciba el código de autorización
  4. Asegúrate de que el intercambio de tokens funcione correctamente

Paso 4: Validar el almacenamiento de tokens

Usa Apidog para:

Casos de Uso Comunes

1. Probando Webhooks de Pago (Stripe, PayPal)

Desafío: Los proveedores de pago envían webhooks para eventos como cargos exitosos, reembolsos, disputas.

Solución:

# Start tunnel
ngrok http 3000

# Configure webhook URL in Stripe dashboard
# https://abc123.ngrok.io/webhook/stripe

# Use Stripe CLI to forward test webhooks
stripe listen --forward-to localhost:3000/webhook/stripe

# Trigger test events
stripe trigger payment_intent.succeeded

Prueba con Apidog:

2. Probando Comandos de Bot de Slack/Discord

Desafío: Las plataformas de chat envían eventos de interacción cuando los usuarios hacen clic en botones o ejecutan comandos.

Solución:

# Start tunnel
nport start 3000 --subdomain myslackbot

# Configure in Slack API:
# Interactivity URL: https://myslackbot.nport.io/slack/interactions
# Slash Commands: https://myslackbot.nport.io/slack/commands

Prueba con Apidog:

3. Probando Webhooks de SMS/Voz (Twilio)

Desafío: Twilio envía webhooks cuando llegan SMS o se reciben llamadas de voz.

Solución:

cloudflared tunnel --url http://localhost:3000

Configura los webhooks de TwiML para que apunten a la URL de tu túnel.

Prueba con Apidog:

4. Pruebas de API de Aplicaciones Móviles

Desafío: Probar tu API desde un dispositivo físico o emulador.

Problema con localhost:

// Esto falla desde un dispositivo móvil
fetch('http://localhost:3000/api/users')

Solución con túnel:

// Esto funciona desde cualquier lugar
fetch('https://myapi.ngrok.io/api/users')

Prueba con Apidog:

  1. Genera documentación de API con la URL base tunelizada
  2. Comparte con el equipo móvil
  3. Los desarrolladores móviles pueden probar contra tu servidor de desarrollo en vivo
  4. Cambia a URLs de staging/producción cuando esté listo

5. Probando Webhooks de GitHub/GitLab

Desafío: Probar webhooks de repositorio (push, pull request, issues) localmente.

Solución:

# Start tunnel
ngrok http 4000

# Configure in GitHub repo settings:
# Webhook URL: https://abc123.ngrok.io/github/webhook
# Content type: application/json
# Events: Push, Pull requests

Prueba con Apidog:

Mejores Prácticas de Seguridad

Exponer localhost a internet crea riesgos de seguridad. Sigue estas prácticas:

1. Usa Solo HTTPS

Todos los servicios de tunelización proporcionan HTTPS por defecto. Nunca uses HTTP simple para túneles:

# Good
ngrok http 3000
# Creates https://abc123.ngrok.io

# Bad (don't do this)
ngrok http --scheme=http 3000

2. Implementa la Verificación de Firma de Webhook

No confíes ciegamente en los webhooks entrantes. Verifica las firmas:

const crypto = require('crypto');

function verifyStripeSignature(payload, signature, secret) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}

app.post('/webhook/stripe', (req, res) => {
  const signature = req.headers['stripe-signature'];

  if (!verifyStripeSignature(req.body, signature, process.env.STRIPE_SECRET)) {
    return res.status(401).send('Invalid signature');
  }

  // Process webhook
});

3. Restringe el Acceso con Autenticación Básica

Añade autenticación a tu túnel:

# ngrok with basic auth
ngrok http 3000 --auth="username:password"

# NPort with basic auth
nport start 3000 --auth username:password

Ahora las solicitudes necesitan credenciales:

curl -u username:password https://abc123.ngrok.io/webhook

4. Usa Secretos Específicos del Entorno

Nunca hagas commit de secretos de webhook o claves API:

// .env.development
STRIPE_WEBHOOK_SECRET=whsec_test_abc123
WEBHOOK_TUNNEL_URL=https://abc123.ngrok.io

// .env.production
STRIPE_WEBHOOK_SECRET=whsec_live_xyz789
WEBHOOK_URL=https://api.yourapp.com

5. Monitoriza el Acceso al Túnel

Usa el inspector de solicitudes para vigilar actividades sospechosas:

# ngrok provides a web interface at:
http://localhost:4040

# View all requests, responses, replay attacks

6. Limita la Duración del Túnel

No dejes los túneles ejecutándose indefinidamente:

# Auto-expire tunnel after 1 hour
ngrok http 3000 --session-duration 1h

7. Valida las Fuentes de Solicitudes

Verifica las direcciones IP entrantes o usa listas blancas:

const allowedIPs = [
  '192.0.2.1',  // Stripe webhook IPs
  '198.51.100.0/24'
];

app.use('/webhook', (req, res, next) => {
  const clientIP = req.ip;

  if (!allowedIPs.includes(clientIP)) {
    return res.status(403).send('Forbidden');
  }

  next();
});

Resolución de Problemas Comunes

Problema 1: La URL del Túnel Cambia en Cada Sesión

Problema: Los túneles gratuitos de ngrok usan URLs aleatorias que cambian con cada reinicio. Los webhooks configurados con la URL antigua dejan de funcionar.

Soluciones:

  1. Usa un plan de pago para URLs estáticas:
ngrok http 3000 --domain=myapp.ngrok.app
  1. Cambia a NPort con subdominios personalizados gratuitos:
nport start 3000 --subdomain myapp
# Always https://myapp.nport.io
  1. Actualiza los webhooks programáticamente a través de API cuando el túnel se inicie

Problema 2: Los Webhooks Exceden el Tiempo de Espera

Problema: Tu servidor local tarda demasiado en responder. Servicios como Slack requieren respuestas en 3 segundos.

Solución:

Procesa asincrónicamente:

app.post('/webhook', async (req, res) => {
  // Acknowledge immediately
  res.json({ received: true });

  // Process in background
  processWebhookAsync(req.body).catch(console.error);
});

async function processWebhookAsync(data) {
  // Do slow work here (database, external APIs, etc.)
  await heavyProcessing(data);
}

Prueba los tiempos de espera con Apidog configurando límites de tiempo de espera agresivos en los escenarios de prueba.

Problema 3: Errores CORS desde el Navegador

Problema: El frontend que hace solicitudes a la URL del túnel obtiene errores CORS.

Solución:

Configura los encabezados CORS:

const cors = require('cors');

app.use(cors({
  origin: [
    'http://localhost:3001',  // Your frontend dev server
    'https://abc123.ngrok.io'  // Your tunnel URL
  ],
  credentials: true
}));

Problema 4: Límite de Velocidad en la Capa Gratuita

Problema: Los túneles gratuitos tienen límites de conexión (ngrok: 40/min).

Soluciones:

  1. Agrupa las solicitudes de prueba en Apidog en lugar de realizar pruebas individuales rápidas
  2. Usa múltiples túneles para diferentes servicios
  3. Actualiza a un plan de pago si realizas muchas pruebas
  4. Cambia a un servicio ilimitado como Cloudflare Tunnel o NPort

Problema 5: El Túnel se Desconecta Frecuentemente

Problema: La inestabilidad de la red causa caídas del túnel.

Solución:

Usa systemd/pm2 para reiniciar automáticamente:

# Create systemd service
sudo nano /etc/systemd/system/ngrok.service
[Unit]
Description=ngrok tunnel
After=network.target

[Service]
Type=simple
User=youruser
WorkingDirectory=/home/youruser
ExecStart=/usr/local/bin/ngrok http 3000
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
sudo systemctl enable ngrok
sudo systemctl start ngrok

Problema 6: No se Puede Alcanzar el Túnel desde una Red Específica

Problema: Los firewalls corporativos o redes restrictivas bloquean el tráfico del túnel.

Soluciones:

  1. Usa Cloudflare Tunnel (raramente bloqueado)
  2. Cambia la región del túnel a una más cercana a ti:
ngrok http 3000 --region eu
  1. Usa Tailscale para una red privada en lugar de un túnel público

Patrones Avanzados

Patrón 1: Tunelización Multi-Puerto

Expón múltiples servicios simultáneamente:

# Terminal 1: API server
ngrok http 3000

# Terminal 2: Frontend dev server
ngrok http 3001

# Terminal 3: Webhook worker
ngrok http 3002

O usa el archivo de configuración de ngrok:

# ~/.ngrok2/ngrok.yml
tunnels:
  api:
    proto: http
    addr: 3000
  frontend:
    proto: http
    addr: 3001
  worker:
    proto: http
    addr: 3002
ngrok start --all

Patrón 2: Túnel + Docker Compose

# docker-compose.yml
version: '3'
services:
  api:
    build: .
    ports:
      - "3000:3000"

  ngrok:
    image: ngrok/ngrok:latest
    command:
      - "http"
      - "api:3000"
    environment:
      NGROK_AUTHTOKEN: ${NGROK_AUTHTOKEN}
docker-compose up

Patrón 3: Inyección Dinámica de URL del Túnel

Actualiza automáticamente tu aplicación con la URL del túnel:

// start-tunnel.js
const ngrok = require('ngrok');
const fs = require('fs');

(async function() {
  const url = await ngrok.connect(3000);
  console.log(`Tunnel started: ${url}`);

  // Update .env file
  fs.appendFileSync('.env', `\nTUNNEL_URL=${url}\n`);

  // Update Stripe webhook
  await updateStripeWebhook(url);
})();

Patrón 4: Reenvío de Solicitudes a Múltiples Entornos

Prueba el mismo webhook contra desarrollo, staging y producción:

// webhook-multiplexer.js
app.post('/webhook', async (req, res) => {
  const environments = [
    'http://localhost:3000',
    'https://staging.api.com',
    'https://api.yourapp.com'
  ];

  // Forward to all environments
  const results = await Promise.all(
    environments.map(env =>
      fetch(`${env}/webhook`, {
        method: 'POST',
        headers: req.headers,
        body: JSON.stringify(req.body)
      })
    )
  );

  res.json({ forwarded: results.length });
});

Conclusión

Probar APIs locales que reciben webhooks o callbacks no requiere desplegar a staging por cada cambio. Los servicios de tunelización crean URLs públicas temporales que permiten a los servicios externos alcanzar tu entorno de desarrollo.

Comienza con la capa gratuita de cualquier herramienta. Si las pruebas de webhooks se convierten en una parte diaria de tu flujo de trabajo, considera los planes de pago para URLs estáticas y características adicionales. Pero para la mayoría de los desarrolladores, los servicios de tunelización gratuitos combinados con las capacidades de prueba de API de Apidog proporcionan todo lo necesario para probar APIs locales de manera efectiva.

botón

Practica el diseño de API en Apidog

Descubre una forma más fácil de construir y usar APIs