Developers

API documentation

Automate your proxies: everything in your dashboard, from your own code. Create a key, send it in a header, and you're set.

Introduction

The Proxy Portal API lets your own scripts, bots and apps do everything your dashboard does: check your balance, buy GB and ISP IPs, create, move and delete proxies, read your usage and talk to support. It's a plain HTTPS JSON API that works with any language.

Base URL
https://proxyportal.io/api/me
Authentication
X-Api-Key: YOUR_API_KEY header
Format
JSON request bodies (Content-Type: application/json), JSON responses. Times are ISO 8601 in UTC, money in USD, traffic in GB (1 GB = 109 bytes).
Proxy host
gw-pr.proxyportal.io · HTTP 8080 · SOCKS5 1080

Paths below are relative to the base URL. Calls change only your own account; nothing here can see other customers.

Authentication

Create a key in your dashboard under Account → API (no account yet? Sign up). Keys start with ppu_ and are shown only once, so copy it when you create it. Send it in the X-Api-Key header on every call:

Header
X-Api-Key: ppu_your_key_here
  • Use the key on proxyportal.io, the site where you created your account. On any other address it answers 401.
  • You can have up to 10 active keys, for example one per bot. Revoke a key in the dashboard and it stops working at once.
  • Anyone with your key can spend your balance. Keep it on your server, never in a web page or app that others can download.
  • For safety, a key can't create or revoke keys or change your password (403); do that in the dashboard.

Quick start

Check your balance, then create a proxy and print its connection URL:

# Check your balance
curl "https://proxyportal.io/api/me/summary" -H "X-Api-Key: $API_KEY"

# Create one US proxy that changes IP every 15 minutes
curl -X POST "https://proxyportal.io/api/me/proxies" \
  -H "X-Api-Key: $API_KEY" -H "Content-Type: application/json" \
  -d '{"country": "us", "rotation": 15, "count": 1}'

The Python example uses requests; the Node.js one needs Node 18 or newer (built-in fetch, run as an ES module).

Errors & limits

Errors use standard HTTP status codes and a JSON body with a human-readable detail you can show to people:

Error
HTTP/1.1 402 Payment Required

{ "detail": "your balance is 0 GB; add GB first" }

When a field fails validation (422), detail is a list that says which field and why:

Validation error
{ "detail": [ { "type": "less_than_equal", "loc": ["body", "count"], "msg": "Input should be less than or equal to 20", "input": 50 } ] }
200Success. The body is JSON.
400Something in the request can't be done, e.g. a state and a city together.
401The key is missing, wrong, revoked, or used on another site's address.
402Not enough balance: no GB left, or not enough money for a purchase.
403Not allowed with an API key (passwords and keys are managed in the dashboard).
404The proxy, IP or ticket doesn't exist or isn't yours.
409Can't be done right now, e.g. a location just sold out.
422A field is missing or has the wrong type or value (FastAPI validation; detail is a list).
429Too many of something, e.g. open support tickets.
5xxA temporary problem on our side or with an upstream network; retry after a moment.

Limits

There's no fixed request quota per key today, but please keep polling reasonable (once a minute is plenty for usage) and reuse proxies instead of creating new ones for every request. These limits are enforced:

  • Up to 20 proxies per create call and 200 active proxies per account.
  • Up to 10 active API keys.
  • ISP IPs: up to max_quantity per order (and what's in stock).
  • Top-ups up to $10,000 each.
  • Support: 10 open tickets at a time, 15 new tickets a day, 3 attachments of 2 MB per message.

Connecting to proxies

Every proxy is reached through our gateway at gw-pr.proxyportal.io with the proxy's own username and password. One login works on every port:

HTTP8080
SOCKS51080
HTTPS (TLS to the proxy)8443

Each proxy object comes with ready-made URLs in urls and a short connection_string:

Connection string
protocol://username:[email protected]:port

http://m1_3f9a2c1b7d4e:[email protected]:8080
socks5://m1_3f9a2c1b7d4e:[email protected]:1080

Settings in the username

The proxy's plain username uses the settings it was created with. You can also put settings in the username itself (that's full_username) and change location or rotation without any API call. Keys go in this order and are joined with -:

