How to Implement Geographic Restrictions for SaaS Free Trials?

For SaaS founders and backend engineers, the "Free Trial" is a double-edged sword. While it is a primary driver for user acquisition, it is also a significant vector for platform abuse. One of the most effective, yet underutilized, methods for protecting your margins is geographic trial limiting.

Geographic limiting involves using IP intelligence to determine a user’s physical location during the signup process and applying logic to restrict or modify the trial offering based on that location. This article explains how geographic trial limiting works, how to implement it safely, and where common mistakes occur.

Limiting free trials by countries for new signups in SaaS apps

Why Restrict Free Trials by Geography?

Before diving into the implementation, it is important to understand the technical and business drivers behind this strategy:

What “Limiting Free Trials by Geography” Means

Limiting free trials by geography usually involves one or more of the following rules:

Importantly, this logic should never rely on user-supplied location data. Instead, it should be derived from the client’s IP address at the backend.

How Geographic Filtering Works Internally

Geographic filtering relies on IP Geolocation. Every device connected to the internet is assigned an IP address (IPv4 or IPv6). These addresses are allocated by Regional Internet Registries (RIRs) like ARIN or RIPE to Internet Service Providers (ISPs).

By maintaining a database of these allocations, an IP intelligence API can map an IP address to a physical location, including the country, region, city, and even the type of connection (e.g., residential vs. data center).

The Logic Flow

Practical Implementation with ip2geoapi.com

To implement this reliably, you need an API that provides low latency and high accuracy for both IPv4 and IPv6 addresses. ip2geoapi.com is a specialized service for this purpose, offering a generous 100,000 free requests per month, making it an ideal choice for startups and scaling applications.

  1. Capturing the User Data: In a Node.js/Express or Go environment, your first step is capturing the IP. If you are behind a proxy like Cloudflare or Nginx, ensure you are pulling the real client IP.

  2. The API Request: You can query the API using a simple GET request. Here is an example using curl:

curl "https://api.ip2geoapi.com/ip/116.98.8.7?key=YOUR_API_KEY"
  1. Analyzing the JSON Response: The API returns a structured JSON object. For trial limiting, we focus primarily on the countryCode and the security flags (if applicable).

Example Response:

{
  "success": true,
  "ip": "116.98.8.7",
  "version": "ipv4",
  "geo": {
    "city": "Ho Chi Minh",
    "country": "Vietnam",
    "countryCode": "VN",
    "region": null,
    "regionCode": null,
    "latitude": 16.1667,
    "longitude": 107.8333,
    "postalCode": null,
    "geonameId": 1562822,
    "accuracyRadius": 1000,
    "metroCode": null,
    "continentName": "Asia",
    "continentCode": "AS",
    "isEuMember": false
  },
  "countryInfo": {
    "name": "Viet Nam",
    "alpha2Code": "VN",
    "alpha3Code": "VNM",
    "flag": "https://api.ip2geoapi.com/assets/flags/vn.svg",
    "callingCodes": [
      "84"
    ],
    "currencies": [
      {
        "code": "VND",
        "name": "Vietnamese đồng",
        "symbol": "₫"
      }
    ],
    "languages": [
      {
        "iso639_1": "vi",
        "iso639_2": "vie",
        "name": "Vietnamese",
        "nativeName": "Tiếng Việt"
      }
    ]
  },
  "timezoneInfo": {
    "timezone": "Asia/Ho_Chi_Minh",
    "utcOffsetSeconds": 25200,
    "utcOffsetText": "+07:00",
    "utcOffsetHours": 7,
    "isDst": false,
    "abbreviation": "GMT+7",
    "localTime": "2026-01-19T11:51:35+07:00"
  },
  "network": {
    "cidr": "116.98.8.0/21",
    "prefixLen": 21,
    "asn": 24086,
    "asFormatted": "AS24086",
    "asName": "Viettel Corporation",
    "isp": "Viettel Group",
    "organization": "Viettel Group",
    "connectionType": "Cable/DSL",
    "mobile": {
      "mcc": null,
      "mnc": null
    }
  },
  "asDetails": {
    "asn": 24086,
    "abuser_score": "0.0048 (Low)",
    "descr": "VIETTEL-AS-VN Viettel Corporation, VN",
    "country": "vn",
    "active": true,
    "org": "Viettel Corporation",
    "domain": "viettel.com.vn",
    "abuse": "[email protected]",
    "type": "isp",
    "updated": "2013-12-11",
    "rir": "APNIC"
  },
  "security": {
    "isHosting": false,
    "isProxy": false,
    "proxyType": null,
    "isVpn": false,
    "vpnProvider": null,
    "vpnProviderUrl": null,
    "isTor": false,
    "isAnonymous": false,
    "trustScore": 100,
    "riskLevel": "low"
  }
}

