Deposit $50.00 or more and get 10% extra balance, until Nov 14, 2026.

Create an account
BooProxies

Reseller API

One JSON API for everything you sell: your prices, new plans, top-ups, usage, new passwords, tests and IP lists. It takes about ten minutes to wire up.

The basics

  • Base address: https://proxies.boo/api/v1
  • Send and receive JSON. POST bodies need Content-Type: application/json.
  • Money is always in US cents, as whole numbers: 330 is $3.30.
  • Orders are paid from your account balance the moment you place them. Add balance in the dashboard.
  • Every order is charged at the reseller price. See the reseller prices.

Authentication

Once your reseller application is approved, make a key in Dashboard > Reseller and send it with every request. A key is shown once, when you make it; store it like a password. You can lock a key to your server's IP addresses and revoke it at any time.

curl https://proxies.boo/api/v1/account -H "Authorization: Bearer boo_YOUR_KEY"

The header X-API-Key: boo_YOUR_KEY works too.

Answers and errors

A request that works answers {"success": true, "data": ...}. One that does not answers with an HTTP error status and a code you can act on:

{"success": false, "error": {"code": "INSUFFICIENT_BALANCE", "message": "This order costs $3.30 and the balance is $1.00. Add balance in the dashboard."}}
StatusCodeMeaning
400VALIDATION_ERRORA field is missing or out of range. The message says which.
400INVALID_JSONThe body could not be read as JSON.
401INVALID_API_KEYNo key, a wrong key or a revoked key.
402INSUFFICIENT_BALANCEThe balance does not cover the order. Nothing was charged.
403IP_NOT_ALLOWEDThe key is locked to other IP addresses.
403RESELLER_OFFThe account is not an approved reseller, or access was paused.
404PLAN_NOT_FOUND / ORDER_NOT_FOUND / PRODUCT_NOT_FOUNDNothing with that id on this account.
409ORDER_FAILEDThe order was refused. Nothing was charged, or the price is back in the balance.
409PLAN_ENDED / NOT_SUPPORTEDThe plan has ended, or this product does not offer that action.
429RATE_LIMITEDToo many requests. Wait a minute and retry.
502 / 503TRY_AGAINA short hiccup upstream. Retry after a few seconds.

Rate limits

Each key may send 240 requests a minute in total. Buying and topping up allow 30 a minute, new passwords and tests 10, IP lists 20. Past a limit the answer is 429 RATE_LIMITED; wait a minute and carry on.

Safe retries

Send an Idempotency-Key header with every purchase and top-up, such as your own order number. If the connection drops and you send the same request again with the same key, you get the first answer back and nothing is bought twice. Keys are 8 to 64 letters, digits, _ or -, and stay tied to the order for good.

Account

GET /account

Your balance, when you became a reseller and what you spent in the last 30 days.

{"success": true, "data": {
  "email": "you@example.com",
  "balance_cents": 25000,
  "reseller_since": "2026-11-07T18:00:00.000Z",
  "spend_30d_cents": 4200
}}

Products and prices

GET /products

Every proxy type on sale, with its host, ports, targeting options and your price. Per-GB products carry price_per_gb_cents; unlimited datacenter carries an options list of every length and speed with price_cents.

{"success": true, "data": [{
  "id": "residential", "name": "Residential", "billing": "per_gb", "delivery": "gateway",
  "host": "resi.proxies.boo", "port_http": 8080, "port_socks5": 1080,
  "targeting": {"country": true, "state": true, "city": true, "fixed_country": null},
  "username_format": "standard", "password_reset": true,
  "min_gb": 1, "max_gb": 500, "price_per_gb_cents": 165, "retail_per_gb_cents": 440, "available": true
}]}

GET /products/{id}/countries

The two-letter country codes a product can exit from.

POST /quote

The price of an order before you place it. For a new plan send product and gb (or duration and mbps). For a top-up send plan_id and gb (or days).

curl https://proxies.boo/api/v1/quote -H "Authorization: Bearer boo_YOUR_KEY" -H "Content-Type: application/json" \
  -d '{"product": "residential", "gb": 10}'

Plans

POST /plans

Buys a plan and pays for it from your balance. Fields: product; gb for per-GB products, or duration and mbps for unlimited datacenter; tag, optional, up to 64 characters of your own. Answers 201 with the order and the plan, 202 while a rare order is still being confirmed, or 402 when the balance is short.

curl https://proxies.boo/api/v1/plans -H "Authorization: Bearer boo_YOUR_KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: shop-order-1001" \
  -d '{"product": "residential", "gb": 5, "tag": "customer-42"}'
{"success": true, "data": {
  "order": {"id": "BPX7K2M9Q4", "kind": "new", "product": "residential", "label": "Residential, 5 GB", "price_cents": 825, "status": "fulfilled", "plan_id": 318},
  "plan": {
    "id": 318, "product": "residential", "label": "Residential, 5 GB", "tag": "customer-42", "status": "active",
    "created_at": "2026-11-07T18:20:11.000Z", "expires_at": null,
    "connection": {"host": "resi.proxies.boo", "port_http": 8080, "port_socks5": 1080, "username": "u8f3k2", "password": "Zx9vQ2mT", "ip_list": null},
    "traffic": {"unit": "GB", "gb": 5, "bytes_used": null, "bytes_total": 5000000000},
    "usage_read_at": null
  }
}}

