@proxyrequest/sdk
v4.1.0
Published
Official TypeScript SDK for the ProxyRequest public API.
Maintainers
Readme
ProxyRequest TypeScript SDK
The official TypeScript SDK for the ProxyRequest public API. It provides a typed, promise-based client for Node.js 22+ and modern browsers, with both ESM and CommonJS builds.
See analytics formats and compatibility for Unix timestamps, reporting windows, and feed identifiers.
What is ProxyRequest?
ProxyRequest is the control plane for operating a white-label proxy platform. It connects the commercial and operational pieces that a proxy provider or reseller would otherwise have to build separately:
- customer and sub-user accounts;
- packages, traffic allocations, connection limits, and proxy credentials;
- invoices, payment links, coupons, rewards, and reseller workflows;
- residential and static ISP proxy inventory, targeting, routing, and sticky proxy credentials;
- usage accounting, analytics, operational visibility, and webhooks;
- dashboard, branding, API automation, and Telegram integration.
This SDK talks to the management API at https://api.proxyrequest.com/api/v1. It is not itself an HTTP/SOCKS proxy client. The credentials returned by the proxy generation endpoints are used separately by your application, browser, scraper, or other proxy-aware software.
Start with the platform overview, then see API fundamentals and the API resource map.
Installation
npm install @proxyrequest/sdkpnpm add @proxyrequest/sdkyarn add @proxyrequest/sdkQuick start
import { ProxyRequestClient } from "@proxyrequest/sdk";
const client = ProxyRequestClient.withApiKey(process.env.PROXYREQUEST_API_KEY!);
const users = await client.users.list({ limit: 25, search: "[email protected]" });
for (const user of users.results) {
console.log(user.id, user.username);
}CommonJS is supported as well:
const { ProxyRequestClient } = require("@proxyrequest/sdk");Client is exported as a shorter alias for ProxyRequestClient.
Authentication
Static API keys are intended for trusted backend services:
const client = ProxyRequestClient.withApiKey(process.env.PROXYREQUEST_API_KEY!, {
language: "en",
timeoutMs: 15_000,
});Dashboard access tokens use Bearer authentication:
const client = ProxyRequestClient.withBearerToken(accessToken);Public login, signup, locations, and similar calls can use an anonymous client:
const client = ProxyRequestClient.anonymous();Never embed a Static API key or webhook secret in frontend JavaScript. Browser support is intended for anonymous or appropriately scoped end-user token flows. See the service documentation on authentication and API fundamentals.
Resource API
The client exposes 81 supported operations through 18 resource groups. The pinned
public schema contains 83 operations; the disabled sessions_list and
sessions_destroy operations are intentionally excluded from the SDK. Sticky
session options in proxy generation remain supported.
See backend compatibility and MFA for the updated login flow, variable response models, and migration notes.
client.apiKeys;
client.affiliates;
client.analytics;
client.authorization;
client.coupons;
client.invoices;
client.locations;
client.news;
client.orders;
client.packages;
client.profile;
client.providers;
client.proxies;
client.rewards;
client.settings;
client.telegram;
client.users;
client.webhooks;Method and option names use idiomatic camelCase. Request and response bodies preserve the API's snake_case JSON fields, so the values you inspect are exactly the values sent over the wire.
Create a managed user
const user = await client.users.create({
body: {
username: "customer_123",
password: "a-long-random-password",
is_reseller: false,
is_top_level: false,
package_id: "7ef79941-a099-4e4e-9282-a231bc683003",
},
});Read users and data for traditional and package-based account models.
Add data to a user's order
await client.users.addData({
id: user.id!,
body: {
package_id: "7ef79941-a099-4e4e-9282-a231bc683003",
data: 10 * 1024 ** 3,
},
});Create an invoice and payment link
const invoice = await client.invoices.create({
body: {
gateway: "stripe",
package_id: "7ef79941-a099-4e4e-9282-a231bc683003",
user_id: user.id,
data: 10 * 1024 ** 3,
},
});
const payment = await client.invoices.getPaymentLink({ id: invoice.id! });
console.log(payment.payment_url);Invoice creation is the normal API workflow for selling packages or topping up a user. Review reseller workflow and billing and growth before implementing checkout.
Generate proxy credentials
const generated = await client.proxies.generate({
body: {
package_id: "7ef79941-a099-4e4e-9282-a231bc683003",
user_id: user.id,
quantity: 5,
targeting: { country: "US" },
},
});
console.log(generated.proxies);See catalog and proxies and the separate proxy connection documentation.
Automatic retries and optimistic concurrency
The SDK automatically protects supported writes during up to three total
attempts after a network failure, or after 409 Conflict with a numeric
Retry-After of at most five seconds. Other HTTP errors are returned
immediately. This protection applies inside one running call. If the process
stops before saving the result, inspect the affected resource before submitting
another write:
const response = await client.invoices.createWithResponse({
body: { gateway: "stripe", package_id: packageId },
});
console.log(response.data.id, response.etag);Every generated method also has a WithResponse variant exposing statusCode,
headers, and etag.
Updates and deletes that declare If-Match accept the latest strong ETag:
await client.users.update({ id: userId, ifMatch: response.etag, body: changes });A stale value raises ApiError with kind === "precondition" and the current
server ETag in currentEtag. The SDK deliberately does not cache ETags: callers
choose which representation is being updated.
Pagination
List methods return the API page model. Use client.paginate() when you want a lazy async stream:
for await (const user of client.paginate(
({ limit, offset }) => client.users.list({ limit, offset, ordering: "-created" }),
{ limit: 100 },
)) {
console.log(user.username);
}The iterator follows next, rejects repeated pages, and stops after a configurable safety limit.
Errors
Every non-2xx API response and transport failure is normalized as ApiError:
import { ApiError } from "@proxyrequest/sdk";
try {
await client.users.get({ id: "missing-user-id" });
} catch (error) {
if (error instanceof ApiError) {
console.error(error.kind, error.statusCode, error.detail);
console.error(error.fieldErrors, error.requestId, error.retryAfter);
}
}Kinds include validation, authentication, permission, not_found, conflict, precondition, rate_limit, server, network, and unexpected. Supported writes receive bounded automatic retries for transient failures; tokens are never refreshed automatically. See common integration errors.
Per-request controls and custom Fetch
const controller = new AbortController();
await client.analytics.getOverall({
start: "2026-08-01",
end: "2026-08-31",
request: {
signal: controller.signal,
timeoutMs: 30_000,
headers: { "X-Correlation-ID": crypto.randomUUID() },
},
});Frameworks such as SvelteKit or test suites can inject their own Fetch implementation:
const client = ProxyRequestClient.withBearerToken(token, { fetch });Invoice PDFs
const download = await client.invoices.downloadPdf({ id: invoice.id! });
// Node.js
const { writeFile } = await import("node:fs/promises");
await writeFile(download.filename, download.content);
// Browser
const objectUrl = URL.createObjectURL(download.blob());FileDownload is deliberately filesystem-independent. It exposes content, filename, contentType, arrayBuffer(), blob(), and text().
Webhooks
Always verify the exact raw request body before parsing JSON:
import { WebhookVerifier } from "@proxyrequest/sdk";
const event = await WebhookVerifier.decodeVerifiedJson(
rawBody,
request.headers.get("X-Signature") ?? "",
process.env.PROXYREQUEST_WEBHOOK_SECRET!,
);Deliveries use standard padded Base64 HMAC-SHA256 over the raw body, without a signed timestamp. Verification accepts only this current format. It authenticates the body, but does not prevent replay: deduplicate usage events in your application. These helpers require SDK 2.0.0 or newer; version 1.0.0 does not support the current delivery format. See the webhook integration guide and event reference.
Raw requests
Use the escape hatch for a newly introduced endpoint that is not yet present in the generated resources:
const response = await client.request("POST", "/new-endpoint", {
query: { preview: true },
body: { example_field: "value" },
});It reuses base URL, authentication, language, timeout, cancellation, and ApiError behavior.
Types and generated code
All public OpenAPI model types are exported from both the package root and @proxyrequest/sdk/models:
import type { User, InvoiceCreateRequestRequest } from "@proxyrequest/sdk/models";Advanced consumers can import raw schema types:
import type { paths, operations } from "@proxyrequest/sdk/openapi";Generated files are committed for reproducible builds. Run npm run generate after replacing openapi/openapi.yaml; CI uses npm run generate:check to reject stale output.
Development
npm ci
npm run generate:check
npm run lint
npm run typecheck
npm test
npm run build
npm run validate:package
npm run test:packageThe repository also has a real Chromium smoke test via npm run test:browser.
More documentation
- Getting started
- Reseller workflow
- Errors and pagination
- Webhook verification
- Release process
- Full API reference
- Platform changelog
License
Reset remaining data (SDK 2.1.0+)
const order = await client.users.resetData({
id: userId,
body: { package_id: packageId },
idempotencyKey: resetOperationId,
});Send only package_id, without data. A system administrator can reset any user; other accounts can reset only their direct children. The server atomically clears positive, zero, or negative remaining data for a finite package and returns the updated order. Unlimited packages are rejected. Root orders lose their remaining ledger balances; child orders lose their remaining quota without changing the parent pool. Usage history and invoices are preserved.
Persist one operation ID and reuse it when retrying the same reset, including after a process restart. This prevents a repeated request from clearing a later top-up. Use subtraction when an explicit amount should be removed from a child quota. The backend must support the reset endpoint before calling it.
Version 2.1 retains legacy user and invoice models from 2.0 for compatibility with older deployments. These compatibility types do not change the current public API contract.
Provider data balances
Available since 4.1.0. Authenticate with a superuser JWT or an API key owned by an active superuser.
const page = await client.providers.listDataBalances({ limit: 20 });
for (const balance of page.results) {
console.log(balance.provider_name, balance.remaining_bytes, balance.history);
}Provider byte amounts are exact decimal strings, including history entries; calculated usage and remaining amounts can be null. The response includes observation and calculation times, freshness, errors, and recent checkpoint history. History is limited by the server's PROVIDER_DATA_BALANCE_HISTORY_LIMIT setting (default 10). Standard pagination applies to providers.
Country, region, and city methods also support includeAsns. Set it to true to populate nested ASN arrays; omitted or false uses the API's empty-array default.
