GET
https://jmpy.me/api/v1
/
analytics
/
geographic
/
:shortUrlId
Location Analytics
curl --request GET \
  --url https://jmpy.me/api/v1/analytics/geographic/:shortUrlId \
  --header 'Authorization: Bearer <token>'
{
  "data": [
    {
      "country": "<string>",
      "country_code": "<string>",
      "region": "<string>",
      "city": "<string>",
      "clicks": 123,
      "percentage": 123
    }
  ],
  "total_locations": 123
}
Get detailed geographic breakdown of clicks by country, region, and city.
For user-level location analytics across all your URLs, use the User Location Analytics endpoint.

Path Parameters

shortUrlId
string
required
Short URL identifier. Accepts:
  • UUID: 550e8400-e29b-41d4-a716-446655440000
  • Short code: abc123
  • Custom alias: my-custom-link

Response

data
array
Array of geographic location records.
total_locations
integer
Total number of unique locations tracked.

Request Examples

# Get location analytics by UUID
curl -X GET "https://jmpy.me/api/v1/analytics/geographic/550e8400-e29b-41d4-a716-446655440000" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Get location analytics by short code
curl -X GET "https://jmpy.me/api/v1/analytics/geographic/abc123" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Get location analytics by custom alias
curl -X GET "https://jmpy.me/api/v1/analytics/geographic/my-promo-link" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response Examples

{
  "success": true,
  "data": {
    "data": [
      {
        "country": "United States",
        "country_code": "US",
        "region": "California",
        "city": "San Francisco",
        "clicks": 534,
        "percentage": 11.8
      },
      {
        "country": "United States",
        "country_code": "US",
        "region": "New York",
        "city": "New York",
        "clicks": 489,
        "percentage": 10.8
      },
      {
        "country": "United Kingdom",
        "country_code": "GB",
        "region": "England",
        "city": "London",
        "clicks": 423,
        "percentage": 9.4
      },
      {
        "country": "Germany",
        "country_code": "DE",
        "region": "Berlin",
        "city": "Berlin",
        "clicks": 312,
        "percentage": 6.9
      },
      {
        "country": "Canada",
        "country_code": "CA",
        "region": "Ontario",
        "city": "Toronto",
        "clicks": 287,
        "percentage": 6.3
      }
    ],
    "total_locations": 127
  }
}

User-Level Location Analytics

Get aggregated location analytics across all your short URLs.

Endpoint

GET /analytics/user-locations

Query Parameters

days
integer
default:30
Number of days to include in analytics (1-365).

Request Example

curl -X GET "https://jmpy.me/api/v1/analytics/user-locations?days=30" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response Example

{
  "success": true,
  "data": {
    "data": {
      "countries": [
        { "country": "United States", "country_code": "US", "clicks": 8234, "percentage": 45.2 },
        { "country": "United Kingdom", "country_code": "GB", "clicks": 3456, "percentage": 19.0 },
        { "country": "Germany", "country_code": "DE", "clicks": 2134, "percentage": 11.7 },
        { "country": "Canada", "country_code": "CA", "clicks": 1567, "percentage": 8.6 },
        { "country": "Australia", "country_code": "AU", "clicks": 892, "percentage": 4.9 }
      ],
      "cities": [
        { "city": "New York", "country": "United States", "clicks": 1234 },
        { "city": "London", "country": "United Kingdom", "clicks": 987 },
        { "city": "San Francisco", "country": "United States", "clicks": 876 }
      ]
    }
  }
}
Geographic analytics may be restricted based on your plan. Free plans have limited access to location data. Pro and Enterprise plans have full access including city-level data.

Use Cases

Prepare location data for visualization on a world map.
async function getMapData(shortUrlId) {
  const response = await fetch(
    `https://jmpy.me/api/v1/analytics/geographic/${shortUrlId}`,
    { headers: { 'Authorization': 'Bearer YOUR_API_KEY' } }
  );
  const { data } = await response.json();
  
  // Group by country for country-level heatmap
  const countryData = {};
  data.data.forEach(loc => {
    if (!countryData[loc.country_code]) {
      countryData[loc.country_code] = {
        country: loc.country,
        code: loc.country_code,
        clicks: 0
      };
    }
    countryData[loc.country_code].clicks += loc.clicks;
  });
  
  // Convert to array sorted by clicks
  return Object.values(countryData)
    .sort((a, b) => b.clicks - a.clicks);
}
Analyze geographic distribution to identify your strongest markets.
import requests

def identify_target_markets(short_url_id, threshold=5):
    """
    Identify countries with >threshold% of traffic as target markets.
    """
    response = requests.get(
        f'https://jmpy.me/api/v1/analytics/geographic/{short_url_id}',
        headers={'Authorization': 'Bearer YOUR_API_KEY'}
    )
    
    locations = response.json()['data']['data']
    
    # Aggregate by country
    countries = {}
    total_clicks = sum(loc['clicks'] for loc in locations)
    
    for loc in locations:
        code = loc['country_code']
        countries[code] = countries.get(code, 0) + loc['clicks']
    
    # Identify target markets
    target_markets = []
    for code, clicks in countries.items():
        percentage = (clicks / total_clicks) * 100
        if percentage >= threshold:
            target_markets.append({
                'country_code': code,
                'clicks': clicks,
                'percentage': round(percentage, 1)
            })
    
    return sorted(target_markets, key=lambda x: -x['percentage'])
Compare performance across different regions for localization decisions.
interface RegionPerformance {
  region: string;
  totalClicks: number;
  topCities: Array<{ city: string; clicks: number }>;
}

async function compareRegions(shortUrlId: string): Promise<RegionPerformance[]> {
  const response = await fetch(
    `https://jmpy.me/api/v1/analytics/geographic/${shortUrlId}`,
    { headers: { 'Authorization': 'Bearer YOUR_API_KEY' } }
  );
  const { data } = await response.json();
  
  // Group by region
  const regions: Record<string, RegionPerformance> = {};
  
  data.data.forEach(loc => {
    const key = `${loc.country} - ${loc.region}`;
    if (!regions[key]) {
      regions[key] = {
        region: key,
        totalClicks: 0,
        topCities: []
      };
    }
    regions[key].totalClicks += loc.clicks;
    regions[key].topCities.push({ city: loc.city, clicks: loc.clicks });
  });
  
  // Sort cities within each region and return top regions
  return Object.values(regions)
    .map(r => ({
      ...r,
      topCities: r.topCities.sort((a, b) => b.clicks - a.clicks).slice(0, 3)
    }))
    .sort((a, b) => b.totalClicks - a.totalClicks);
}