Exposing Agents
Exposing Your Agent to the Internet
Use ngrok to create a public URL for your local agent so SignalWire can send webhook requests to it.
Why You Need a Public URL
SignalWire’s cloud needs to reach your agent via HTTP:


Installing ngrok
macOS (Homebrew)
Linux
Windows
Direct Download
Visit ngrok.com/download and download for your platform.
Create an ngrok Account (Free)
- Go to ngrok.com and sign up
- Get your auth token from the dashboard
- Configure ngrok with your token:
This enables:
- Longer session times
- Custom subdomains (paid)
- Multiple tunnels
Basic Usage
Start your agent in one terminal:
Start ngrok in another terminal:
You’ll see output like:
Your public URL is: https://abc123def456.ngrok-free.app
Test the Tunnel
Both should return the same SWML document.
ngrok Web Interface
ngrok provides a web interface at http://127.0.0.1:4040 showing:
- All requests coming through the tunnel
- Request/response headers and bodies
- Timing information
- Ability to replay requests
This is invaluable for debugging SignalWire webhook calls!
Static Domains (Recommended)
Free ngrok gives you random URLs that change each restart. For easier development, use a static domain:
Free Static Domain (ngrok account required)
- Go to ngrok Dashboard → Domains
- Create a free static domain (e.g.,
your-name.ngrok-free.app) - Use it:
Now your URL stays the same across restarts!
Understanding Basic Authentication
Important: The SDK automatically secures your agent with HTTP Basic Authentication. Every time you start your agent, you’ll see:
The password changes on every restart unless you set environment variables.
Setting Persistent Credentials
For development, set these environment variables to use the same credentials across restarts:
Then start your agent:
Now it will show:
Why this matters:
- SignalWire needs these credentials to call your agent
- Random passwords mean reconfiguring SignalWire on every restart
- Set environment variables once for consistent development
Configure Your Agent for ngrok
Set the SWML_PROXY_URL_BASE environment variable so your agent generates correct webhook URLs:
Or set them when running:
This ensures:
- SWAIG function webhook URLs point to your public ngrok URL, not localhost
- Authentication credentials remain consistent across restarts
Complete Development Setup
Here’s the full workflow:
Using a Script
Create start-dev.sh:
Make it executable:
Alternative Tunneling Solutions
Cloudflare Tunnel (Free)
localtunnel (Free, no signup)
tailscale Funnel (Requires Tailscale)
Production Alternatives
For production, don’t use ngrok. Instead:
See the Deployment chapter for production deployment guides.
Troubleshooting
ngrok shows “ERR_NGROK_108”
Your auth token is invalid or expired. Get a new one from the ngrok dashboard:
Connection refused
Your agent isn’t running or is on a different port:
Webhook URLs still show localhost
Set SWML_PROXY_URL_BASE:
ngrok tunnel expires
Free ngrok tunnels expire after a few hours. Solutions:
- Restart ngrok
- Use a static domain (stays same after restart)
- Upgrade to paid ngrok plan
- Use an alternative like Cloudflare Tunnel
What’s Next?
Your agent is now accessible at a public URL. You’re ready to connect it to SignalWire!
You’ve Completed Phase 1!
- Installed the SDK
- Created your first agent
- Set up development environment
- Exposed agent via ngrok
Your agent is ready at: https://your-domain.ngrok-free.app
Next Chapter: Core Concepts - Deep dive into SWML, SWAIG, and agent architecture
Or jump to: SignalWire Integration - Connect your agent to phone numbers