# What is an EndpointId in Iroh?

> Learn what an EndpointId is in Iroh. Discover how this unique cryptographic identifier uses Ed25519 public keys for secure peer-to-peer connections and network routing.

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

---

**An EndpointId in Iroh is the unique cryptographic identifier of an endpoint, implemented as a type alias for the Ed25519 public key that authenticates all peer-to-peer connections and enables secure routing across the network.**

The n0-computer/iroh distributed systems framework uses the EndpointId as the canonical identity primitive for every network participant. Derived directly from an endpoint's cryptographic keypair, this identifier ensures global uniqueness without centralized coordination and appears in all connection establishment flows, from direct peer dialing to relay-assisted NAT traversal.

## EndpointId Definition and Cryptographic Foundation

The **EndpointId** is fundamentally a type alias for the **PublicKey** structure. According to the iroh source code in [`iroh-base/src/key.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/key.rs) (lines 58-70), it is defined as:

```rust
pub type EndpointId = PublicKey;

```

The underlying `PublicKey` represents a compressed Ed25519 public key (specifically the compressed Y coordinate), providing 128-bit security and global uniqueness. Because the identifier derives from asymmetric cryptography, you can share it openly for routing purposes without exposing the private **SecretKey** used to prove ownership.

## How Iroh Generates the EndpointId

Endpoint generation occurs during the binding phase of the **Builder** API. When you invoke `Endpoint::builder().bind().await` in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs) (lines 24-27), the system executes the following sequence:

1. **Secret Key Generation** – If the user does not supply a secret key via `Builder::secret_key`, the system invokes `SecretKey::generate()` to create a cryptographically secure Ed25519 keypair.
2. **Public Key Derivation** – The builder calls `SecretKey::public()` to derive the corresponding public key.
3. **Identifier Assignment** – This public key becomes the endpoint's permanent **EndpointId**.

Once constructed, the `Endpoint::id()` method (defined in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs), lines 66-72) returns this identifier on demand:

```rust
pub fn id(&self) -> EndpointId {
    self.public_key()
}

```

## Working with EndpointId in Practice

Retrieving and displaying your endpoint's identifier requires only a few lines of Rust. The following example demonstrates creating an endpoint, extracting its **EndpointId**, and preparing to connect to a remote peer:

```rust
use iroh::{Endpoint, endpoint::presets};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Build endpoint with default configuration (generates fresh secret key)
    let ep = Endpoint::builder(presets::N0).bind().await?;
    
    // Retrieve the EndpointId (PublicKey)
    let id = ep.id();
    println!("My EndpointId: {}", id); // Hex-encoded public key
    
    // Form an EndpointAddr to dial a remote peer
    // let remote_id: iroh_base::EndpointId = ...;
    // let addr = iroh_base::EndpointAddr::from_parts(remote_id, vec![]);
    // let conn = ep.connect(addr, b"my-alpn").await?;
    
    Ok(())
}

```

The `Display` implementation for `PublicKey` renders the **EndpointId** as a hexadecimal string, making it easy to log, share, or serialize for discovery services.

## EndpointId in Network Addresses and TLS Verification

Every network-level address in Iroh explicitly includes the **EndpointId** to ensure cryptographic authentication during connection establishment. The `EndpointAddr` struct, defined in [`iroh-base/src/endpoint_addr.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/endpoint_addr.rs) (lines 42-46), couples the identifier with optional relay and direct IP addresses:

```rust
pub struct EndpointAddr {
    pub id: EndpointId,
    // ... relay and direct addresses
}

```

When establishing TLS connections, Iroh encodes the **EndpointId** into DNS names for certificate verification. The `iroh::tls::name` module (in [`iroh/src/tls/name.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/tls/name.rs)) handles this encoding, allowing the TLS stack to verify that the connecting peer actually possesses the private key corresponding to the expected **EndpointId**.

## Summary

- **EndpointId** is a type alias for `PublicKey` defined in [`iroh-base/src/key.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/key.rs), representing the compressed Ed25519 public key of an endpoint.
- Generation occurs automatically during `Builder::bind` in [`iroh/src/endpoint.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint.rs), deriving the identifier from a freshly generated or user-supplied `SecretKey`.
- The `Endpoint::id()` method provides runtime access to the identifier, which displays as a hex string via the `Display` trait.
- **EndpointAddr** structures always contain an **EndpointId** to ensure secure routing, and the identifier participates in TLS certificate verification via DNS name encoding.

## Frequently Asked Questions

### Is the EndpointId sensitive information?

No. The **EndpointId** is the public component of your cryptographic identity and is designed to be shared freely with other peers. Only the **SecretKey** (the private component) must remain confidential, as it proves ownership of the **EndpointId** and authorizes connections.

### How do I share my EndpointId with other peers?

You can serialize the **EndpointId** using its `Display` implementation to obtain a hexadecimal string, or use standard serialization libraries. Other peers need this identifier to construct an `EndpointAddr` when calling `Endpoint::connect` to reach your node.

### Can I reuse the same EndpointId across application restarts?

Yes, but only if you persist and reload the same **SecretKey**. The **EndpointId** is deterministically derived from the secret key; generating a fresh secret key (the default behavior when none is provided to the Builder) creates a new random **EndpointId**. To maintain a stable identity, use `Builder::secret_key` to supply a persisted secret key when constructing the endpoint.

### What is the relationship between EndpointId and EndpointAddr?

The **EndpointId** is the cryptographic identity component, while **EndpointAddr** is the complete network address that includes both the **EndpointId** and routing information (IP addresses or relay URLs). You cannot establish a connection with only an IP address; Iroh requires the **EndpointId** to authenticate the remote peer during the cryptographic handshake.