Username format
user-<login>-type-<mobile|residential|datacenter>-session-<id>-country-<cc>[-state-<state> | -city-<city>][-asn-<asn>]-rotation-<minutes>

user-m1_3f9a2c1b7d4e-type-mobile-session-8c1d0f2a-country-de-city-Munich-rotation-10
  • rotation: -1 new IP on every request, 0 keep the same IP as long as possible, or 5, 10, 15, 20, 60 minutes per IP. Leave it out to keep the rotation the proxy was created with.
  • Change session to any other letters and digits (up to 32) to get a different IP right away.
  • State and city names come from Locations, with spaces written as _. Use a state or a city, not both.
  • The password is always the proxy's own password.
curl -x "http://m1_3f9a2c1b7d4e:[email protected]:8080" https://api.ipify.org

curl -x "socks5h://m1_3f9a2c1b7d4e:[email protected]:1080" https://api.ipify.org

Traffic is taken from your GB balance as you use it. When it reaches 0 the gateway answers 402 until you add GB. ISP IPs aren't metered.

Account

GET/summary

Account summary

Your balances, the proxy host and ports to connect to, and your price per GB. A good first call to check that your key works.

Request
curl "https://proxyportal.io/api/me/summary" \
  -H "X-Api-Key: $API_KEY"
Response
{
  "email": "[email protected]",
  "name": "Alex",
  "site": "Proxy Portal",
  "balance_gb": 12.5,
  "used_gb": 37.5,
  "active_proxies": 3,
  "proxy_host": "gw-pr.proxyportal.io",
  "ports": { "http": 8080, "socks5": 1080 },
  "support_email": "[email protected]",
  "telegram_link": "https://t.me/example",
  "logo_url": null,
  "primary_color": null,
  "prices": [{ "from_gb": 1, "usd_per_gb": 4.5 }, { "from_gb": 50, "usd_per_gb": 3.9 }],
  "balance_usd": 25.0,
  "discount_pct": null,
  "support_unread": 0
}
GET/usage

Traffic usage

GB used in the last 24 hours, 7 and 30 days, plus a time series in UTC buckets. Usage is counted per hour.

Query parameters

range string
24h, 7d (default) or 30d.
bucket string
hour, day (default) or week (weeks start on Monday).
Request
curl "https://proxyportal.io/api/me/usage?range=7d&bucket=day" \
  -H "X-Api-Key: $API_KEY"
Response
{
  "range": "7d",
  "bucket": "day",
  "totals": { "24h": 0.84, "7d": 5.12, "30d": 21.7 },
  "points": [
    { "t": "2026-11-04T00:00:00+00:00", "gb": 0.62 },
    { "t": "2026-11-05T00:00:00+00:00", "gb": 0.0 }
  ]
}

Errors

  • 400 range is 24h/7d/30d, bucket is hour/day/week
GET/history

GB balance history

Changes to your GB balance other than metered traffic (top-ups, adjustments, refunds), newest first, up to 200.

Request
curl "https://proxyportal.io/api/me/history" \
  -H "X-Api-Key: $API_KEY"
Response
[
  { "id": 77, "type": "Top-up", "delta_gb": 10.0, "note": "bought with balance $45.00", "created_at": "2026-11-09T18:20:03Z" }
]
GET/wallet

Money balance

Your USD balance and its history (top-ups, GB and ISP purchases, referral rewards, refunds), newest first.

Request
curl "https://proxyportal.io/api/me/wallet" \
  -H "X-Api-Key: $API_KEY"
Response
{
  "balance_usd": 25.0,
  "transactions": [
    { "id": 140, "type": "gb_buy", "usd": -45.0, "note": "10 GB at $4.50/GB", "created_at": "2026-11-09T18:20:03+00:00" }
  ]
}
POST/profile

Update your name

Changes the name on your account. Passwords and API keys can only be changed from the dashboard, not with an API key.

Body (JSON)

name stringrequired
Up to 120 characters; empty clears it.
Request
curl -X POST "https://proxyportal.io/api/me/profile" \
  -H "X-Api-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Alex"}'
Response
{ "name": "Alex" }

Mobile proxies

Rotating 4G/5G proxies billed per GB from your balance. Each proxy has its own login; the location and rotation can also be changed in the username alone (see Connecting).

GET/proxies

List proxies

Your active mobile proxies, newest first.

