---
title: Get lists by URL, not by title
summary: "`getbytitle()` breaks the moment someone renames a list; resolve by URL (bonus: `GetList` normalises folder paths to their list)"
tags: [rest-api, lists, csom, spfx]
applies-to: SharePoint Online, SharePoint Server
last-reviewed: 2026-09-24
---

# Get lists by URL, not by title

> **Bottom line.** `getbytitle()` breaks the moment anyone renames the list (or switches UI language) — resolve lists by their fixed server-relative URL via `GetList(@u)` instead.
>
> **Ve zkratce.** `getbytitle()` přestane fungovat, jakmile někdo seznam přejmenuje (nebo přepne jazyk UI) – řeš seznamy přes jejich neměnnou server-relativní URL pomocí `GetList(@u)`.

> ⚠ **Follow-up trap.** Once you are on the alias form, the URL ends in a query string —
> so you can no longer concatenate an action onto it. See
> [Actions go before the alias query string](actions-must-precede-the-alias-query-string.md).

## Symptom

REST calls that worked for months suddenly return **404 Not Found**:

```http
GET /_api/web/lists/getbytitle('Project Documents')/items
```

Nothing changed in your code. The list is right there in the browser.

## Cause

Someone renamed the list. `getbytitle()` resolves the **display title**, which any list owner can change in list settings at any time. The list's **URL segment** (`/Lists/ProjectDocuments`, `/Shared Documents`) is fixed at creation and survives renames.

Bonus trap: on multilingual sites (MUI), the display title can differ per UI language — so `getbytitle` may break only for *some* users.

## Fix

Resolve lists by server-relative URL:

```http
GET /_api/web/GetList(@u)?@u='/sites/projects/Lists/ProjectDocuments'
```

TypeScript / SPFx:

```ts
const listUrl = `${this.context.pageContext.web.serverRelativeUrl}/Lists/ProjectDocuments`;
const endpoint = `${webAbsoluteUrl}/_api/web/GetList(@u)?@u='${listUrl}'&$select=Id,Title`;
```

PnP.PowerShell accepts the URL form directly:

```powershell
Get-PnPList -Identity 'Lists/ProjectDocuments'
```

CSOM: `web.GetList(serverRelativeUrl)`.

## Notes

- Document libraries live at the web root (`/Shared Documents`), not under `/Lists/`.
- If a title must be user-facing configuration, resolve it once, store the list **ID (GUID)**, and re-resolve on 404.
- The same rename risk applies to anything keyed by display names: views, fields (use internal names), content types.

## Bonus: `GetList` accepts paths *inside* the list too (verified live 2026-08)

The docs say `GetList` takes the server-relative URL *of the list*, but SharePoint Online quietly **normalises any existing path inside the list to the list itself**:

```http
GET /_api/web/GetList(@u)?@u='/sites/x/Shared Documents/Contracts/2026'
```

returns **200** with the library's `Title` — and `RootFolder/ServerRelativeUrl` gives you the library root. A **404 means the path does not exist at all**, not "this is a folder, give me the root".

Two practical consequences:

- Resolving "which library does this folder path belong to?" is a **single request**: `GetList('<any path>')?$select=RootFolder/ServerRelativeUrl&$expand=RootFolder`. No segment-walking needed (keep the walk only as a fallback).
- Don't diagnose "GetList must 404 on folder paths" from reading code or docs — this behaviour difference is exactly the kind of thing to **verify with a live A/B request** before calling it a bug.

Caveat: when you probe *permissions* for a target folder, prefer the folder's own item (`GetFolderByServerRelativePath(decodedurl='<encoded path>')/ListItemAllFields/EffectiveBasePermissions` — the path-based form, because the classic `getfolderbyserverrelativeurl('…')` cannot find a folder with `#` or `%` in its name, see [A `#` or `%` in a file or folder name](hash-and-percent-in-file-names-need-the-resourcepath-api.md)) over the list-level answer — a folder with unique permissions would otherwise get the library's verdict, not its own.

The same leniency means a list-level probe also passes on a path that is *not* a sensible target at all — a view page such as `…/Forms/AllItems.aspx` resolves to its library. Check the shape of a path separately: [`ParentLink` from Search points at a library view](../search/parentlink-points-at-a-view-not-the-library.md).
