Skip to content

Analytics and reconciliation

Analytics turns completed proxy activity into operational and commercial evidence. Use it to answer what consumed traffic, which destinations and targeting combinations were used, where failures occurred, and whether your local billing projection still matches the platform.

OBSERVABILITY MODELOne proxy session, different kinds of evidence
SUCCESSFUL COMPLETIONRequest snapshot → Analytics

Eligible completed requests become historical records: who used data, how much, where and through which route.

Feed · overall traffic · domains
WHILE TRAFFIC RUNSLive counters → Access state

Current users, package access and working balances support authorization. Live connection counters answer what is active now.

Connections
WHEN SOMETHING GOES WRONGDiagnostic events → Error logs

Warnings and failures carry their own status, error and request context. They are not successful request rows.

Logs

Accounting records are separate: orders and ledgers describe durable entitlements and usage. The optional transactions view is not a copy of the request feed.

Customer-facing dashboards and API operations expose usage, requests, destinations, active connections, and proxy errors. Operators can additionally inspect technical metrics, provider health, configured alerts, and incident history through deployment-level monitoring surfaces.

Distributed tracing is not provided. Correlate a customer report with request IDs, time windows, gateway context, analytics feed rows, and proxy error logs instead. Provider health and incident operations are operator-facing and should not be assumed to have the same public API coverage as customer analytics.

A historical request row is queued after successful completion, when analytics is enabled for the selected provider and the request has an authenticated user. The storage layer requires identity, client IP, destination and provider context. Writes are asynchronous and can fail: this is not a guarantee that every attempted request appears in the feed.

The current request record has 31 fields. The map below distinguishes what is stored from what the public GET /analytics/feed response exposes. “Not exposed” means absent from that public feed, not that the field is available through another customer endpoint.

Identity and purchased access

Stored fieldMeaningPublic feed
user_idAccount that authenticated the request.user_id
reseller_idReseller relationship attached to the request.reseller_id
package_idPackage used for access.package_id
package_slugPackage alias used by proxy authentication.Not exposed
ledger_idPurchased data bucket charged for this traffic, when present. A shared-pool child can consume a parent ledger.ledger_id
usernameProxy authentication username, including any targeting tokens.username

Traffic and time

Stored fieldMeaningPublic feed
request_idIdentifier for this request or tunnel.id
dataAccounted traffic in bytes, not a monetary amount or request-body size.data
established_connectionsConnection count captured with the record; not a live reading when you later query the feed.established_connections
timestampUTC time recorded on successful completion, at second precision.timestamp
dateUTC calendar date derived from that timestamp for storage organization.Not exposed

Client, gateway and destination

Stored fieldMeaningPublic feed
user_ipClient peer IP observed by the gateway.user_ip
server_ipProxy gateway server IP; not the destination-facing exit IP.server_ip
clusterGateway cluster identifier.Not exposed
hostnameDestination hostname. This row does not include URL paths, query strings, headers or bodies.hostname
protocolProxy protocol used for the request.protocol
methodMethod or tunnel operation recorded by the proxy.method

Selected upstream route

Stored fieldMeaningPublic feed
provider_idSelected upstream provider identifier.Not exposed
providerSelected upstream provider name.Not exposed
poolSelected routing pool.pool
pool_countryCountry from the selected pool configuration or eligible pool location.Not exposed
pool_regionRegion from the selected pool configuration or eligible pool location.Not exposed
pool_cityCity from the selected pool configuration or eligible pool location.Not exposed

Requested targeting

Stored fieldMeaningPublic feed
continentContinent targeting attached to the request.Not exposed
countryCountry targeting attached to the request.country
regionRegion targeting attached to the request.region
cityCity targeting attached to the request.city
asnRequested autonomous system number; stored as 0 when absent.asn

Sessions and restricted authentication context

Stored fieldMeaningPublic feed
session_idSticky-session identifier. The public feed exposes presence only, not the identifier.is_session (boolean)
session_keyInternal sticky-session key. Restrict access and redact before exports or support tickets.Not exposed
passwordProxy authentication password. This is a credential, not a dashboard dimension; restrict access and redact it.Not exposed

Requested country, region, city, continent and asn describe targeting. The separate pool_* fields describe a configured or selected pool location. Neither is an independent measurement of the exit IP’s location. Use an IP-check service through the proxy if you need to verify the observed exit.