Request
curl "https://proxyportal.io/api/me/proxies" \
  -H "X-Api-Key: $API_KEY"
Response
[
  {
    "id": 4821,
    "protocol": "http",
    "host": "gw-pr.proxyportal.io",
    "port": 8080,
    "username": "m1_3f9a2c1b7d4e",
    "password": "Jt8vQm2LxR0aZk1c",
    "connection_string": "http://m1_3f9a2c1b7d4e:[email protected]:8080",
    "full_username": "user-m1_3f9a2c1b7d4e-type-mobile-session-8c1d0f2a9b3e4d5c-country-us-city-Los_Angeles-rotation-15",
    "proxy_type": "mobile",
    "urls": {
      "http": "http://user-m1_3f9a2c1b7d4e-type-mobile-...-rotation-15:[email protected]:8080",
      "socks5": "socks5://user-m1_3f9a2c1b7d4e-type-mobile-...-rotation-15:[email protected]:1080",
      "https": "https://user-m1_3f9a2c1b7d4e-type-mobile-...-rotation-15:[email protected]:8443"
    },
    "ports": { "http": 8080, "socks5": 1080, "https": 8443 },
    "country": "us",
    "state": null,
    "city": "Los_Angeles",
    "rotation": 15,
    "active": true,
    "created_at": "2026-11-10T09:12:44.118000Z"
  }
]
POST/proxies

Create proxies

Creates 1 to 20 proxies with the same settings. You need GB on your balance; you can have up to 200 active proxies.

rotation: -1 new IP on every request, 0 keep the same IP as long as possible, or 5, 10, 15, 20, 60 minutes per IP.

Body (JSON)

country stringrequired
Two-letter country code, e.g. us, de, gb (see Locations).
state string
A state or region from Locations, e.g. California. Use a state or a city, not both.
city string
A city from Locations, e.g. Los_Angeles (spaces are written as _).
asn string
Mobile carrier ASN, digits only, e.g. 21928.
rotation integer
Default 15. -1, 0, 5, 10, 15, 20 or 60 (see below).
protocol string
http (default) or socks5. Every proxy also works on the other ports; this only picks connection_string.
count integer
How many proxies, 1 to 20. Default 1.
proxy_type string
mobile (default), residential or datacenter.
Request
curl -X POST "https://proxyportal.io/api/me/proxies" \
  -H "X-Api-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"country": "us", "city": "Los_Angeles", "rotation": 15, "protocol": "http", "count": 2}'
Response
[
  {
    "id": 4821,
    "protocol": "http",
    "host": "gw-pr.proxyportal.io",
    "port": 8080,
    "username": "m1_3f9a2c1b7d4e",
    "password": "Jt8vQm2LxR0aZk1c",
    "connection_string": "http://m1_3f9a2c1b7d4e:[email protected]:8080",
    "full_username": "user-m1_3f9a2c1b7d4e-type-mobile-session-8c1d0f2a9b3e4d5c-country-us-city-Los_Angeles-rotation-15",
    "proxy_type": "mobile",
    "urls": {
      "http": "http://user-m1_3f9a2c1b7d4e-type-mobile-...-rotation-15:[email protected]:8080",
      "socks5": "socks5://user-m1_3f9a2c1b7d4e-type-mobile-...-rotation-15:[email protected]:1080",
      "https": "https://user-m1_3f9a2c1b7d4e-type-mobile-...-rotation-15:[email protected]:8443"
    },
    "ports": { "http": 8080, "socks5": 1080, "https": 8443 },
    "country": "us",
    "state": null,
    "city": "Los_Angeles",
    "rotation": 15,
    "active": true,
    "created_at": "2026-11-10T09:12:44.118000Z"
  }
]

Errors

  • 400 choose a state or a city, not both
  • 400 you can have up to 200 active proxies; delete some first
  • 402 your balance is 0 GB; add GB first
POST/proxies/{id}/location

Change location

Moves a proxy to another country, state, city or carrier. The login stays the same; you get a new IP. Rotation is kept unless you send one.

Body (JSON)

