# What Is the iroh API? A Complete Guide to Peer-to-Peer Networking in Rust

> Explore the iroh API, a Rust library for peer-to-peer networking. Discover how iroh simplifies QUIC networking with easy-to-use types for endpoints and builders.

- Repository: [number zero/iroh](https://github.com/n0-computer/iroh)
- Tags: api-reference
- Published: 2026-06-21

---

**The iroh API is a Rust library that provides a high-level, peer-to-peer networking stack built on QUIC, abstracting away hole-punching, relay fallback, address discovery, and TLS-based authentication behind ergonomic types like `Endpoint` and `Builder`.**

The iroh API serves as the public interface for the n0-computer/iroh repository, enabling Rust applications to establish secure, direct connections between devices across the internet without manual firewall configuration or complex infrastructure management. It exposes a concise set of methods that handle the underlying complexities of modern peer-to-peer communication while maintaining type safety and performance.

## Core Concepts of the iroh API

### Endpoint

The `Endpoint` is the central object representing a local iroh node. According to the source code in [`iroh/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/lib.rs) (lines 82-86), it owns the cryptographic key pair, manages socket bindings, handles address lookup, and controls the QUIC transport layer. All network operations flow through this type.

### Builder Pattern

Configuration follows a fluent `Builder` API defined in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs) (lines 22-30). This pattern allows you to set secret keys, ALPN protocols, relay modes, and custom transports before calling `bind()` to initialize the endpoint.

### Identity and Authentication

Each node is identified by an `EndpointId` (also referred to as `PublicKey`), which represents the public portion of the node's secret key. As documented in [`iroh/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/lib.rs) (lines 84-90), this identifier serves as both the network identity and the basis for TLS authentication, eliminating the need for traditional certificate authorities.

### Relay Infrastructure

When direct connectivity fails, the API falls back to `RelayUrl` endpoints. The default configuration uses the "number 0" relay (see [`iroh/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/lib.rs) lines 96-103), though custom relays can be specified via the builder to handle traffic forwarding when direct paths are unavailable.

### Address Lookup Services

The API supports optional address discovery mechanisms like DNS-based PKARR, documented in [`iroh/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/lib.rs) (lines 60-70). These services publish an `EndpointId` alongside reachable addresses, allowing peers to connect using only the cryptographic identifier without knowing IP addresses beforehand.

### QUIC Streams

Once connected, applications communicate through lightweight QUIC streams. The stream API in [`iroh/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/lib.rs) (lines 36-44) provides bidirectional (`open_bi`) and unidirectional (`open_uni`) variants that are inexpensive to create and can be multiplexed arbitrarily over a single connection.

## How the iroh API Establishes Connections

The connection process implemented in the iroh API follows a specific sequence that combines multiple networking techniques:

1. **Endpoint Construction** – Calling `Endpoint::builder(preset).bind().await` creates a `Builder`, applies a configuration preset (e.g., `presets::N0`), and binds sockets plus QUIC configuration. The logic in `Builder::bind` ([`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs) lines 24-30) generates a `SecretKey` automatically if none is supplied.

2. **Relay Discovery** – If a direct address is unknown, the endpoint contacts its home relay (default "number 0" as described in [`iroh/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/lib.rs) lines 97-104). The relay forwards encrypted packets based on the remote `EndpointId` until a direct path is established.

3. **Hole-Punching** – After the initial relay-mediated handshake, both endpoints attempt direct UDP connectivity via hole-punching techniques. As noted in [`iroh/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/lib.rs) (lines 66-73), successful hole-punching causes traffic to switch to the direct path, removing the relay from the data path.

4. **TLS Authentication** – Each endpoint authenticates the other by verifying the peer's public key (the `EndpointId`). According to [`iroh/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/lib.rs) (lines 81-89), no traditional client/server certificates are used; the secret key of each endpoint serves as both identity and TLS key material.

5. **Stream Creation** – With the QUIC connection ready, applications open streams via `Connection::open_bi` or `Connection::open_uni`. These methods, referenced in [`iroh/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/lib.rs) (lines 36-44), create inexpensive streams that can be opened at any time during the connection lifetime.

## Working with the iroh API: Code Examples

### Basic Endpoint Workflow

This example demonstrates creating an endpoint, connecting to a remote peer, and exchanging data over a bidirectional stream:

```rust
// 1️⃣ Build and bind an endpoint (using the default N0 preset)
let ep = iroh::Endpoint::builder(iroh::endpoint::presets::N0)
    .alpns(vec![b"my-alpn".to_vec()])   // accept this ALPN
    .bind()
    .await?;                            // ← binds sockets, creates QUIC config

// 2️⃣ Connect to a remote peer (you need the remote EndpointId)
let remote_addr = iroh::EndpointAddr::from_parts(
    remote_endpoint_id,                 // the peer’s public key
    None,                              // optional RelayUrl
    vec![]);                           // optional direct IPs
let conn = ep.connect(remote_addr, b"my-alpn").await?;

// 3️⃣ Open a bidirectional stream and exchange data
let (mut send, mut recv) = conn.open_bi().await?;
send.write_all(b"ping").await?;
send.finish()?;                       // finish sending side
let reply = recv.read_to_end(64).await?;
assert_eq!(&reply, b"pong");

// 4️⃣ Gracefully shut down
conn.close(0u32.into(), b"bye");
ep.close().await;

```

### Address Lookup with PKARR

This example shows how to enable DNS-based address discovery, allowing peers to find each other without sharing IP addresses:

```rust
use iroh::endpoint::presets::N0;
use iroh::address_lookup::DnsAddressLookup;

// Build an endpoint that publishes its ID via DNS (pkarr) and discovers peers
let ep = iroh::Endpoint::builder(N0)
    .address_lookup(DnsAddressLookup::default()) // enable DNS-based lookup
    .bind()
    .await?;

```

The `address_lookup` service publishes the endpoint's `EndpointId` together with any discovered external addresses, allowing other peers to dial using only the cryptographic identifier.

## Key Source Files in the iroh API

Understanding the repository structure helps when navigating the iroh API implementation:

- **[`iroh/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/lib.rs)** – Re-exports the public API (`Endpoint`, `RelayUrl`, etc.) and contains the high-level documentation describing architecture and usage patterns.
- **[`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs)** – Implementation of `Endpoint`, its `Builder`, connection logic, and public methods including `connect`, `accept`, and `add_external_addr`.
- **`iroh/src/socket/*.rs`** – Low-level transport and path-selection code handling IP transports, relay transports, and custom transport implementations.
- **[`iroh-base/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/lib.rs)** – Core types including `EndpointId`, `PublicKey`, `SecretKey`, and `RelayUrl`.
- **[`iroh-dns/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-dns/src/lib.rs)** – DNS resolver used for relay hostnames and PKARR address lookup services.
- **`iroh-relay/src/*`** – Relay server and client implementation that forwards encrypted traffic when direct connectivity fails.

## Summary

- The **iroh API** provides a Rust-native interface for peer-to-peer networking over QUIC, exposing high-level abstractions like `Endpoint` and `Builder`.
- **Identity is cryptographic**: Nodes use `EndpointId` (public keys) for both addressing and TLS authentication, eliminating certificate management overhead.
- **Automatic connectivity**: The API handles complex network traversal via relay fallback (`RelayUrl`) and automatic hole-punching, as implemented in [`iroh/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/lib.rs) lines 66-104.
- **Ergonomic configuration**: The `Builder` pattern in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs) enables fluent setup of ALPN protocols, relay modes, and address lookup services.
- **Lightweight streams**: QUIC streams are inexpensive to create and multiplex, accessible via `Connection::open_bi` and `Connection::open_uni`.

## Frequently Asked Questions

### What transport protocol does the iroh API use?

The iroh API uses **QUIC** as its underlying transport protocol, providing built-in encryption, multiplexing, and congestion control. This is implemented through the `Endpoint` type in [`iroh/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/lib.rs), which manages the QUIC configuration and socket bindings.

### How does the iroh API handle devices behind NAT or firewalls?

The iroh API automatically handles NAT traversal through a combination of **relay fallback** and **hole-punching**. When direct connectivity fails, traffic routes through a default or custom `RelayUrl` (as documented in [`iroh/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/lib.rs) lines 96-103). Simultaneously, both endpoints attempt UDP hole-punching to establish a direct path, switching traffic away from the relay once successful.

### What is the relationship between EndpointId and TLS certificates?

In the iroh API, the `EndpointId` (a public key) serves as the **TLS identity**. According to [`iroh/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/lib.rs) (lines 81-89), each endpoint uses its secret key to generate TLS key material during the handshake. Peers authenticate each other by verifying that the presented public key matches the expected `EndpointId`, eliminating the need for traditional X.509 certificate chains.

### Can I use custom relay servers with the iroh API?

Yes, the iroh API supports custom relay servers. While the default preset uses the "number 0" relay, you can configure alternative `RelayUrl` endpoints through the `Builder` API in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs). This allows deployment of private relay infrastructure or selection of geographically closer relay nodes.