Developing an IP lookup function using an API

You’d have to use add_rewrite_rule so you can capture your desired url match and pass it on query_vars

Something like;

add_action('init', function() {
    add_rewrite_rule('ip/(.+)/?$','index.php?ip_search=$matches[1]','top');
});

add_filter( 'query_vars',  function( $vars ) {
    $vars[] = 'ip_search';
    return $vars;
});

dont forget to flush the rewrite rule once you added your own rule, change the permalink settings back and fort or just call the flush_rewrite_rules after the rule been added

Then the next step is how to handle if ip_search param is present in query var,

One option is to create a custom template inside your plugin,

e.i, your-plugin-name/some-folder/ip-lookup.php

Then you could use template_include and add your API related code inside that template.

Another option is to create a page without content, then query that page if your ip_search is present in query var and hijack the content using the_content filter and replace it with the output of your function

e.i.

// Query that page when ip_search query is present
add_action( 'wp', function() {

    global $wp_query, $post;

    if ( !isset( $wp_query->query['ip_search'] ) )
        return;
        
    $args=[
        'post_type' => 'page', 
        'p' =>  116, // The page ID you want to query if your custom rewrite rule is match
        'ip' => $wp_query->query['ip_search'], //pass in the ip just so you can capture on the_content filter
    ];
        
    $wp_query = new WP_Query( $args ); 
        
    $wp_query->is_single = false; //tell wordpress its a single page
    $wp_query->is_page = 1; // tell wordpress its a page
    $post = $wp_query->posts[0]; // assign first post to global $post
});

//Hijack the content if the query contains an IP
add_filter( 'the_content', function($content) {
    global $wp_query;

    if (  !isset( $wp_query->query['ip'] ) )
        return $content;
    // Call your function and pass the in the IP
    return ip_info_shortcode( $wp_query->query['ip'] );
});