An unlimited datacenter plan has no shared host: connection.host is null and connection.ip_list points at its list. Durations are 1_hour, 1_day, 7_days, 14_days, 30_days, 60_days and 90_days; the products endpoint says which are on sale at which speed.

GET /plans

Your plans, newest first. Filters: status (active, expired, used, cancelled), tag, product. Paging: limit (up to 200, default 50) and offset. Answers total, limit, offset and plans.

GET /plans/{id}

One plan with its login and a fresh usage reading. Usage is read again at most every few minutes; usage_read_at says when it was read.

POST /plans/{id}/extend

Tops up a running plan from your balance: gb for per-GB plans, days (1, 7, 14, 30, 60 or 90) for unlimited datacenter. The login stays the same. Accepts an Idempotency-Key.

curl https://proxies.boo/api/v1/plans/318/extend -H "Authorization: Bearer boo_YOUR_KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: shop-topup-2001" -d '{"gb": 10}'

POST /plans/{id}/password

Gives the plan a new password and answers the plan with it. The old password stops working within a minute. Not offered on every product: see password_reset in the products list.

POST /plans/{id}/tag

Sets or clears the tag on a plan. Send {"tag": "customer-42"}, or {"tag": null} to clear it.

POST /plans/{id}/test

Sends one request through the plan from our servers and answers ok, exit_ip, http_code and elapsed_ms. Optional: protocol (http or socks5) and username, which may carry targeting after the plan's own username.

GET /plans/{id}/proxy-list

Unlimited datacenter only: the plan's IPs as ip:port:username:password lines. Query: protocol (http or socks5), limit (1 to 20000, or all; default 100). Fetch it fresh when you need it.

Orders

GET /orders/{id}

The status of one order: fulfilled, review, failed or expired. Use it after a 202 answer: a reviewed order ends delivered, or with its price back in your balance, usually within 15 minutes.

Countries and sessions

Targeting goes in the username, exactly as for our own customers, so your customers can choose a country or keep one IP for a while without asking you. How the username works

Code samples

Python

import requests

API = "https://proxies.boo/api/v1"
HEAD = {"Authorization": "Bearer boo_YOUR_KEY"}

r = requests.post(f"{API}/plans", headers={**HEAD, "Idempotency-Key": "shop-order-1001"},
                  json={"product": "residential", "gb": 5, "tag": "customer-42"}, timeout=90)
body = r.json()
if not body["success"]:
    raise SystemExit(body["error"]["code"] + ": " + body["error"]["message"])
c = body["data"]["plan"]["connection"]
print(f"http://{c['username']}:{c['password']}@{c['host']}:{c['port_http']}")

Node.js

const API = 'https://proxies.boo/api/v1';
const head = { Authorization: 'Bearer boo_YOUR_KEY', 'Content-Type': 'application/json' };

const res = await fetch(API + '/plans', {
  method: 'POST',
  headers: { ...head, 'Idempotency-Key': 'shop-order-1001' },
  body: JSON.stringify({ product: 'residential', gb: 5, tag: 'customer-42' }),
});
const body = await res.json();
if (!body.success) throw new Error(body.error.code + ': ' + body.error.message);
const c = body.data.plan.connection;
console.log(`${c.host}:${c.port_http}:${c.username}:${c.password}`);

PHP

<?php
$ch = curl_init("https://proxies.boo/api/v1/plans");
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_TIMEOUT => 90,
  CURLOPT_HTTPHEADER => ["Authorization: Bearer boo_YOUR_KEY", "Content-Type: application/json", "Idempotency-Key: shop-order-1001"],
  CURLOPT_POSTFIELDS => json_encode(["product" => "residential", "gb" => 5, "tag" => "customer-42"]),
]);
$body = json_decode(curl_exec($ch), true);
if (!$body["success"]) die($body["error"]["code"] . ": " . $body["error"]["message"]);
$c = $body["data"]["plan"]["connection"];
echo $c["host"] . ":" . $c["port_http"] . ":" . $c["username"] . ":" . $c["password"];

Good habits

  • Store our plan id next to your own order, and send your order number as the tag. Support can then find any plan in seconds.
  • Always send an Idempotency-Key on purchases and top-ups, and allow up to 90 seconds for an answer.
  • Keep your balance topped up. Check balance_cents from /account before a busy day; a 402 answer charges nothing.
  • Use your own hostname if you like: a CNAME record such as proxy.yourbrand.com pointing at resi.proxies.boo works with the same ports.
  • Lock keys to your server's IPs and make one key per app, so you can revoke one without stopping the rest.

Need a hand? Open the chat bubble or email support@proxies.boo.