country stringrequired
Two-letter country code, e.g. us, de, gb (see Locations).
state string
A state or region from Locations, e.g. California. Use a state or a city, not both.
city string
A city from Locations, e.g. Los_Angeles (spaces are written as _).
asn string
Mobile carrier ASN, digits only, e.g. 21928.
rotation integer
Optional new rotation: -1, 0, 5, 10, 15, 20 or 60.
Request
curl -X POST "https://proxyportal.io/api/me/proxies/4821/location" \
  -H "X-Api-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"country": "de", "city": "Munich"}'
Response
{
  "id": 4821,
  "protocol": "http",
  "host": "gw-pr.proxyportal.io",
  "port": 8080,
  "deername": "m1_3f9a2c1b7d4e",
  "password": "Jt8vQm2LxR0aZk1c",
  "connection_string": "http://m1_3f9a2c1b7d4e:[email protected]:8080",
  "full_username": "user-m1_3f9a2c1b7d4e-type-mobile-session-8c1d0f2a9b3e4d5c-country-us-city-Munich-rotation-15",
  "proxy_type": "mobile",
  "urls": {
    "http": "http://user-m1_3f9a2c1b7d4e-type-mobile-...-rotation-15:[email protected]:8080",
    "socks5": "socks5://user-m1_3f9a2c1b7d4e-type-mobile-...-rotation-15:[email protected]:1080",
    "https": "https://user-m1_3f9a2c1b7d4e-type-mobile-...-rotation-15:[email protected]:8443"
  },
  "ports": { "http": 8080, "socks5": 1080, "https": 8443 },
  "country": "us",
  "state": null,
  "city": "Munich",
  "rotation": 15,
  "active": true,
  "created_at": "2026-11-10T09:12:44.118000Z"
}

Errors

  • 404 proxy not found
POST/proxies/{id}/reset

Get a new IP

Starts a new session: same login and location, new IP. Proxies with rotation -1 already change IP on every request and don't need it.

Request
curl -X POST "https://proxyportal.io/api/me/proxies/4821/reset" \
  -H "X-Api-Key: $API_KEY"
Response
{
  "id": 4821,
  "protocol": "http",
  "host": "gw-pr.proxyportal.io",
  "port": 8080,
  "username": "m1_3f9a2c1b7d4e",
  "password": "Jt8vQm2LxR0aZk1c",
  "connection_string": "http://m1_3f9a2c1b7d4e:[email protected]:8080",
  "full_username": "user-m1_3f9a2c1b7d4e-type-mobile-session-8c1d0f2a9b3e4d5c-country-us-city-Los_Angeles-rotation-15",
  "proxy_type": "mobile",
  "urls": {
    "http": "http://user-m1_3f9a2c1b7d4e-type-mobile-...-rotation-15:[email protected]:8080",
    "socks5": "socks5://user-m1_3f9a2c1b7d4e-type-mobile-...-rotation-15:[email protected]:1080",
    "https": "https://user-m1_3f9a2c1b7d4e-type-mobile-...-rotation-15:[email protected]:8443"
  },
  "ports": { "http": 8080, "socks5": 1080, "https": 8443 },
  "country": "us",
  "state": null,
  "city": "Los_Angeles",
  "rotation": 15,
  "active": true,
  "created_at": "2026-11-10T09:12:44.118000Z"
}

Errors

  • 400 this proxy already gets a new IP on every request
  • 404 proxy not found
POST/proxies/{id}/check

Check a proxy

Sends one small request through the proxy (a few KB of your traffic) and returns where it came out. Works for mobile proxies and ISP IPs. A failed check still answers 200, with ok: false and the reason.

Request
curl -X POST "https://proxyportal.io/api/me/proxies/4821/check" \
  -H "X-Api-Key: $API_KEY"
Response
{
  "ok": true,
  "ip": "172.56.21.90",
  "country_code": "US",
  "region": "California",
  "city": "Los Angeles",
  "org": "AS21928 T-Mobile USA, Inc.",
  "label": "US, California, Los Angeles, 172.56.21.90",
  "latency_ms": 812
}

// or
{ "ok": false, "error": "no GB left on your balance" }

Errors

  • 404 proxy not found
POST/proxies/{id}/delete

Delete a proxy

Stops a proxy. Its login stops working right away; unused GB stay on your balance.

Request
curl -X POST "https://proxyportal.io/api/me/proxies/4821/delete" \
  -H "X-Api-Key: $API_KEY"
