Plivo can restrict API access to whitelisted IPs, rejecting everything else with 403 Forbidden. Send voice, SMS, and AI agent traffic through two fixed static EU IPs with one HTTPS_PROXY variable.
# on the machine that calls Plivo
export HTTPS_PROXY=https://user:pass@eu-01.outboundgateway.com:8443
export NO_PROXY=localhost,127.0.0.1
import requests
# requests and httpx read HTTPS_PROXY
r = requests.post(
f"https://api.plivo.com/v1/Account/{auth_id}/Message/",
auth=("AUTH_ID", "AUTH_TOKEN"))
IP whitelisting on Plivo is all-or-nothing per address: requests from IPs that do not match a whitelisted CIDR are rejected outright. Great for security, brutal for anything that moves.
Whitelisting activates the moment you add the first CIDR entry, and any API request from a non-whitelisted IP gets 403 Forbidden. Redeploy your app onto a new address and every send-message and voice call starts failing immediately, with nothing in your code having changed.
Serverless functions, auto-scaled containers, CI runners, laptop-based demos: each one exits from an address you did not choose and cannot predict. Plivo matches the requesting IP against your CIDR list with plain allow rules, so a moving target simply never matches.
Plivo allows up to 50 CIDR entries per account, with validation that rejects overlaps and duplicates. Whitelisting a handful of addresses per environment, per region, per deploy quickly turns the list into a bottleneck you have to curate by hand.
Subaccounts inherit the parent account's whitelist rules and cannot manage their own CIDRs. One workload on a rotating address does not just break itself; it breaks every subaccount riding on the same rules.
Your Apps
voice, SMS, AI agents
HTTPS Proxy
(Static EU IP)
Plivo API
with IP allowlist
Add both proxy addresses as /32 CIDR entries once. Every app, script, and serverless function behind the proxy then presents one of those two addresses to Plivo, whatever platform it runs on.
Teams building on Plivo that want the security of IP whitelisting without the fragility.
SMS and WhatsApp sends are customer-facing. The moment your sending host changes address, delivery drops with 403s. Pin the egress once and forget about it.
Agents that place and manage calls through Plivo run in containers that scale with conversation load. Every replica inherits the same two whitelisted addresses through one variable.
You turned IP whitelisting on because auditors or customers asked for it. Keep it on, and let the proxy guarantee your requests actually originate from where the whitelist says.
Each client project on its own host used to mean its own CIDR entry. Collapse them all behind one address pair and the 50-entry cap stops being a planning constraint.
Two steps in the Plivo console, one variable in your environment. Redeploy freely afterwards.
In the Plivo console, open Account Settings > IP Whitelisting and click + Add CIDR Address. Enter both of your OutboundGateway addresses in CIDR format, comma-separated, and click Add. Whitelisting takes effect with the first entry, so add both in the same action.
# Plivo console: Account Settings > IP Whitelisting
# + Add CIDR Address (comma-separated)
203.0.113.10/32, 203.0.113.11/32
# single IPs must use CIDR notation:
# /32 for IPv4, /128 for IPv6
Add the export to your shell profile so every session and process manager picks it up, then source it or reconnect. Keep the credentials out of committed files.
# ~/.bashrc or ~/.zshrc on the machine
export HTTPS_PROXY=https://user:pass@eu-01.outboundgateway.com:8443
export NO_PROXY=localhost,127.0.0.1
# apply without reconnecting
source ~/.bashrc
requests and httpx read HTTPS_PROXY from the environment automatically. No code changes beyond reading credentials from the environment.
import os
import requests
# picked up from HTTPS_PROXY in the environment
auth_id = os.environ["PLIVO_AUTH_ID"]
r = requests.post(
f"https://api.plivo.com/v1/Account/{auth_id}/Message/",
auth=(auth_id, os.environ["PLIVO_AUTH_TOKEN"]),
json={"src": "+15551234567",
"dst": "+15557654321",
"text": "Shipped!"},
)
Node's fetch does not follow proxy environment variables on its own. Wire it explicitly with https-proxy-agent.
const { HttpsProxyAgent } = require('https-proxy-agent');
const agent = new HttpsProxyAgent(process.env.HTTPS_PROXY);
const res = await fetch(`https://api.plivo.com/v1/Account/${process.env.PLIVO_AUTH_ID}/Message/`, {
method: 'POST',
headers: { 'Authorization': 'Basic ' + Buffer.from(
process.env.PLIVO_AUTH_ID + ':' + process.env.PLIVO_AUTH_TOKEN
).toString('base64') },
agent,
});
Whitelist both IPs, in Plivo and everywhere else
Your account includes two fixed IP addresses. Add both to the Plivo whitelist and to every other allowlist you maintain, each as a /32 entry. Traffic balances across the pair, and if one proxy node drops out the other keeps your sends and calls going out.
📖 Complete Documentation: For detailed examples, error handling, and other Python libraries, see the Python SSL Proxy Guide, Node.js Guide, and all other language guides.
Message bodies and call metadata carry personal data: phone numbers, names, conversation content. OutboundGateway keeps that outbound leg inside EU infrastructure, so the path from your European stack to Plivo's API stays consistent with the data-processing story you tell customers and auditors.
Traffic to Plivo leaves from EU addresses through EU infrastructure, which simplifies the data-processing story around message content and phone numbers.
Your servers, your data, and the egress leg all stay on European infrastructure. No detour through overseas compute just to send a message.
Two stable addresses make your Plivo traffic auditable: the whitelist says where requests come from, and they actually do.
Apps, scripts, and serverless functions all present the same pair, with automatic failover between them.
Move hosts, rebuild containers, scale functions. The whitelisted addresses belong to your account, not to any machine.
Two clean /32 entries that never rotate, out of Plivo's 50 per account, with room for everything else you need to whitelist.
Python, Node, and any runtime that honours HTTPS_PROXY. One pair covers sends, calls, and webhooks-out alike.
TLS passthrough means the proxy never sees plaintext. Auth tokens, numbers, and message bodies remain private.
Starting from €19/month. Flexible plans for every scale. Cancel anytime.
Keep IP whitelisting on and stop fearing the 403. One environment variable, and every voice call, SMS, and AI agent request egresses through the same two fixed EU IPs.
€19/month starter plan • 7-day refund policy • Direct founder support
Yes. Under API Access Control (IP Whitelisting) in the Plivo console, you add CIDR entries at Account Settings > IP Whitelisting. Requests from non-whitelisted IPs are rejected with 403 Forbidden, up to 50 CIDR entries are allowed per account, and subaccounts inherit the parent's rules. It takes effect as soon as the first entry is added, which is exactly why your egress needs to be stable before you turn it on.
No. Plivo requires CIDR format, so a single IPv4 address is entered as 203.0.113.10/32 (and IPv6 as /128). Both OutboundGateway addresses are plain single addresses, so each becomes one clean /32 entry in the console, comma-separated in the Add CIDR modal.
For Python apps using requests or httpx, no: they read HTTPS_PROXY from the environment automatically, so exporting the variable on the machine or in the container is enough. Node's built-in fetch ignores proxy environment variables, so Node services need a small change with https-proxy-agent, shown in the implementation above.
Happy to talk through how a two-IP EU egress fits your Plivo setup, from a single notification service to a fleet of voice AI agents.
Contact Our Founders →