Frescoa documentation
Frescoa is a standard HTTP proxy. Any client that supports an HTTP proxy with Basic authentication works — curl, browsers, Node, Python, Go, PHP, Playwright, Puppeteer and so on. You choose the exit country in the proxy username.
Quick start
- Create an account and verify your email.
- Create an API key under Dashboard → API keys. It's shown once — store it in a secret manager.
- Send a request through the country you want:
curl -x http://proxy.frescoa.com:8080 -U "country-za:$FRESCOA_API_KEY" https://api.ipify.org?format=json
# → {"ip":"<a South African IP>"}Endpoint & protocols
| Endpoint | Use |
|---|---|
| http://proxy.frescoa.com:8080 | Standard HTTP proxy. Plain-HTTP requests (absolute-form URLs) and HTTPS via CONNECT. |
| https://proxy.frescoa.com:8443 | The same proxy behind TLS, so your credentials are encrypted between your client and Frescoa (curl: --proxy https://…). |
HTTPS destinations are tunnelled, never decrypted. Your client sends CONNECT host:443, Frescoa opens a raw TCP tunnel from the exit node, and TLS is negotiated end-to-end between you and the destination. Frescoa never sees request paths, headers or bodies of HTTPS traffic.
Allowed destination ports: 80, 443, 8080, 8443. Arbitrary TCP tunnelling and SOCKS are not offered.
Every response through the proxy carries X-Frescoa-Country with the exit country (on CONNECT it's on the tunnel's 200 Connection Established response; on plain HTTP it's on the forwarded response).
Authentication & options
Authenticate with HTTP Basic proxy authentication. The preferred form puts routing options in the username and the API key in the password:
username: country-za-session-checkout42
password: fsk_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXIf your tooling only accepts a single credential string, put the key first in the username and leave the password empty: fsk_XXXX…-country-za.
Options are dash-separated key/value pairs. Unknown options are rejected rather than ignored so typos never route you somewhere unexpected.
| Option | Format | Meaning |
|---|---|---|
| country-xx | ISO 3166-1 alpha-2 (required) | Exit country, e.g. za, gb, us. Case-insensitive. |
| session-xxx | 1–32 letters/digits (optional) | Sticky session: requests with the same id prefer the same exit node. |
Choosing a country
Use the two-letter ISO code. See live network status for which countries are currently available. Rules we guarantee:
- Traffic only ever exits from the country you requested.
- If no healthy node exists in that country you get
503 country_unavailable— we never fall back to another country. - Each exit IP is validated against MaxMind, ipinfo.io and ip-api before activation, and must be recognised as the right country by a majority of them.
Sticky sessions
Add session-<id> to the username to keep a sequence of requests on the same exit node (and therefore the same IP) while it stays healthy. Ids are 1–32 alphanumeric characters you choose; use a new id to get a fresh assignment. If the node becomes unhealthy, the session moves to another node in the same country.
curl -x http://proxy.frescoa.com:8080 -U "country-us-session-cart7:$FRESCOA_API_KEY" https://example.com/Code examples
curl -x http://proxy.frescoa.com:8080 \
-U "country-gb:YOUR_API_KEY" \
https://api.ipify.org?format=jsonWith the TLS endpoint, change the proxy URL scheme to https:// and the port to 8443.
Errors
Errors generated by Frescoa (as opposed to the destination) carry an X-Frescoa-Error header with a stable code, and a JSON body:
HTTP/1.1 503 Service Unavailable
X-Frescoa-Error: country_unavailable
Content-Type: application/json
{"error":{"code":"country_unavailable","message":"No healthy exit nodes are currently available in DE. We never reroute through another country."}}For CONNECT, the error is the response to the CONNECT request itself (curl reports it as the proxy's CONNECT status).
| Code | Status | Meaning |
|---|---|---|
| auth_required | 407 | No Proxy-Authorization header was sent. |
| invalid_credentials | 407 | The API key is missing, malformed or unknown. |
| key_revoked | 407 | The API key has been revoked. |
| invalid_option | 400 | An unknown or malformed username option (e.g. a 3-letter country). |
| country_required | 400 | No country-xx option was given. |
| country_not_supported | 400 | The country isn't part of the Frescoa network. |
| country_not_allowed | 403 | Your plan doesn't include this country. |
| account_suspended | 403 | The account is suspended — contact support. |
| blocked_destination | 403 | The destination resolves to a private, loopback, link-local or metadata address. |
| blocked_port | 403 | The destination port isn't permitted (allowed: 80, 443, 8080, 8443). |
| invalid_destination | 400 | Malformed host, or an https:// URL sent without CONNECT. |
| bandwidth_limit_exceeded | 402 | The account's monthly allowance is used up (and overage isn't enabled). |
| key_limit_exceeded | 402 | This key's own monthly limit is used up. |
| rate_limited | 429 | Requests-per-minute limit exceeded, or too many failed auth attempts from your IP. |
| concurrency_limited | 429 | Too many simultaneous connections for your plan. |
| country_unavailable | 503 | The country is supported but has no healthy node right now. We never reroute elsewhere. |
| internal_error | 503 | Frescoa couldn't authorise the request — safe to retry. |
| upstream_connect_failed | 502 | The exit node couldn't resolve or connect to the destination. |
| node_error | 502 | The exit node failed; retry (another node in the same country may be used). |
| upstream_timeout | 504 | The destination didn't accept the connection in time. |
Limits
Limits are per account and depend on your plan (see pricing):
- Bandwidth — monthly allowance; new connections get
402once exhausted, and long-running transfers are closed. Per-key monthly limits can be set in the dashboard. - Requests per minute — new connections beyond the limit get
429 rate_limited. - Concurrent connections — open tunnels/requests beyond the limit get
429 concurrency_limited. - Idle tunnels are closed after 2 minutes of inactivity.
You're emailed at 50%, 80% and 100% of your allowance.
Metering & billing
- The billing unit is the decimal gigabyte: 1 GB = 1,000,000,000 bytes.
- Billable bandwidth = bytes uploaded to the destination + bytes downloaded from it, measured at the gateway. For HTTPS this is the encrypted tunnel traffic, including TLS overhead.
- Requests rejected by Frescoa (auth, limits, blocked destinations) transfer no bytes and aren't billed.
- Usage appears in the dashboard within seconds, broken down by country and API key. Billing periods are UTC calendar months.
Security model
- Frescoa is never an open proxy: every connection is authenticated and attributed to an account.
- Destinations resolving to private (RFC 1918), loopback, link-local, CGNAT, multicast, reserved or cloud-metadata addresses (e.g. 169.254.169.254) are blocked. The check is repeated on the exit node after DNS resolution, which defeats DNS-rebinding tricks.
- Gateway-to-node links use TLS with pinned certificates.
- We log connection metadata (time, account, destination host and port, bytes, status) for abuse investigation and billing — never request contents. Metadata is retained for 30 days.
- Use of Frescoa is governed by the acceptable-use policy. Report abuse at frescoa.com/abuse.