Response
{ "ok": true }

Errors

  • 404 proxy not found

Locations

Public lists for choosing a proxy location. They need no key and are cached for an hour.

GET/api/public/locationsNo key needed

Countries, states and cities

Every country with mobile proxies, with the state and city names to send to Create proxies and Change location.

Request
curl "https://proxyportal.io/api/public/locations"
Response
[
  { "country": "Germany", "country_code": "DE", "states": ["Bavaria", "Hessen"], "cities": ["Munich", "Frankfurt_am_Main"] },
  { "country": "United States", "country_code": "US", "states": ["California", "Texas"], "cities": ["Los_Angeles", "Chicago"] }
]
GET/api/public/countriesNo key needed

Countries only

Just the countries, sorted by name.

Request
curl "https://proxyportal.io/api/public/countries"
Response
[{ "country": "Germany", "country_code": "DE" }, { "country": "United States", "country_code": "US" }]

Buying GB

GB are bought with your money balance (top it up with Top up). The price per GB gets lower with volume.

GET/gb-quote

Price quote

What a given amount of GB costs you, and whether your balance covers it. Prices are null while not set.

Query parameters

gb_amount numberrequired
GB to price, e.g. 10.
Request
curl "https://proxyportal.io/api/me/gb-quote?gb_amount=10" \
  -H "X-Api-Key: $API_KEY"
Response
{ "usd_per_gb": 4.5, "total_usd": 45.0, "balance_usd": 50.0, "enough": true }
POST/buy-gb

Buy GB

Buys GB with your money balance. The GB are added at once.

Body (JSON)

gb numberrequired
More than 0, up to 100,000.
Request
curl -X POST "https://proxyportal.io/api/me/buy-gb" \
  -H "X-Api-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"gb": 10}'
Response
{ "balance_gb": 22.5, "balance_usd": 5.0 }

Errors

  • 402 this costs $45.00; your balance is $20.00
  • 409 GB prices are not set yet; please contact support

ISP IPs

Static ISP IPs rented per IP for 30 to 365 days and paid from your money balance. Unlimited traffic; HTTP and HTTPS on port 8080, SOCKS5 on 1080, with the same login.

GET/isp/offers

Locations and prices

Locations in stock with your price per IP for each period. Standard IPs are located in the city and registered abroad; Premium IPs are registered to a local provider.

Request
curl "https://proxyportal.io/api/me/isp/offers" \
  -H "X-Api-Key: $API_KEY"
Response
{
  "days": [30, 60, 90, 180, 365],
  "max_quantity": 20,
  "balance_usd": 25.0,
  "offers": [
    {
      "id": "JPNTOKTOK.2.NONE",
      "country": "JP",
      "country_name": "Japan",
      "city": "Tokyo",
      "type": "Premium",
      "type_note": "Registered to a local internet provider in this country. Passes strict location checks.",
      "isp_type": 2,
      "recommended": true,
      "available": 14,
      "prices": { "30": { "usd": 7.0 }, "60": { "usd": 14.0 }, "90": { "usd": 21.0 }, "180": { "usd": 42.0 }, "365": { "usd": 85.17 } }
    }
  ]
}

Errors

  • 503 ISP IPs are not available right now
GET/isp

Your ISP IPs

Your ISP IPs with their login and expiry, and orders still being set up (usually ready within a few minutes).

Request
curl "https://proxyportal.io/api/me/isp" \
  -H "X-Api-Key: $API_KEY"
Response
{
  "proxies": [
    {
      "id": 9120,
      "country": "JP",
      "city": "Tokyo",
      "protocol": "http",
      "host": "gw-pr.proxyportal.io",
      "port": 8080,
      "http_port": 8080,
      "socks5_port": 1080,
      "username": "isp_5d0c9e7a21",
      "password": "pW3kq9ZrT1",
      "expires_at": "2026-12-10T09:30:00+00:00",
      "expired": false,
      "days_left": 30,
      "ip": "203.0.113.24"
    }
  ],
  "pending": [{ "id": 55, "quantity": 2, "city": "Tokyo", "days": 30 }],
  "balance_usd": 18.0
}
POST/isp/buy

Buy ISP IPs

Orders IPs at one location; the price is taken from your balance. If an order can't be completed it's refunded automatically.

