---
title: Concepts and terminology
description: Endpoint, endpoint ID, ALPN, transport address, relay, path, discovery, ticket — the vocabulary go-iroh uses.
icon: book
---

These are the terms the rest of the site assumes. Where a term belongs to the
iroh protocol rather than to Go, this page gives the Go spelling and links
upstream for the protocol definition.

## Endpoint

An endpoint is "a bound iroh node: it owns a secret key, a UDP socket, and the
QUIC transport used to dial and accept connections" (`iroh.Endpoint`'s doc
comment). It is created with `iroh.Bind` and closed with
`Endpoint.Shutdown` — there is no `Close` method and no `NewEndpoint`
constructor.

An `Endpoint` is safe for concurrent use.

## Endpoint ID

The public half of the endpoint's ed25519 key, spelled `key.EndpointID`. It is
the peer's name: everything else about an address is just a hint about how to
reach it.

Two textual forms appear in the tooling: 64 hex characters, and the
z-base-32 form produced by `EndpointID.Z32()`. The `iroh` command converts
between them.

> Upstream Rust iroh calls this a **NodeId** and its address a **NodeAddr**.
> go-iroh uses **EndpointID** and **EndpointAddr**. The wire encoding is the
> same; the Go names are not aliases of the Rust ones. This is the single most
> common source of confusion when reading upstream docs alongside Go code.

## Transport address and endpoint address

A `netaddr.TransportAddr` is one way to reach a peer. Three kinds ship:

| Kind | Go type | String form |
| --- | --- | --- |
| Direct IP | `netaddr.IPAddr` | `ip:127.0.0.1:4433` |
| Relay | `netaddr.RelayAddr` | `relay:https://use1-1.relay.iroh.network./` |
| Custom transport | `netaddr.CustomAddr` | `custom:…` |

A `netaddr.EndpointAddr` combines an endpoint ID with zero or more transport
addresses. Its doc comment states the rule: "To establish a connection both the
`key.EndpointID` and at least one path (a relay URL or a direct IP address) are
needed; an `EndpointAddr` with no addresses is still usable together with an
address-lookup service."

Build one with `netaddr.NewEndpointAddr(id)` and the `WithIP`, `WithRelayURL`,
and `WithAddrs` builders.

## ALPN

ALPN is Application-Layer Protocol Negotiation, the TLS extension that lets
peers agree which application protocol a QUIC connection carries. go-iroh
routes incoming connections to handlers by ALPN.

The Go API takes ALPN values as strings — TLS ALPN values are byte strings on
the wire, and Go strings preserve arbitrary bytes while keeping the common
printable-ASCII case simple. Protocol ALPNs in the ecosystem look like
`/iroh-gossip/1` or `n0/tracker/1`; pick a namespaced value for your own.

## Path

A path is a concrete network route in use by a connection: a direct UDP path
between two addresses, or a path through a relay. `Conn.Paths()` returns the
current set and `Conn.WatchPaths` observes changes. go-iroh's QUIC layer
supports multipath, so a connection can hold more than one at a time and
migrate between them — typically starting on a relay path and upgrading to a
direct path once hole punching succeeds.

## Relay

A relay is a public server that forwards packets between endpoints that cannot
yet (or ever) reach each other directly, and helps them discover their own
observed addresses. The `relay` package holds the public configuration types —
relay URLs grouped into a `Map`, per-relay `Config`, and a `Mode` selecting
which relays an endpoint uses. The client and wire protocol are internal.

See [Relays and discovery](relays-and-discovery), and upstream's
[relay documentation](https://docs.iroh.computer) for the protocol.

## Discovery / address lookup

Given only an endpoint ID, an address-lookup service answers "where is this
peer?". go-iroh calls the abstraction `AddressLookupServices` in the `iroh`
package, with pluggable `AddressPublisher` and `AddressResolver` halves.
Shipped backends: DNS, pkarr (signed DNS records published to a relay), static,
in-memory, and mDNS for local networks.

## Ticket

A ticket is the compact string form of an address for out-of-band sharing. An
endpoint ticket "starts with `endpoint` followed by lowercase base32 without
padding" (`endpointticket` package doc). The `blobs` package defines the
corresponding blob tickets.

## Wire compatibility

go-iroh's stated goal is wire compatibility with Rust iroh: the same QUIC,
TLS, relay, and protocol bytes, not a shared codebase. The README describes the
module as "a clean-room Go port targeting wire compatibility with upstream Rust
iroh. It is not affiliated with the n0 team."

What is mechanically proven, and by which test gate, is covered in
[Testing and interop](testing-and-interop).

## Next steps

- [How go-iroh works](architecture) — how these pieces fit together at runtime.
- [Endpoints and connections](endpoints-and-connections) — the API that uses
  this vocabulary.
- [API map](api-map) — which package holds which type.
