IPinfo API call
-
Hi Ben,
Great work on this plugin. I do have an issue, otherwise I would not use the support ticket 🙂
I also taken the liberty to sugges a fix. But this is just for your convenience.
—
## Problem
The IPinfo module uses theipinfo/ipinfoPHP library, which calls the **Legacy API** (https://ipinfo.io/{ip}) with a Bearer token. That Legacy endpoint has a **50,000 requests/month** limit for the free tier. Once that quota is exceeded, almost all requests return **429 Quota Exceeded** (e.g. 99% in weekly IPinfo reports).
IPinfo’s **free unlimited** tier is the **Lite API**:https://api.ipinfo.io/lite/{ip}?token={token}.
– Lite API docs: https://ipinfo.io/developers/lite-api
– Auth & URL structure: https://ipinfo.io/developers
– Free plan difference: https://ipinfo.io/faq/article/134-what-is-the-difference-between-using-the-authenticated-free-plan-and-just-the-public-api-with-no-account
**Expected:** Use the Lite API so that authenticated free-tier tokens get unlimited requests and no 429s from quota.
—
## Suggested fix
Call the Lite API directly withwp_remote_get(and optional persistent cache with transients) instead of the vendor that uses the Legacy URL.
### Example implementationphp<br><br><em>/**</em><br><br><em> * Get geolocation via IPinfo Lite API (unlimited for free tier).</em><br><br><em> * Do NOT use Legacy (ipinfo.io) – 50k/month limit → 429.</em><br><br><em> *</em><br><br><em> * @param string $ip IP address to look up.</em><br><br><em> * @param string $token IPinfo access token.</em><br><br><em> * @return array|false Normalized location array or false.</em><br><br><em> */</em><br><br>public static function get_geolocation( $ip, $token ) {<br><br> if ( empty( $token ) ) {<br><br> return false;<br><br> }<br><br> <em>// Optional: persistent cache (e.g. transient) to reduce API calls.</em><br><br> $cache_key = 'zerospam_ipinfo_' . md5( $ip );<br><br> $cached = get_transient( $cache_key );<br><br> if ( false !== $cached ) {<br><br> return $cached;<br><br> }<br><br> <em>// Correct: Lite API – unlimited for free accounts.</em><br><br> $url = 'https://api.ipinfo.io/lite/' . rawurlencode( $ip ) . '?token=' . rawurlencode( $token );<br><br> $response = wp_remote_get( $url, array( 'timeout' => 5 ) );<br><br> if ( is_wp_error( $response ) ) {<br><br> return false;<br><br> }<br><br> $code = wp_remote_retrieve_response_code( $response );<br><br> if ( 429 === (int) $code || 200 !== (int) $code ) {<br><br> return false;<br><br> }<br><br> $body = wp_remote_retrieve_body( $response );<br><br> $data = json_decode( $body, true );<br><br> if ( ! is_array( $data ) || empty( $data['country_code'] ) ) {<br><br> return false;<br><br> }<br><br> <em>// Normalize to existing log_record format: country = 2-letter code, etc.</em><br><br> $result = array(<br><br> 'country' => $data['country_code'],<br><br> 'region' => isset( $data['region'] ) ? $data['region'] : '',<br><br> 'city' => isset( $data['city'] ) ? $data['city'] : '',<br><br> 'postal' => isset( $data['postal'] ) ? $data['postal'] : '',<br><br> );<br><br> if ( ! empty( $data['loc'] ) ) {<br><br> $loc = explode( ',', $data['loc'], 2 );<br><br> if ( 2 === count( $loc ) ) {<br><br> $result['latitude'] = trim( $loc[0] );<br><br> $result['longitude'] = trim( $loc[1] );<br><br> }<br><br> }<br><br> <em>// Cache e.g. 14 days.</em><br><br> set_transient( $cache_key, $result, 14 * DAY_IN_SECONDS );<br><br> return $result;<br><br>}<br><br>
—
## API URLs reference
| Use case | Correct (Lite – unlimited) | Incorrect (Legacy – 50k/month) |
|———–|——————————————————|—————————————-|
| Lookup IP |https://api.ipinfo.io/lite/8.8.8.8?token=TOKEN|https://ipinfo.io/8.8.8.8(+ Bearer) |
| Auth |?token=TOKENin query string (or Bearer on Lite) | Bearer header on Legacy |
—
## References
– [IPinfo Lite API](https://ipinfo.io/developers/lite-api)
– [IPinfo Developers – Authentication & URL structure](https://ipinfo.io/developers)
– [Free plan vs public API](https://ipinfo.io/faq/article/134-what-is-the-difference-between-using-the-authenticated-free-plan-and-just-the-public-api-with-no-account)
You must be logged in to reply to this topic.