Body (JSON)

offer stringrequired
An offer id from Locations and prices, e.g. JPNTOKTOK.2.NONE.
quantity integer
Default 1. At most what the offer has in stock and max_quantity.
days integer
30 (default), 60, 90, 180 or 365.
protocol string
http (default) or socks5: which port the returned port field shows.
Request
curl -X POST "https://proxyportal.io/api/me/isp/buy" \
  -H "X-Api-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"offer": "JPNTOKTOK.2.NONE", "quantity": 1, "days": 30, "protocol": "http"}'
Response
{
  "order_id": 56,
  "status": "pending",
  "proxies": [],
  "pending": [{ "id": 56, "quantity": 1, "city": "Tokyo", "days": 30 }],
  "balance_usd": 18.0
}

Errors

  • 400 days must be one of 30, 60, 90, 180, 365
  • 402 this costs $7.00; your balance is $5.00
  • 409 this location is out of stock; pick another one
  • 503 ISP IPs are not available right now
POST/isp/{id}/renew

Renew an ISP IP

Extends an IP for another period; you keep the same IP. Returns the same data as Your ISP IPs.

Body (JSON)

days integer
30 (default), 60, 90, 180 or 365.
Request
curl -X POST "https://proxyportal.io/api/me/isp/9120/renew" \
  -H "X-Api-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"days": 30}'
Response
{ "proxies": [ ... ], "pending": [], "balance_usd": 11.0 }

Errors

  • 404 IP not found
  • 409 this IP can't be renewed online; please contact support

Payments

GET/payments

Top-ups

Whether online top-ups are on, the accepted coins and networks, the limits, and your last 50 payments.

Request
curl "https://proxyportal.io/api/me/payments" \
  -H "X-Api-Key: $API_KEY"
Response
{
  "enabled": true,
  "min_usd": 5,
  "max_usd": 10000,
  "methods": [{ "trade_type": "usdt.trc20", "currency": "USDT", "network": "TRC20", "label": "USDT · TRC20 (Tron)" }],
  "balance_usd": 25.0,
  "payments": [
    { "id": 31, "usd": 50.0, "status": "paid", "method": "USDT · TRC20 (Tron)", "payment_url": null,
      "crypto_amount": "50", "tx_hash": "9f2c...", "created_at": "2026-11-08T12:00:00+00:00", "paid_at": "2026-11-08T12:04:10+00:00" }
  ]
}
POST/topup

Top up

Starts a crypto payment. Open payment_url to pay; your money balance goes up once the payment is confirmed.

Body (JSON)

usd numberrequired
Amount in USD, from min_usd up to 10,000.
trade_type string
A method from Top-ups, e.g. usdt.trc20. Leave out to choose on the payment page.
Request
curl -X POST "https://proxyportal.io/api/me/topup" \
  -H "X-Api-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"usd": 50, "trade_type": "usdt.trc20"}'
Response
{ "id": 32, "payment_url": "https://pay.example.com/pay/checkout-counter?trade_id=..." }

Errors

  • 400 amount must be from $5 to $10,000
  • 503 online payment is not set up yet; please contact support

Rewards

GET/referral

Referral link

Your referral link, the share of your referrals' deposits you earn, and your totals.

Request
curl "https://proxyportal.io/api/me/referral" \
  -H "X-Api-Key: $API_KEY"
Response
{ "code": "ALEX7Q", "link": "https://proxyportal.io/signup?ref=ALEX7Q", "pct": 5, "invited": 4, "earned_usd": 12.5 }
POST/promo

Redeem a promo code

Adds a promo code's value to your money balance.

Body (JSON)

code stringrequired
3 to 32 letters, digits, - or _ (not case sensitive).
Request
curl -X POST "https://proxyportal.io/api/me/promo" \
  -H "X-Api-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"code": "WELCOME5"}'
Response
{ "added_usd": 5.0, "balance_usd": 30.0 }

Errors

  • 400 codes are 3 to 32 letters, digits, - or _

Support tickets

Open and answer support tickets. You get an email whenever support replies.

GET/tickets

List tickets

Your tickets, latest activity first, plus the categories and priorities you can use.

Request
curl "https://proxyportal.io/api/me/tickets" \
  -H "X-Api-Key: $API_KEY"
