# Complete Guide to iroh RPC API Endpoints: Binary QUIC Protocol Reference

> Discover the iroh RPC API endpoints. Learn how iroh utilizes a binary QUIC protocol with Connect, Announce, Lookup, Ping, StreamOpen, and Close messages for efficient communication.

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

---

**TLDR:** iroh does not expose traditional HTTP REST or JSON-RPC interfaces; instead, the public relay service communicates via a **binary QUIC-based protocol** featuring six core message types—**Connect**, **Announce**, **Lookup**, **Ping**, **StreamOpen**, and **Close**—implemented in the `iroh-relay` crate and defined in `noq-proto`.

The n0-computer/iroh project implements a peer-to-peer networking stack that replaces conventional HTTP APIs with a high-performance binary protocol. Understanding the **iroh RPC API endpoints** requires examining how clients and relay servers exchange protobuf-encoded messages over QUIC connections rather than traditional REST paths.

## Protocol Architecture: Binary QUIC vs. HTTP REST

Unlike typical cloud services that expose `/api/v1/` HTTP endpoints, iroh utilizes a binary protocol transported over QUIC. When a client connects to a relay, it performs a short handshake and exchanges binary-encoded messages defined by the `noq-proto` crate. These messages function as the functional RPC endpoints, carrying commands and data without HTTP overhead.

Because the transport is multiplexed on a single QUIC connection, a single logical endpoint can carry many streams—such as data channels and control channels—without requiring separate HTTP URLs.

## The Six Core iroh RPC API Endpoints

The protocol defines six primary message types that serve as the API surface between clients and the relay server.

### Connect (Client → Relay)

Opens a QUIC connection and negotiates the application-layer protocol (ALPN). This is the initial handshake that establishes the secure channel for subsequent RPC messages.

### Announce (Client → Relay)

Publishes the client’s public key (**EndpointId**) to the relay’s internal registry. This endpoint enables peer discovery by mapping EndpointIds to their current network addresses.

### Lookup (Client → Relay)

Queries the relay for the current network address(es) associated with a specific EndpointId. This powers the peer resolution mechanism, returning `RelayUrl` mappings stored by previous **Announce** calls.

### Ping (Client ↔ Relay)

Maintains connection liveness and measures round-trip latency. Bidirectional by design, this endpoint keeps NAT mappings open and provides health metrics.

### StreamOpen (Client ↔ Relay)

Creates a bidirectional QUIC stream for data transfer after the initial handshake. This endpoint multiplexes multiple logical channels over the single QUIC connection.

### Close (Client → Relay)

Gracefully terminates the connection, signaling the relay to release associated resources and remove temporary routing entries.

## Source Code Implementation

The logic handling these endpoints spans several key files in the n0-computer/iroh repository:

- **[`iroh-relay/src/main.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-relay/src/main.rs)**: Implements the relay server, parsing the binary protocol and dispatching each request type to appropriate handlers. The server routes **Announce** requests to update internal EndpointId-to-RelayUrl mappings and processes **Lookup** requests to return current address lists.
- **[`noq-proto/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/noq-proto/src/lib.rs)**: Contains the protobuf definitions for the binary message structs (**Connect**, **Announce**, **Lookup**, **Ping**, **StreamOpen**, **Close**). These definitions establish the wire format for all RPC communication.
- **[`iroh/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/lib.rs)**: Provides the core client implementation, including methods to build QUIC connections and transmit RPC messages. This file contains the client-side logic for `connect()`, `announce()`, and `lookup()` operations.
- **[`iroh-base/src/relay_url.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-base/src/relay_url.rs)**: Defines the `RelayUrl` type that clients use to specify relay server addresses and that the **Lookup** endpoint returns in its responses.

## Practical Code Examples

The following examples demonstrate how to interact with the iroh RPC API endpoints using the official Rust client library.

### Connecting to a Relay and Announcing

```rust
use iroh::client::{Client, Config};
use iroh_base::EndpointId;
use std::sync::Arc;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Load a configuration that contains the relay URL.
    let cfg = Config::load("example.config.toml")?;
    let client = Client::new(cfg).await?;

    // Connect to the relay (QUIC handshake happens under the hood).
    client.connect().await?;

    // Announce our public key so others can find us.
    client.announce().await?;

    // (optional) keep the connection alive.
    client.ping().await?;

    Ok(())
}

```

### Looking Up a Remote Peer

```rust
use iroh::client::Client;
use iroh_base::EndpointId;

async fn resolve_peer(client: &Client, id: EndpointId) -> anyhow::Result<Vec<String>> {
    // Ask the relay for the current network addresses of `id`.
    let addrs = client.lookup(id).await?;
    Ok(addrs)
}

```

### Server-Side Request Handling

```rust
use iroh_relay::server::Server;
use iroh_relay::protocol::{Request, Response};

async fn run_server() -> anyhow::Result<()> {
    let server = Server::bind("0.0.0.0:443").await?;
    while let Some(conn) = server.accept().await {
        tokio::spawn(async move {
            while let Some(req) = conn.next_request().await {
                match req {
                    Request::Announce { endpoint_id, .. } => {
                        // Store the mapping.
                        server.register(endpoint_id).await;
                        conn.respond(Response::Ok).await?;
                    }
                    Request::Lookup { endpoint_id } => {
                        let addrs = server.lookup(endpoint_id).await;
                        conn.respond(Response::LookupResult { addrs }).await?;
                    }
                    // …other request variants…
                    _ => {}
                }
            }
        });
    }
    Ok(())
}

```

## Summary

- iroh implements **iroh RPC API endpoints** as binary protobuf messages over QUIC, not HTTP REST.
- The six core message types are **Connect**, **Announce**, **Lookup**, **Ping**, **StreamOpen**, and **Close**.
- Client logic resides in [`iroh/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/lib.rs), while the relay server implementation lives in [`iroh-relay/src/main.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-relay/src/main.rs).
- Message definitions are located in [`noq-proto/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/noq-proto/src/lib.rs), establishing the wire format for all communication.
- All endpoints are accessed through the Rust client library rather than raw HTTP requests.

## Frequently Asked Questions

### Does iroh expose HTTP REST API endpoints?

No. According to the source code in [`iroh-relay/src/main.rs`](https://github.com/n0-computer/iroh/blob/main/iroh-relay/src/main.rs), iroh uses a binary QUIC-based protocol defined in `noq-proto`. There are no HTTP paths like `/api/v1/announce`; instead, clients send protobuf-encoded messages over established QUIC connections.

### How do I discover peer addresses using the iroh RPC API?

Use the **Lookup** endpoint. As implemented in the relay server, you call `client.lookup(endpoint_id).await` from [`iroh/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/lib.rs), which queries the internal mapping updated by **Announce** requests and returns a list of current network addresses.

### What crate contains the protocol definitions for iroh RPC endpoints?

The `noq-proto` crate contains the protobuf definitions. The file [`noq-proto/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/noq-proto/src/lib.rs) defines the binary structs for **Connect**, **Announce**, **Lookup**, **Ping**, **StreamOpen**, and **Close** messages that function as the API surface.

### Can I use curl or standard HTTP clients to call iroh RPC endpoints?

No. Because the protocol uses binary-encoded protobuf messages over QUIC rather than HTTP/1.1 or HTTP/2, you must use the iroh client library (or implement the binary protocol yourself). The connection requires QUIC handshake and ALPN negotiation as seen in [`iroh/src/lib.rs`](https://github.com/n0-computer/iroh/blob/main/iroh/src/lib.rs).