In plain English: Axios is a widely used JavaScript library for making web requests from Node.js. It has a built-in proxy option, but that option often fails with HTTPS sites, which these days means most of the web. The dependable fix is a proxy agent: a small helper package, https-proxy-agent, that handles the connection to the proxy on Axios's behalf, secure tunnel included. Below you'll find that setup, then a reusable client, rotation, retries and SOCKS5.
Quick start in 3 steps
- Install Axios and the agent package with npm.
- Test your proxy details with a single cURL command.
- Paste the agent example, add your details, and run it with Node.js. The IP it prints should be the proxy's.
Two packages to install
npm install axios https-proxy-agentThe code below uses HOST, PORT, USER and PASS as placeholders for your real details. Check those details in a terminal before writing any JavaScript:
curl --proxy http://USER:PASS@HOST:PORT https://api.ipify.orgThe dependable way: a proxy agent
Build an agent from your proxy address and hand it to Axios. The agent opens the tunnel for secure sites (the HTTP CONNECT method) and sends your login along the way:
const axios = require("axios");
const { HttpsProxyAgent } = require("https-proxy-agent");
const proxyUrl = "http://USER:PASS@HOST:PORT";
const agent = new HttpsProxyAgent(proxyUrl);
(async () => {
const res = await axios.get("https://api.ipify.org?format=json", {
httpAgent: agent,
httpsAgent: agent,
timeout: 20000
});
console.log(res.data);
})();Giving the same agent to both httpAgent and httpsAgent covers plain and secure sites alike. If the printed IP is the proxy's, it works. This is the setup to use in almost every project.
What about Axios's own proxy option?
For reference, the built-in setting looks like this:
const res = await axios.get("http://httpbin.org/ip", {
proxy: {
protocol: "http",
host: "HOST",
port: Number("PORT"),
auth: { username: "USER", password: "PASS" }
}
});It can work for plain http:// sites, but with HTTPS it often fails, depending on your Node.js and Axios versions, and the error messages rarely point to the real cause. Since nearly every site uses HTTPS now, stay with the agent.
One client for the whole project
If most of your requests go through the same proxy, create a preconfigured Axios instance once and reuse it everywhere. Your code stays shorter:
const axios = require("axios");
const { HttpsProxyAgent } = require("https-proxy-agent");
const agent = new HttpsProxyAgent("http://USER:PASS@HOST:PORT");
const client = axios.create({
httpAgent: agent,
httpsAgent: agent,
timeout: 20000,
headers: { "User-Agent": "Mozilla/5.0 (compatible; MyScraper/1.0)" }
});
client.get("https://example.com").then(r => console.log(r.status));Taking turns across endpoints
Have a list of sticky endpoints? Make one agent per endpoint, then use the next agent for each request, so no single IP does all the work:
const axios = require("axios");
const { HttpsProxyAgent } = require("https-proxy-agent");
const urls = [
"http://USER:PASS@HOST:PORT1",
"http://USER:PASS@HOST:PORT2",
"http://USER:PASS@HOST:PORT3"
];
const agents = urls.map(u => new HttpsProxyAgent(u));
let i = 0;
async function fetch(url) {
const agent = agents[i++ % agents.length];
return axios.get(url, { httpAgent: agent, httpsAgent: agent, timeout: 20000 });
}
fetch("https://api.ipify.org?format=json").then(r => console.log(r.data));A single rotating gateway is simpler still. One agent is enough, because the gateway hands each request a fresh IP by itself.
Retrying without hammering
Through any proxy the odd request will fail, and busy sites sometimes reply with 429, meaning too many requests. This small wrapper waits a bit longer after each failed attempt:
async function getWithRetry(url, opts, tries = 4) {
for (let attempt = 1; attempt <= tries; attempt++) {
try {
return await axios.get(url, opts);
} catch (err) {
const status = err.response && err.response.status;
if (attempt === tries || (status && status < 500 && status !== 429)) throw err;
await new Promise(r => setTimeout(r, attempt * 1500));
}
}
}It retries network errors, 429 and server errors (the 5xx codes), but gives up straight away on mistakes such as 404 (page not found), which no amount of retrying will fix.
Using a SOCKS5 proxy instead
For SOCKS5, install a different agent package:
npm install socks-proxy-agentThen build the agent from your SOCKS5 address:
const { SocksProxyAgent } = require("socks-proxy-agent");
const agent = new SocksProxyAgent("socks5://USER:PASS@HOST:PORT");
// then pass it as httpAgent and httpsAgent exactly as beforeCheck it worked
Run the ipify example and compare the IP it prints with your own, or put the same details through our proxy checker.
Which type should I pick?
- APIs, simple sites and practice projects: datacenter proxies keep the bill small.
- Sites that look harder at who's visiting: residential proxies, stepping up to residential premium if needed.
- Mobile-app data or carrier-specific pages: mobile proxies.
Every type is described on the proxies page and priced on the pricing page, and our proxy for scraping overview goes further into scraping itself.
Common mistakes
- Using the proxy field for HTTPS sites. Use the agent instead.
- Setting only one of the two agents. Give the agent to both httpAgent and httpsAgent, so plain and secure sites both go through the proxy.
- Copying an older import line. Recent versions of https-proxy-agent use the curly-brace import shown above. Older tutorials import it differently, which can fail with a "not a constructor" error.
- No timeout. Keep one like the examples' 20000 (that's in milliseconds, so twenty seconds), so a dead proxy can't stall your script.
Is this allowed?
When you scrape, read the target's robots.txt, respect its terms of service, keep your request rate low and collect only public, permitted data. Never use a proxy to get round a login, defeat anti-fraud checks or commit fraud. A considerate script that backs off when it sees a 429 and limits how many requests run at once keeps working far longer than one that floods a server.
Beginner questions
Why do I need two packages?
Axios makes the requests; the agent package handles the proxy connection, which Axios's own option doesn't do reliably for HTTPS.
Can I use this code in a web browser?
No. Proxy agents are a Node.js feature. In a browser, requests go through the browser's own proxy settings.
Does this work with a rotating gateway?
Yes. Create one agent for the gateway, and each request gets a new IP from it.