Missing routing or session context can be empty. An unset ASN is stored as 0. The feed converts session presence to is_session; it does not return a session key. It returns ASN as a result field but does not offer an ASN query filter.

This request row does not store HTTP bodies, headers, a full destination URL, or elapsed request time. Performance metrics and warning/error logs are separate sources; do not infer those fields from the historical feed.

The internal record can include the proxy password and session key. These are restricted credentials, not fields to display in a customer dashboard. They are absent from the public feed. Apply least-privilege access, retention controls and redaction to internal exports as well.

Choose the view that answers your question

Section titled “Choose the view that answers your question”
QuestionEndpointReturned viewWhy it is useful
How many connections are active now?GET /analytics/connectionsUser, package, server IP, connection countCapacity dashboards, concurrency support, and detecting abandoned clients
How did traffic change over time?GET /analytics/overallTime buckets with bytes and request countUsage charts, anomaly detection, customer summaries, and closed-window reconciliation
Which destinations consume the most?GET /analytics/domainsHostname, requests, and bytesCost concentration, customer behavior, allow/block policy reviews, and abuse investigation
What happened on an individual request?GET /analytics/feedRequest-level identity, traffic, destination, protocol, pool, geo, ASN, and session dataReproducing routing behavior and explaining a customer’s traffic record
Why did requests fail?GET /analytics/logsStatus, proxy error code/message, identity, destination, geo, and timestampSupport triage, provider incident correlation, and retry-policy tuning
Which recorded transactions are available?GET /analytics/{id}/transactionsSender, recipient, type, amount, package, details, and timeInvestigating recorded movements when transactions are enabled; not a complete allocation, purchase or expiry journal

overall is the primary chart and reconciliation surface. It fills missing buckets with zeroes and returns both data and requests. Short windows use hour-level buckets; longer windows use daily buckets. Always store the requested start, end, and IANA timezone next to your own report so the same commercial period can be reproduced.

Use feed when you need evidence at request granularity and domains when you need a ranked aggregate. Feed rows can distinguish customers, packages, and ledgers; show the destination and client/proxy IPs; and explain the protocol, method, pool, targeting, ASN, and sticky-session usage associated with the byte count.

Domain aggregation is better for questions such as “which destinations generated 70% of traffic?” without downloading every request row. Treat destination hostnames as potentially sensitive customer data.

connections is an operational snapshot rather than a historical traffic report. Compare its per-server counts with package concurrency limits to distinguish real capacity pressure from a historical usage spike.

logs reads proxy warning/error records, not successful requests. Filter it by protocol, error code, package, ledger, account, or location where supported. Correlate a log row with feed data using time, request context, identity, and destination instead of exposing full proxy credentials in a support ticket.

Transactions describe data movements and consumption records with sender/recipient scope. For non-staff callers, sender and recipient filters are constrained to the authenticated account. This is not a complete journal of allocations, purchases or expiry, and it is not generated one-for-one from request rows. Use your operation journal for quota changes, overall for traffic and durable order/ledger state for usable balance.

Every analytics request is evaluated inside the authenticated account boundary:

  • a regular user can query only its own user_id;
  • a reseller can query its own user or one of its direct sub-users;
  • a reseller can add include_sub_users=true to overall or domains to aggregate its own activity with every direct sub-user;
  • a superuser can combine user_id with include_sub_users=true to aggregate a selected account and its direct sub-users;
  • platform administrators can use broader scopes, but customer integrations should not depend on administrative access.
Filter groupValuesTypical use
Reporting windowstart, end, timezoneReproducible billing and operational periods
Paginationlimit, offsetBounded feed, log, domain, and transaction exports
Commercial scopeuser_id, package_id, ledger_id, include_sub_usersOne customer, product, purchase pool, or aggregated reseller portfolio
Request detailshostname, protocolDestination investigation and HTTP/SOCKS comparison
Targetingcountry, region, cityInventory and routing-quality analysis
Failure and movementerror_code, sender_id, recipient_id, typeError clustering and allocation audits

Not every endpoint accepts every filter. Region requires country, and city requires country and region. Use the Analytics operations in the API Reference as the exact per-endpoint contract.

Use include_sub_users=true when a chart or destination report must represent a reseller as one commercial account. The option is available only on GET /analytics/overall and GET /analytics/domains.

