The Meerkly proxy.
One endpoint, HTTP and SOCKS5 on the same port. Choose where your traffic leaves from, and what kind of connection it leaves through, in the username.
Connecting
Point your client at gw.meerkly.com:8888. The port speaks HTTP proxy (CONNECT for HTTPS, absolute-form requests for plain HTTP) and SOCKS5; it tells them apart from the first byte, so there is nothing to configure.
Authenticate with your proxy credential: a user id starting usr_ and its secret, sent as HTTP Proxy-Authorization: Basic or as SOCKS5 username/password. Credentials are issued in the Meerkly dashboard.
http://USER:[email protected]:8888
socks5h://USER:[email protected]:8888Use socks5h, not socks5, so the host name is resolved on the exit rather than on your machine.
Username options
Routing options follow your user id in the username, each written .key-value. They combine freely and in any order:
USER.country-es.type-consumer.session-a1.strict-1| Option | Effect |
|---|---|
.country-<cc> | Exit in this country (ISO 3166-1 alpha-2, e.g. es). The country is measured from the exit's real egress address, not claimed by the device. |
.session-<id> | Keep the same exit across requests. Any id you like, without dots. See sticky sessions. |
.type-<type> | Only exits of this kind: mobile, residential, datacenter, or consumer (mobile or residential). See exit types. |
.strict-1 | With a session: never move it to another exit. Fail instead.true and yes work too. |
Without options, each request goes to any available exit.
Sticky sessions
A .session- id binds to one exit node on its first request and keeps using it. The binding expires after 10 minutes without a request; every request refreshes it. Sessions are per user, so your ids never collide with anyone else's.
Every request re-checks the session's exit against the .country- and .type- you asked for. If the exit has disconnected, or has changed network so it no longer matches, what happens depends on .strict:
- Default (failover). The session moves to a new matching exit and the request goes through. The response carries
X-Meerkly-Session-Moved: 1, so you can tell that the address changed. .strict-1. The session never moves. The request fails with503andX-Meerkly-Error: session_exit_goneorsession_exit_changed, and keeps failing until the binding expires. Start a new session id to continue.
Exit types
Meerkly classifies every exit from the network its traffic actually leaves through, measured by the gateway, together with the transport the device reports (cellular, Wi-Fi, ethernet).
| Type | Meaning |
|---|---|
mobile | Leaves through a cellular network. |
residential | Leaves through a consumer fixed-line or satellite ISP. |
datacenter | Leaves through a hosting or cloud provider. |
unknown | Not measured yet. Reported in headers, never selected by .type-. |
A hosting network is always datacenter, whatever the device reports. When no exit matches your country and type, the request fails with 503 and X-Meerkly-Error: no_exit rather than falling back to another type.
Response headers
The 200 Connection Established answer to a CONNECT tells you what you got:
| Header | Value |
|---|---|
X-Meerkly-Exit-Type | mobile, residential, datacenter or unknown |
X-Meerkly-Exit-Country | Two-letter country code, lowercase |
X-Meerkly-Exit-IP | The IPv4 address targets see |
X-Meerkly-Exit-ASN | The exit network's autonomous system number |
X-Meerkly-Session | Your session id, on sticky requests |
X-Meerkly-Session-Moved | 1 when this request moved the session to a new exit |
A header is left out when its value is not known yet. Plain-HTTP (absolute-form) requests get the target's own response unchanged, and SOCKS5 has no headers; use the session API for those.
Errors
| HTTP | SOCKS5 | Meaning |
|---|---|---|
407 | auth failure | Missing or invalid credential. |
400 | auth failure | The username has an unknown or malformed option. |
403 | 0x02 | Destination refused by policy: mail submission (SMTP), telnet, SMB and NetBIOS, RDP and VNC, database and cache ports, and IPv6 address literals. |
429 | 0x01 | Too many concurrent connections on this credential. |
503 | 0x01 | No exit could be used. X-Meerkly-Error says why: no_exit (nothing matches the country and type), session_exit_gone or session_exit_changed (strict sessions only). |
502 | 0x01 | The exit could not reach the target. |
Session API
Look up what a session is bound to, with the same credential you proxy with:
curl -u USER:SECRET https://dashboard.meerkly.com/api/v1/proxy/sessions/a1{
"session_id": "a1",
"active": true,
"type": "mobile",
"country": "es",
"ipv4": "203.0.113.24",
"ipv6": null,
"asn": 64500,
"isp": "Example Mobile"
}active is false once the exit has disconnected. An unknown or expired session answers 404, and a wrong credential 401. ipv6 is always null; see below.
Address family
Exits are IPv4 only. Targets always see the exit's IPv4 address, including dual-stack sites, and a destination given as an IPv6 address is refused with 403. Targets that have no IPv4 address cannot be reached. One session is one exit node, so every request in it presents the same address.
Examples
curl, HTTP proxy
curl -x "http://USER.country-es.type-consumer.session-a1:[email protected]:8888" \
-D - https://api.ipify.org-D - prints the proxy's CONNECT response, including the X-Meerkly-* headers.
curl, SOCKS5
curl -x "socks5h://USER.session-a1:[email protected]:8888" \
https://api.ipify.orgPython (requests)
import requests
USER, SECRET = "usr_...", "..."
username = f"{USER}.country-es.type-consumer.session-a1.strict-1"
proxy = f"http://{username}:{SECRET}@gw.meerkly.com:8888"
r = requests.get(
"https://api.ipify.org?format=json",
proxies={"http": proxy, "https": proxy},
timeout=30,
)
print(r.json())