Hybrid and headless integration
A hybrid integration keeps the commercial control plane in your application and uses ProxyRequest as the proxy, provisioning, accounting, and analytics layer. The platform still needs mirrored users, packages, and orders because those resources are part of proxy authentication and every traffic record.
Ownership model
Section titled “Ownership model”| Your control plane owns | ProxyRequest owns |
|---|---|
| Customer identity and lifecycle | Mirrored platform user and access state |
| Product catalog and customer-facing pricing | Package configuration used by routing and targeting |
| Billing, subscriptions, and entitlements | Order, byte allowance, proxy password, and enforcement |
| Dashboard and customer workflows | Proxy generation, traffic accounting, analytics, and webhooks |
There is no native external_id passthrough that replaces platform IDs. Store the mapping in your database and use ProxyRequest IDs for every API request.
Mapping model
Section titled “Mapping model”Keep three mappings instead of putting every identifier in one user row:
| Mapping | Required fields | Constraint |
|---|---|---|
| Customer | Local customer ID, ProxyRequest user_id, sync status, timestamps | Both IDs unique inside one deployment |
| Product | Local product ID, ProxyRequest package_id, configuration version | Local product ID unique; package can be reused by many customers |
| Entitlement | Local subscription/order ID, local customer/product IDs, ProxyRequest order_id, last reconciled time | One active mapping per commercial entitlement |
Persist the returned ProxyRequest ID immediately after each successful create operation. Do not derive it from a username, email address, or display label.
The optional user meta object can carry a non-sensitive correlation value, but it is not an indexed external-ID contract and must not replace the local mapping.
Provisioning flow
Section titled “Provisioning flow”- Authenticate your backend with a static API key and keep it outside the browser.
- Configure package mirrors in the admin, read them through
GET /packages, and persist each local-product mapping. - On purchase or activation, create the mirrored sub-user with
POST /usersand the mappedpackage_id. - Store the returned
user_id, then readGET /users/{id}/ordersand persist the createdorder_id. - Load package-specific locations and call
POST /proxies/generatewith the mappeduser_idandpackage_id. - Return only the required gateway credentials to the customer-facing workflow.
- Process signed webhooks for prompt updates and reconcile closed reporting windows through analytics.
Create a mirrored user
Section titled “Create a mirrored user”The public contract requires username and password. Allocation values are integer bytes, not an implicit GB value.
import { createHmac, randomBytes } from 'node:crypto';
const opaqueCustomer = createHmac('sha256', process.env.MAPPING_SECRET) .update(localCustomer.id) .digest('hex') .slice(0, 24);
const response = await fetch('https://api.proxyrequest.com/api/v1/users', { method: 'POST', headers: { Authorization: `Static ${process.env.PROXYREQUEST_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ username: `customer-${opaqueCustomer}`, password: randomBytes(32).toString('base64url'), package_id: packageMapping.proxyrequestPackageId, data: 10 * 1024 ** 3, meta: { correlation: opaqueCustomer }, }),});
if (!response.ok) throw new Error(`Create mirrored user: ${response.status}`);const proxyRequestUser = await response.json();await mappings.insertCustomer(localCustomer.id, proxyRequestUser.id);{ "username": "customer-4d93b0e73a50f8847624ecf1", "password": "GENERATED_SERVER_SIDE_SECRET", "package_id": "550e8400-e29b-41d4-a716-446655440002", "data": 10737418240, "meta": { "correlation": "4d93b0e73a50f8847624ecf1" }}Use the exact request and response schemas in the API Reference. Do not copy a generated account password into logs or customer-visible analytics.
Generate credentials
Section titled “Generate credentials”Resolve local IDs before the API call:
local customer ──> ProxyRequest user_idlocal product ──> ProxyRequest package_idThen call POST /proxies/generate with both platform identifiers and the requested targeting, connection, and session objects. The generator does not accept local IDs and does not infer a package from your product name.
{ "user_id": "550e8400-e29b-41d4-a716-446655440001", "package_id": "550e8400-e29b-41d4-a716-446655440002", "quantity": 1, "targeting": { "country": "us" }, "connection": { "protocol": "http" }, "session": { "ttl": 3600 }}The session TTL requests sticky behavior in seconds and accepts 30 through 86400 in the current public contract. Omit session for rotating eligibility.
Analytics and reconciliation
Section titled “Analytics and reconciliation”Analytics filters also use platform identifiers:
user_idscopes usage to the mirrored customer;package_idscopes usage to the mapped product;ledger_idororder_id-related records distinguish purchase and allocation context where supported.
Translate the result back to local customers and products through the mapping layer before rendering it. Do not expose platform-wide IDs as your customer-facing identity model.
Webhooks are the prompt notification path, not the billing source of truth. Verify signatures, deduplicate deliveries, and reconcile a closed start/end/timezone window through GET /analytics/overall. Use feed, logs, domains, and transactions to explain differences.
Recover safely
Section titled “Recover safely”If a create or allocation call times out after the request was sent, do not immediately repeat it. Read the affected user or order, compare the observed state with the pending local operation, and escalate an ambiguous result. The public API does not promise universal idempotency for these writes.
Keep states such as pending, active, reconcile_required, and deprovisioning in the mapping record. Revoke access before deleting a mapping, and retain the accounting references required by your own audit policy.
For the complete direct reseller sequence, see reseller workflow. For API authentication and errors, see API fundamentals.