For an authenticated reseller, omit user_id or pass the reseller’s own ID:

RequestGET /analytics/overall
curl 'https://{api_host}/api/v1/analytics/overall' \
--get \
--header 'Authorization: Static {api_key}' \
--data-urlencode 'timezone=UTC' \
--data-urlencode 'start=2026-09-01T00:00:00Z' \
--data-urlencode 'end=2026-09-01T01:00:00Z' \
--data-urlencode 'include_sub_users=true'
Response200 OK
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"timestamp": "2026-09-01T00:00:00Z",
"data": 1073741824,
"requests": 120
}
],
"timezone": "UTC",
"start": "2026-09-01T00:00:00Z",
"end": "2026-09-01T01:00:00Z"
}

Replace placeholders in braces with your values. Responses use synthetic example data.Install SDKsAPI reference →

A superuser must identify the account whose portfolio should be aggregated. JWT and static API-key authentication have the same scope rules:

RequestGET /analytics/domains
curl 'https://{api_host}/api/v1/analytics/domains' \
--get \
--header 'Authorization: Static {api_key}' \
--data-urlencode 'timezone=UTC' \
--data-urlencode 'start=2026-09-01T00:00:00Z' \
--data-urlencode 'end=2026-09-01T01:00:00Z' \
--data-urlencode 'user_id={user_id}' \
--data-urlencode 'ordering=-data' \
--data-urlencode 'include_sub_users=true'
Response200 OK
{
"next": null,
"previous": null,
"timezone": "UTC",
"start": "2026-09-01T00:00:00Z",
"end": "2026-09-01T01:00:00Z",
"results": [
{
"hostname": "example.com",
"data": 1073741824,
"requests": 120
}
]
}

Replace placeholders in braces with your values. Responses use synthetic example data.Install SDKsAPI reference →

The response shape does not change. overall sums every account into the existing time buckets; domains combines identical hostnames before ordering and pagination. Date, package, hostname, search, ordering, limit, and offset filters continue to apply to the combined data.

Historical activity remains attributable through the reseller relationship, so the aggregate includes traffic generated during the selected window by sub-users that have since been deleted. It does not add a per-user breakdown. Query an individual user_id without the option when you need a single account, and use feed or logs for request-level investigation.

For regular users the option is ignored. When a reseller selects one of its sub-users through user_id, the request remains scoped to that sub-user even if the option is present. A superuser request without user_id remains scoped to the authenticated superuser; it is not a global analytics query.

Protect gross margin

Compare traffic by customer, package, and destination with the commercial plan to identify costly workloads and plans priced below their usage shape.

Improve support

Move from “the proxy failed” to a bounded request, time, protocol, location, pool, and error code that engineering can reproduce.

Plan capacity

Combine active connections with traffic trends to detect concurrency saturation separately from byte-volume growth.

Reconcile resellers

Compare sub-user activity and transaction history with your local customer, allocation, invoice, and webhook projections.

Keep three sources separate: invoices describe purchases, your durable operation journal describes quota grants/reductions, and traffic analytics describes consumption. Current allocation writes produce administrative audit events; do not assume each one also appears in the optional legacy transactions feed. Expiration is another reason usable balance can fall without traffic.

For a finite root pool, reason about opening usable balance + purchased additions − all traffic charged to that pool − expired unused data, with any explicit corrections and accounting delay recorded separately. The root user’s own data_spent is not all shared-pool consumption. For a virtual child, REST remaining is max(assigned data - child usage, 0) and still depends on the parent pool. See the balance field map.

The public usable-ledger list cannot reconstruct a complete past expiration journal after buckets disappear. Persist the purchase/deadline context your own billing requires; do not label an unexplained balance decrease as customer traffic.

CLOSED-WINDOW CONTROL

Repair event-driven state with analytics

  1. Consume signed webhook batches

    Verify the raw body, deduplicate delivery, and update a provisional balance projection.

  2. Close one reporting window

    Persist its start, end, timezone, account scope, and package or ledger filters.

  3. Query aggregate traffic

    Read bytes and request counts after the selected window is complete.

    GET /analytics/overall
  4. Drill into differences

    Use transactions, feed, domains, and logs to find missing mappings, duplicate processing, or unexpected traffic.

  5. Correct and audit

    Repair the local projection and retain the source window and reason for every correction.