| Crates.io | myip-foo |
| lib.rs | myip-foo |
| version | 1.0.0 |
| created_at | 2025-11-24 13:34:04.340133+00 |
| updated_at | 2025-11-24 13:34:04.340133+00 |
| description | Official Rust client for myip.foo - free IP lookup API with geolocation |
| homepage | https://myip.foo |
| repository | https://github.com/virtualox/myip-packages |
| max_upload_size | |
| id | 1947826 |
| size | 56,143 |
Official Rust client for myip.foo - a free, privacy-focused IP lookup API.
Add to your Cargo.toml:
[dependencies]
myip-foo = "1.0"
tokio = { version = "1.0", features = ["full"] }
use myip_foo::{get_ip, get_ip_data};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Get plain IP
let ip = get_ip().await?;
println!("IP: {}", ip);
// Get full data with geolocation
let data = get_ip_data().await?;
println!("IP: {}", data.ip);
println!("City: {}", data.location.city);
println!("Country: {}", data.location.country);
println!("ISP: {}", data.network.isp);
Ok(())
}
get_ip() -> Result<String>Returns your IP address as plain text.
get_ip_data() -> Result<IpData>Returns full IP data including geolocation.
get_dual_stack() -> Result<DualStackData>Returns both IPv4 and IPv6 addresses using dedicated endpoints.
get_connection_type() -> Result<ConnectionTypeData>Detects if connection is residential, VPN, or datacenter.
get_headers() -> Result<HashMap<String, String>>Returns all HTTP headers as seen by the server.
get_user_agent() -> Result<String>Returns your user agent string.
pub struct IpData {
pub ip: String,
pub ip_type: String, // "IPv4" or "IPv6"
pub hostname: Option<String>,
pub connection_type: Option<String>, // "residential", "vpn", "datacenter", "tor"
pub location: Location,
pub network: Network,
pub cloudflare: Cloudflare,
}
pub struct DualStackData {
pub ipv4: Option<String>,
pub ipv6: Option<String>,
}
pub struct ConnectionTypeData {
pub ip: String,
pub connection_type: String, // "residential", "vpn", "datacenter", "unknown"
}
use myip_foo::get_dual_stack;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let dual = get_dual_stack().await?;
if let Some(ipv4) = dual.ipv4 {
println!("IPv4: {}", ipv4);
}
if let Some(ipv6) = dual.ipv6 {
println!("IPv6: {}", ipv6);
}
Ok(())
}
use myip_foo::get_connection_type;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let conn = get_connection_type().await?;
println!("Connection: {} ({})", conn.connection_type, conn.ip);
Ok(())
}
The get_dual_stack() function uses dedicated subdomains:
ipv4.myip.foo/ip - Returns IPv4 only (A record)ipv6.myip.foo/ip - Returns IPv6 only (AAAA record)myip.foo does not log IP addresses or use cookies. See Privacy Policy.
MIT License - see LICENSE for details.