The hardest part of running a trial is taking access back when the trial ends. Customers do not voluntarily turn off something that still works, and if your enforcement is manual you will forget. Nodetonet solves this with a single field: give any Proxy Client an expires_at timestamp and access dies at that exact second — no cron job, no reminder, no apology email.
This guide explains how expiry works mechanically, the three practical use cases it covers, how to stack it with a bandwidth quota for the classic trial pattern, and how to extend or revoke access programmatically.
How Proxy Client expiry works
A Proxy Client is a named set of credentials (username + password) that you issue under one of your rotating proxy or mobile proxy groups. Each client can carry independent limits: a bandwidth quota, a thread cap, an IP allowlist, a domain allowlist, and — relevant here — an expiry timestamp.
The timestamp is stored in UTC and enforced to the second. There is no rounding to midnight or "end of business" — if you set 14:32:11 on a Tuesday, that client stops working at precisely 14:32:11 on that Tuesday, regardless of the time zone the customer is in.
At the moment of expiry two things happen simultaneously:
- Every open tunnel for that client is closed. Mid-request, mid-stream — active sockets receive a clean TCP FIN. The client's current download or API call terminates immediately.
- New connections are refused. HTTP clients receive
407 Proxy Authentication Required; SOCKS5 clients receive an auth failure during the greeting handshake.
From the customer's perspective the proxy "stopped accepting their password." If they contact you, you can verify the expiry date, remaining quota and credentials in one glance at the Proxy Clients table — no need to dig through logs.
Setting an expiry — step by step
Open any proxy from the /proxies page and scroll to the Proxy Clients section. Click Add Client or the edit icon on an existing one. The form contains an Expires at datetime picker:
- Leave it empty for a permanent credential that never auto-expires.
- Pick any future datetime to cap that client's lifetime.
Save and the enforcement begins immediately. If you are automating client creation via the REST API, pass expiresAt as an ISO-8601 UTC string in your POST /api/v1/rotating-proxies/:id/clients body. See your first REST API call and programmatic proxy creation in Python for working examples.
The three canonical use cases
1. Free trials
A prospect signs up. You create a Proxy Client with expires_at = now + 7 days and no quota. They get a full week to test the product without any further action from you. Convert them or do nothing — at day 7 they are out, automatically. This works identically whether you are self-serving via your own UI or issuing clients through the reseller / white-label workflow.
2. Sales demos
A 30-minute demo deserves a 60-minute credential. Set expires_at = now + 1 hour, hand it to the prospect, and the credential evaporates while you are still in the follow-up call. Nothing to revoke later, no leaked test credentials lingering in someone's .env file forever. For extra safety, add a low thread cap (5–10) so the demo credential cannot be used to scrape anything large during that hour.
3. Subscription enforcement
Your billing layer (Stripe, WISECP or a custom system) charges customers monthly or annually. Set expires_at to the end of their paid period. On successful payment, extend it; on failure or cancellation, leave it alone. No middleware needed to "pause" a delinquent customer — they pause themselves the moment the billing cycle lapses. This keeps your panel as the single source of truth and removes the risk of a race condition between your billing webhook and a separate suspend API call.
Nodetonet already integrates with WISECP for white-label reselling, so if you are building a proxy reseller business the expiry field maps directly to your WISECP product period.
The "1 GB or 7 days, whichever first" pattern
Limits on a Proxy Client are AND-ed, not OR-ed: a connection is only allowed if every active limit is satisfied. This means you get the classic trial gate for free by combining quota and expiry:
| Field | Value | Effect |
|---|---|---|
quota | 1073741824 bytes (1 GiB) | Cuts off after 1 GB of data transfer |
expires_at | now + 7 days | Cuts off after 7 calendar days |
threads | 20 | Limits to 20 concurrent connections (drain-proof) |
The trial ends the instant either limit is hit. A heavy user gets cut at 1 GB on day 2; a light user gets cut on day 7 having barely touched 200 MB. Both groups have had a fair taste of the product, neither has been able to extract unlimited value, and both are warm for a follow-up conversion call.
Thread cap tip: adding a limit of 10 or 20 concurrent connections makes your trial resistant to a malicious user who tries to drain the quota as fast as possible. See thread limits per client for the full guide.
If your use case is purely quota-based with no time limit, the quota limits per client guide covers that in detail. If you also need to control which domains the credential can reach, read domain restrictions.
Extending or removing an expiry
Edit the client in the Proxy Clients table and either:
- Bump the date to a later moment — the change takes effect on the very next connection attempt.
- Clear the field entirely — the client becomes permanent again immediately. No toggle to flip separately.
If the client is already past expiry, clearing or extending the field reactivates it at once — there is no separate "re-enable" step. You can also delete the client entirely, which immediately closes all tunnels and removes the credential from any cache. Deletion is permanent; if you might need to reinstate the client later, extend instead of delete.
Automating expiry via the API
If you run your own billing on top of Nodetonet, programmatic expiry management is the natural integration point. A Stripe customer.subscription.updated webhook can call the Nodetonet REST API to push the new expiresAt on every successful renewal, and do nothing (letting expiry handle the block) on a failed charge.
The relevant endpoints are:
POST /api/v1/rotating-proxies/:id/clients— create withexpiresAtPUT /api/v1/rotating-proxies/:id/clients/:clientId— updateexpiresAt(or set tonullto remove)
Both require a bearer token from your API key. All timestamps are ISO-8601 in UTC. See per-customer proxy clients for the full multi-tenant reselling pattern including how to scope each customer to their own credential set.
Comparing limit types
Proxy Clients support four independent enforcement mechanisms. They all AND together:
| Limit type | Field | What it controls | Guide |
|---|---|---|---|
| Expiry | expires_at | Calendar time — credential dies at a moment | This post |
| Bandwidth quota | quota | Total bytes transferred through the client | Quota limits |
| Concurrency | threads | Max simultaneous open connections | Thread limits |
| Source IP | ipAllowlist | Which client IPs may authenticate | IP allow/deny lists |
For most trial setups, combining expiry + quota + thread cap is sufficient. Add an IP allowlist if you need to lock a credential to a specific machine or office.
What is next
- Quota limits per client — the byte cap that pairs naturally with expiry.
- Thread limits per client — concurrency caps for noisy-neighbour protection.
- Per-customer proxy clients — the full reselling and multi-tenant pattern.
- Rotating proxies on Nodetonet — see the full feature set these clients sit on top of.