wp_remote_get() returns 403 while file_get_contents() does not

Why do you have curly brackets in there?

Maybe sanitize/process the query string with htmlspecialchars() first. The error is complaining about non-standard characters…which is what your curly brackets are doing.

Build the query string with the $ip value, convert with htmlspecialchars(), then add the URL to the query string. Pass that variable to the wp_remote_get() function.