proxyrequest / php-sdk
Official PHP SDK for the ProxyRequest public API.
Requires
- php: ^8.5
- php-64bit: ^8.5
- ext-curl: *
- ext-hash: *
- ext-json: *
- ext-mbstring: *
- guzzlehttp/guzzle: ^7.15 || ^8.0
- guzzlehttp/psr7: ^2.8 || ^3.0
- psr/http-client: ^1.0
- psr/http-message: ^1.1 || ^2.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.0
- phpstan/phpstan: ^2.2
- phpstan/phpstan-strict-rules: ^2.0
- phpunit/phpunit: ^13.3
- symfony/yaml: ^8.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Official PHP 8.5 client for the ProxyRequest public API. The package covers 80 supported operations from the current OpenAPI contract, including users, orders, proxy generation, analytics, invoices, packages, locations, webhooks, API keys, and Telegram integration.
What is ProxyRequest?
ProxyRequest is a white-label proxy platform for operators and resellers that already have upstream proxy supply. It provides the product and control layer needed to turn that supply into a customer-facing service:
- managed HTTP, HTTPS, SOCKS5, and SOCKS5h gateways;
- packages, users, orders, proxy credentials, limits, and byte accounting;
- geographic and network targeting, sticky sessions, and multi-provider routing;
- customer and reseller dashboards, invoices, coupons, and payment flows;
- analytics, signed webhooks, API keys, and operational reporting.
You can use the complete managed backend and customer dashboard, or keep your own frontend, identity, and billing while ProxyRequest handles provisioning, routing, accounting, and analytics headlessly. You retain your brand, pricing, customer relationships, and upstream provider contracts.
ProxyRequest is not an upstream bandwidth plan. Provider traffic and contracts remain separate from the platform subscription. See the platform overview for the complete operating boundary.
How this SDK fits
The REST API is the control plane around proxy traffic. This SDK provisions resources and reads their state; customer proxy requests go to the managed gateway servers instead of passing through the SDK or REST API.
Your PHP backend ── HTTPS/JSON ──> ProxyRequest API
Customer traffic ── HTTP/SOCKS ──> Managed gateways ──> Destination
Keep the credentials for those paths separate: API keys belong only in trusted backend code, while generated proxy usernames and passwords are supplied only to the customer or workload that connects to a gateway.
The most important resource relationships are:
Customer purchase:
Package -> Invoice -> Paid invoice -> Order / data ledger -> Proxy credentials
Reseller provisioning:
Eligible root order -> Sub-user + child allocation -> Proxy credentials
Invoices describe commercial state. Orders and data ledgers describe service entitlement. Creating an invoice or returning from checkout is therefore not proof that proxy access is active.
Choose an integration path
| Scenario | Use this path |
|---|---|
| Built-in customer checkout | Select a package, create an invoice, obtain its payment link, confirm payment and entitlement, then generate proxy credentials. |
| Reseller-managed customer | Create a sub-user, assign a package and byte limit from an eligible root order, then generate credentials for that user. |
| Existing headless platform | Keep your own customer and billing records, persist mappings to ProxyRequest users/packages/orders, and provision through the API. |
For complete PHP examples, see purchase a package with an invoice and provision a reseller customer.
Installation
composer require proxyrequest/php-sdk:^2.0
The SDK requires 64-bit PHP 8.5 or newer. It includes Guzzle as the ready-to-use HTTP transport.
Quick start
<?php require __DIR__.'/vendor/autoload.php'; use ProxyRequest\Client; use ProxyRequest\Dto\UserCreateRequest; $client = Client::withApiKey($_ENV['PROXYREQUEST_API_KEY']); $profile = $client->profile()->get(); $user = $client->users()->create(new UserCreateRequest([ 'username' => 'customer-reference', 'password' => bin2hex(random_bytes(32)), ])); echo $user->getId();
Static API keys are sent as Authorization: Static YOUR_API_KEY. Never expose
them to browser code.
Common workflows
- Purchase a package with an invoice explains package selection, coupon previews, checkout, payment confirmation, entitlement checks, and credential generation.
- Provision a reseller customer explains sub-user creation, direct allocation, root-versus-child accounting, and credential generation when your application owns the billing flow.
Resource API
Client exposes 17 API groups. The pinned public schema contains 82 operations;
disabled sessions_list and sessions_destroy operations are intentionally
excluded. Sticky session options in proxy generation remain supported.
See backend compatibility and MFA for updated login examples and response-model migration notes.
$client->authorization(); $client->users(); $client->profile(); $client->orders(); $client->proxies(); $client->analytics(); $client->invoices(); $client->coupons(); $client->rewards(); $client->affiliates(); $client->packages(); $client->locations(); $client->apiKeys(); $client->webhooks(); $client->telegram(); $client->settings(); $client->news();
All operation parameters and return types are documented in the generated API resource reference and DTO model reference. IDs are opaque strings and byte amounts use 64-bit integers.
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:
$response = $client->webhooks()->createWithResponse( new \ProxyRequest\Dto\WebhookCreateRequest([ 'type' => \ProxyRequest\Dto\WebhookScopeEnum::USER, 'endpoint' => 'https://example.com/webhook', ]), ); echo $response->data->getEndpoint(); var_dump($response->etag());
Every generated method has a WithResponse variant exposing data,
statusCode, headers, and etag().
Operations that declare If-Match accept the latest strong ETag. A stale value
throws ApiException with ErrorKind::Precondition and exposes the current
server value through getCurrentEtag(). ETags are explicit response metadata
and are not cached by the SDK.
Pagination
List endpoints return their typed OpenAPI page model. Use paginate() when all
pages should be followed lazily:
$users = $client->paginate( fn (int $limit, int $offset) => $client->users()->list( limit: $limit, offset: $offset, ), limit: 100, ); foreach ($users as $user) { echo $user->getUsername(), PHP_EOL; }
Errors
HTTP failures throw ProxyRequest\ApiException. The original body and headers
remain available, together with normalized helpers:
use ProxyRequest\ApiException; use ProxyRequest\Exception\ErrorKind; try { $client->profile()->get(); } catch (ApiException $error) { if (ErrorKind::Authentication === $error->getErrorKind()) { // Replace the invalid API key or token. } $requestId = $error->getRequestId(); $fieldErrors = $error->getFieldErrors(); }
Supported writes receive bounded automatic retries for transient failures.
JWTs are never refreshed automatically; applications may call
$client->authorization()->refresh(...) explicitly. A manual access token can
be configured with Client::withBearerToken().
Configuration and custom deployments
$client = Client::builder() ->withApiKey($_ENV['PROXYREQUEST_API_KEY']) ->withBaseUri('https://customer-api.example/api/v1') ->withLanguage('uk') ->withTimeout(20, connectTimeout: 5) ->build();
An existing GuzzleHttp\ClientInterface can be supplied through
withHttpClient(). The generated resource layer forces http_errors=true so
documented 4xx responses follow the same exception contract with every client.
Invoice downloads
$pdf = $client->downloadInvoicePdf($invoiceId); $pdf->saveTo(__DIR__.'/'.$pdf->filename);
Webhook verification
Verify the exact raw request body before decoding it:
use ProxyRequest\Webhook\WebhookVerifier; $payload = WebhookVerifier::decodeVerifiedJson( $rawBody, $_SERVER['HTTP_X_SIGNATURE'] ?? '', $_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. WebhookVerifier::SIGNATURE_HEADER is X-Signature.
Platform documentation
- Platform documentation: capabilities, responsibility boundaries, deployment modes, and starting points.
- Integration overview: control-plane boundary and common API flows.
- API fundamentals and API resource map: authentication, errors, pagination, and resource relationships.
- Billing and growth: invoices, payment links, coupons, and entitlement reconciliation.
- Reseller workflow and users and data: sub-user provisioning and safe byte allocation.
- Catalog and proxy generation: packages, orders, locations, and credentials.
- Webhooks and usage accounting: event handling, root ledgers, child limits, and reconciliation.
- API Reference: exact endpoints, request schemas, responses, and examples.
Development
composer install make quality make generate-check
The vendored schema is pinned in openapi/source.json. To synchronize a newer
canonical schema, run make sync-openapi SOURCE=/path/to/openapi.yml. The sync
command records the upstream Git commit automatically. Then run make generate
and review the public API diff.
License
MIT
Reset remaining data (SDK 2.1.0+)
use ProxyRequest\Dto\ResetDataRequest; $order = $client->users()->resetData( $userId, new ResetDataRequest(['packageId' => $packageId]), $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.