How to Add IP Geolocation to RudderStack transformations with ipdata

By Max Werner

On Jun 19, 2023

CDP
Cloud Technologies
Tutorial
photo of a map with pushpins in it

Getting Started

We'll be using an API endpoint from ipdata.co. I should note here that ipdata is not a sponsor and has in no way paid to be highlighted here. I have used the service in the past and found it both affordable ($30 / month for 10,000 daily requests at the time of writing) and easy to use. They also have a free tier of 1,500 daily requests to test things out.

Once you've signed up, you will get your API key and that's all we need!

Client-Side vs. Server-Side Enrichment

While you can use the ipdata API client side, it has some extra hoops to jump through and security considerations that are out of scope for this article. We will therefore stick to using a RudderStack transformation to enrich our events server-side. This way our API key stays secure, we are more safe from abuse, and don't have any impact on client performance.

RudderStack Transformations Setup

Even though not shown in live-events or the RudderStack provided sample, there is a event.request_ip property present in RudderStack payloads. We can therefore add our enrichment function quite easily:

async function enrichIP(ip){
    const IPDATA_KEY = '<<YOUR_KEY_HERE>>';
    const res = await fetch(`https://api.ipdata.co/${ip}?api-key=${IPDATA_KEY}`)
    const { is_eu, city, region, region_code, region_type, country_name, country_code, contintent_name } = res;
    return { is_eu, city, region, region_code, region_type, country_name, country_code, contintent_name };

}

export async function transformEvent(event, metadata) {
    const { request_ip } = event;
    if ( request_ip ) {
        const enrichment = await enrichIP(request_ip);
        event.properties = {...event.properties, ...{enrichment}}
    }
    return event;
}

As I mentioned above, the event.request_ip is present in real events, even if you don't see them in the live event viewer. Therefore, in order to test the enrichment, simply add a request_ip property to the event tester like this:

RudderStack Transformation Tester Screenshot

We can see our enrichment data added to the event payload in the output:

RudderStack Transformation Output Screenshot

Next Steps and Considerations

While this demo is perfectly functional, it is far from production ready. There are a number of things that should be improved before deploying this into a production environment. A few things to consider are:

  1. Transformations run per destination, meaning if you need to send enrichment data to multiple destinations you might want to enrich client-side, move the enrichment function to a function library so you can just import and reuse it, etc.
  2. There is no error checking done here. The call to ipdata.co could fail for any number of reasons and you should make sure your transformation doesn't break if that happens.
  3. You'll likely want to limit which events you want to enrich since you have a certain daily limit for ipdata.co's service. For example, consider only running the enrichment function for the first page call of a new session (e.g. when event.context.sessionStart is true) or for important track events or identify calls.
  4. I cherry picked a few properties from the ipdata response to use here. Ipdata.co offers a lot more data than this and you can find those details here.
  5. As good as any IP Geolocation data can be, I recommend not using data that is any more granular than the state/province/region level. Especially on mobile devices, this can be far from accurate! You can see "my city" in the above screenshot and that is not actually where I live ;)

As always, if you'd like to know more or get some assistance in enhancing your data collection, feel free to send us a message and we'll be happy to get back to you!

© 2024 Obsessive Analytics Consulting. All rights reserved.