Response
{
  "tickets": [
    {
      "id": 318,
      "number": "#318",
      "subject": "Proxy stopped working",
      "category": "proxies",
      "category_label": "Proxies & connection",
      "requester": "user",
      "priority": "normal",
      "status": "open",
      "last_reply_by": "user",
      "last_message_at": "2026-11-10T10:02:11Z",
      "created_at": "2026-11-10T10:02:11Z",
      "closed_at": null,
      "unread": false,
      "messages": 1
    }
  ],
  "categories": { "general": "General question", "technical": "Technical issue", "proxies": "Proxies & connection",
                  "isp": "ISP IPs", "billing": "Billing & payments", "account": "Account" },
  "priorities": ["low", "normal", "high", "urgent"]
}
POST/tickets

Open a ticket

Up to 10 open tickets at a time and 15 new ones a day. Attach up to 3 files (PNG, JPG, WebP, GIF, PDF or TXT, 2 MB each, 2.5 MB together) as base64 data URLs.

Body (JSON)

subject stringrequired
Up to 200 characters.
body stringrequired
Your message, up to 20,000 characters.
category string
A key from categories. Default general.
priority string
low, normal (default), high or urgent.
files array
Up to 3 of {"name": "log.txt", "data_url": "data:text/plain;base64,..."}.
Request
curl -X POST "https://proxyportal.io/api/me/tickets" \
  -H "X-Api-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"subject": "Proxy stopped working", "category": "proxies", "body": "Proxy 4821 times out since 10:00 UTC."}'
Response
{
  "id": 318,
  "number": "#318",
  "subject": "Proxy stopped working",
  "category": "proxies",
  "category_label": "Proxies & connection",
  "requester": "user",
  "priority": "normal",
  "status": "open",
  "last_reply_by": "user",
  "last_message_at": "2026-11-10T10:02:11Z",
  "created_at": "2026-11-10T10:02:11Z",
  "closed_at": null,
  "unread": false,
  "messages": 1
}

Errors

  • 400 subject can't be empty
  • 429 you already have 10 open tickets; reply in one of them or close some first
GET/tickets/{id}

Read a ticket

The ticket and its messages, oldest first. Answers from support have author: "staff". Reading it marks it as read.

Request
curl "https://proxyportal.io/api/me/tickets/318" \
  -H "X-Api-Key: $API_KEY"
Response
{
  "ticket": { "id": 318, "number": "#318", "status": "answered", ... },
  "messages": [
    { "id": 901, "author": "user", "author_name": "Alex", "body": "Proxy 4821 times out since 10:00 UTC.",
      "internal": false, "created_at": "2026-11-10T10:02:11Z", "attachments": [] },
    { "id": 905, "author": "staff", "author_name": "Proxy Portal support", "body": "Fixed, please try again.",
      "internal": false, "created_at": "2026-11-10T10:20:40Z",
      "attachments": [{ "name": "screenshot.png", "size": 48211, "type": "image/png",
                        "url": "/api/me/tickets/318/files/3f0c5b7e9d2a4c18b6e0f1a2d3c4b5a6.png" }] }
  ]
}

Errors

  • 404 ticket not found
POST/tickets/{id}/reply

Reply

Adds your message to a ticket (a closed ticket opens again).

Body (JSON)

body stringrequired
Up to 20,000 characters.
files array
Up to 3 files, as in Open a ticket.
Request
curl -X POST "https://proxyportal.io/api/me/tickets/318/reply" \
  -H "X-Api-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"body": "Works now, thanks!"}'
Response
{ "ok": true }

Errors

  • 404 ticket not found
POST/tickets/{id}/close

Close a ticket

Marks a ticket as solved.

Request
curl -X POST "https://proxyportal.io/api/me/tickets/318/close" \
  -H "X-Api-Key: $API_KEY"
Response
{ "ok": true }

Errors

  • 404 ticket not found
GET/tickets/{id}/files/{file}

Download an attachment

Downloads a file from a message; the url of each attachment already points here (send your key with it).

Request
curl "https://proxyportal.io/api/me/tickets/318/files/3f0c5b7e9d2a4c18b6e0f1a2d3c4b5a6.png" \
  -H "X-Api-Key: $API_KEY"
Response
(the file itself)

Errors

  • 404 file not found