Backend Logic Example (Node.js)

const axios = require('axios');

async function validateTrialEligibility(userIp) {
    const API_KEY = 'YOUR_API_KEY';
    const ALLOWED_COUNTRIES = ['US', 'CA', 'GB', 'AU', 'DE'];

    try {
        const response = await axios.get(`https://api.ip2geoapi.com/ip/${userIp}?key=${API_KEY}`);

        // Check if country is in the allowed list
        if (!ALLOWED_COUNTRIES.includes(response.geo.countryCode)) {
            return { 
                eligible: false, 
                reason: "Free trials are not available in your region. Please contact sales." 
            };
        }

        // Optional: Block known data centers to prevent bot abuse
        if (response.security.isHosting) {
            return { 
                eligible: false, 
                reason: "Trials are not permitted from data center networks." 
            };
        }

        return { eligible: true };
    } catch (error) {
        console.error("IP Lookup Failed", error);
        // Fail-safe: Allow trial if API is down, or implement strict block
        return { eligible: true }; 
    }
}

Pseudocode Example using BLOCKED_COUNTRIES

You can maintain a separate BLOCKED_COUNTRIES map that contains all the countries where you do not want to offer free trials. Block them instantly if the CountryCode matches this map.

response = lookup_ip(client_ip)

if response.geo.countryCode in BLOCKED_COUNTRIES:
    deny_trial("Trials not available in your region")

if response.geo.country_code not in FREE_TRIAL_COUNTRIES:
    require_payment_method()

allow_trial()

IPv4 vs IPv6 Considerations

Modern IP intelligence APIs support both IPv4 and IPv6. However:

Your logic should treat IPv4 and IPv6 uniformly, but your expectations around accuracy should be realistic, especially at city-level granularity.

Country-level detection is generally reliable for both. ip2geoapi.com supports both protocols natively, ensuring that your trial-limiting logic doesn't break for users on modern mobile networks or fiber connections that prioritize IPv6.

Common Pitfalls and Edge Cases

Implementing geographic restrictions is not a "set it and forget it" task. Developers should be aware of several technical hurdles:

1. VPNs and Proxies

Savvy users may use a VPN to appear as if they are in an "allowed" region. While basic geolocation tells you where the IP is registered, it doesn't always tell you if it's a proxy. For high-stakes SaaS products, you may want to cross-reference the ISP name; if it belongs to a known VPN provider (e.g., NordVPN, ExpressVPN), you should flag the signup for manual review.

2. IP Database Staleness

IP ranges change hands frequently. An IP that belonged to a US-based corporation last month might be assigned to a European ISP this month. Using a high-performance API like ip2geoapi.com mitigates this, as they handle the constant database updates on the backend, providing you with the most current data via a single endpoint.

3. Mobile Roaming

Users traveling abroad may have an IP address from their home country while physically being in another. Generally, it is best to treat the IP's origin as the "truth" for trial purposes, as it usually matches the user's billing and payment profile.

4. Over-Blocking

Rigidly blocking entire countries can turn away legitimate leads. Consider a "tiered" trial approach:

Performance and Security Considerations

When integrating an IP lookup into your signup flow, latency is king. You do not want a 2-second delay on your "Sign Up" button while waiting for a geolocation response.

Conclusion

Limiting free trials by geography is a practical and effective way to reduce abuse, control costs, and enforce business rules. When implemented correctly, it does not harm legitimate users and integrates cleanly into existing signup flows.

Key takeaways:

With careful implementation and realistic expectations, geographic trial limiting becomes a stable and maintainable part of your SaaS infrastructure.

Next Step: Sign up for a free API key and try running a few test lookups against your current user base to see where your traffic is actually coming from.

Vijay Prajapati
About the Author

Vijay Prajapati

I am a backend developer and founder of IP2GeoAPI, specializing in IP geolocation, network intelligence, and API architecture. I focus on building fast, accurate and scalable APIs for developers.

Connect on LinkedIn

Ready to Integrate?

Start using our IP geolocation & intelligence API in minutes. Sign up now and get your FREE API key with 100,000 monthly quota every month — no credit card required.

Join developers worldwide who rely on IP2GeoAPI for speed, accuracy, and reliability.