---
title: "Get the domain from a URL in C#"
url: https://recursiveai.org/onecontact/cookbook/get-domain-from-url/
description: "Get a registrable domain and public suffix from a URL in C# using OneContact, including multi-part suffixes such as co.uk."
version: "1.0.0"
---

# Get the domain from a URL in C#

**OneContact** is a free, open-source contact data library for .NET from Recursive AI. MIT or Apache-2.0, no native dependencies, no network access.

[NuGet](https://www.nuget.org/packages/RecursiveAI.OneContact) · [GitHub](https://github.com/recursive-ai-oss/onecontact-csharp) · [Docs](https://recursiveai.org/onecontact/docs/) · [Download example (.zip)](https://recursiveai.org/onecontact/cookbook/get-domain-from-url/get-domain-from-url.zip)

Use the Public Suffix List to get the registrable domain—the public suffix plus the label before it—rather than guessing from the last two parts of a hostname.

```shell
dotnet add package RecursiveAI.OneContact
```

Requires [.NET 10](https://dotnet.microsoft.com/download/dotnet/10.0) (net10.0); .NET 9 and earlier aren’t supported.

```csharp
using RecursiveAI.OneContact;

var url = WebAddress.Parse(
    "https://shop.example.co.uk/cart");
Console.WriteLine(url.RegistrableDomain);
```

```text
example.co.uk
```

Unzip [the example](https://recursiveai.org/onecontact/cookbook/get-domain-from-url/get-domain-from-url.zip), then `dotnet run`.

## Full program

The download includes a fuller example with invented input embedded in `Program.cs`:

```csharp
using RecursiveAI.OneContact;

var url = WebAddress.Parse("https://shop.example.co.uk/cart");
Console.WriteLine(url.Host);
Console.WriteLine(url.PublicSuffix);
Console.WriteLine(url.RegistrableDomain);
```

`dotnet run` prints:

```text
shop.example.co.uk
co.uk
example.co.uk
```

An invalid URL makes `Parse` throw `ContactParseException`; `RegistrableDomain` is null for IP hosts and hosts that are themselves public suffixes.

## Variations

Choose whether private suffixes count:

```csharp
using RecursiveAI.OneContact.Web;

Console.WriteLine(PublicSuffixList.GetRegistrableDomain(
    "ada.github.io"));
Console.WriteLine(PublicSuffixList.GetRegistrableDomain(
    "ada.github.io", includePrivateSection: false));
```

```text
ada.github.io
github.io
```

## Related recipes

- [Extract contact information from HTML in C#](https://recursiveai.org/onecontact/cookbook/extract-contacts-from-html/)
- [Parse a URL in C#](https://recursiveai.org/onecontact/cookbook/parse-url/)
- [Parse a postal address in C#](https://recursiveai.org/onecontact/cookbook/parse-postal-address/)
- [Format a postal address by country in C#](https://recursiveai.org/onecontact/cookbook/format-postal-address/)

## The short answer

Parse the URL with `WebAddress.Parse` and read `RegistrableDomain`. For `https://shop.example.co.uk/cart`, the host is `shop.example.co.uk`, the public suffix is `co.uk`, and the registrable domain is `example.co.uk`. Taking only the last two labels would incorrectly produce `co.uk`.

OneContact ships a pinned Public Suffix List and performs the lookup locally. The public suffix is the part under which registrations are organized; the registrable domain adds the label immediately to its left. The [Public Suffix List documentation](https://recursiveai.org/onecontact/docs/psl/) explains the shipped data and lookup rules.

## How do I get just the domain name from a URL in C#?

First decide which meaning of “domain” your feature needs. `Host` is the complete hostname, including subdomains. `PublicSuffix` is the suffix recognized by the list. `RegistrableDomain` is the base registration unit for that suffix. Print all three while building an importer so that the intended boundary is visible.

Use the host when a specific subdomain matters, such as separate service endpoints. Use the registrable domain when grouping website addresses at a broader domain boundary. Neither answer identifies the legal owner of a website. One company can operate several domains, and several organizations can share hosting infrastructure.

The URL wrapper also handles removing the scheme, port and path before consulting the list. Do not pass an entire URL directly to the hostname-only `PublicSuffixList` methods. Those methods expect a domain name and return null for input containing URL punctuation such as a slash or colon.

## How do I get a domain without the subdomain in C#?

Use `RegistrableDomain`, not a rule that simply strips `www.`. Hosts can have arbitrary subdomain labels, and suffixes can contain more than one label. The list also has wildcard and exception rules; counting dots cannot reproduce those boundaries reliably.

An IP address has no registrable domain. A host that is itself a public suffix has none either. Keep the nullable result in your data model rather than turning an absent answer into a fake domain. If your interface needs a fallback display value, the full host is still available, but it should not be labeled as a registrable domain.

## How do I use the Public Suffix List in C#?

For a domain you already have, call `PublicSuffixList.GetRegistrableDomain` or `GetPublicSuffix`. The variation demonstrates the private-section option. With the default setting, `ada.github.io` is a registrable domain because `github.io` is a private suffix. With private rules excluded, the boundary moves and the result is `github.io`.

Choose the setting to match your grouping policy and use it consistently. Including private rules keeps different hosted tenants apart at that boundary; ignoring them groups at the underlying registration boundary. The lookup accepts Unicode and Punycode labels and returns lowercase answers, keeping the script used by the domain input.

The data is bundled, not downloaded during a lookup. That makes results reproducible for the installed package, but it also means the list is the package’s pinned snapshot rather than a live view of registration policy. A registrable-domain result is not a DNS lookup, ownership check or promise that the name is available to register.
