diff --git a/README.md b/README.md
index 9049a0a..98a4d9b 100644
--- a/README.md
+++ b/README.md
@@ -1,42 +1,113 @@
# umd-lib-opendata
-University of Maryland Libraries Open Data Website, built using the
-[Hugo](https://gohugo.io/) static site generator.
+Source for the University of Maryland Libraries Open Data website,
+. The site is a [Hugo](https://gohugo.io/)
+static site built with the [Hextra](https://github.com/imfing/hextra) theme.
+It documents the APIs, services, and datasets that UMD Libraries makes openly
+available, and ships runnable [Python code examples](static/code) that
+demonstrate how to use them.
-## Building
+This README covers two audiences:
-Install go-task.
+* **Site contributors** — building and serving the website locally
+ (start with [Prerequisites](#prerequisites)).
+* **Data and API users** — running the example scripts against UMD Libraries
+ services (skip to [Python code examples](#python-code-examples)).
-```bash
-# Intall using Homebrew
-brew install task
+## Prerequisites
+
+Building the site requires two command-line tools:
+
+* [Hugo](https://gohugo.io/) — the **extended** edition (the Hextra theme
+ requires it)
+* [go-task](https://taskfile.dev/) — the task runner used for all build
+ commands
+
+On macOS with [Homebrew](https://brew.sh/):
-# Install using golang
-go install github.com/go-task/task/v3/cmd/task@latest
+```bash
+brew install hugo go-task
```
-Build and serve the website using hugo:
+Running the Python code examples additionally requires Python 3.12+ (see
+[Python code examples](#python-code-examples)).
+
+## Getting started
-``` bash
+Clone the repository, then start the local development server:
+
+```bash
task serve
+```
+
+This serves the site with drafts enabled at and
+rebuilds automatically as you edit. Open the URL in a browser:
+
+```bash
open http://localhost:1314/
```
-For more information see [Hugo CLI docs](https://gohugo.io/commands/).
+Other common tasks:
+
+```bash
+# Build the static site into public/
+task build
+
+# Remove build artifacts
+task clean
+```
+
+For more options, see the [Hugo CLI docs](https://gohugo.io/commands/).
-## Python Environment
+## Python code examples
-Set up a Python environment to run the [code examples](static/code), using pyenv
-and venv.
+The [`static/code/`](static/code) directory contains standalone Python
+scripts that demonstrate how to query UMD Libraries services (OAI-PMH,
+OpenSearch, the DSpace REST API, JSON-LD, and more). They require Python
+3.12+; the pinned version lives in [`.python-version`](.python-version).
+
+Set up an environment with [pyenv](https://github.com/pyenv/pyenv) and venv:
```bash
-# Setup the Python version
+# Install the pinned Python version
pyenv install --skip-existing $(cat .python-version)
-# Setup the virtual environment
+# Create and activate a virtual environment
python -m venv .venv
source .venv/bin/activate
-# Install the requirements
+# Install dependencies
pip install -r requirements.txt
```
+
+Run the examples' test suite to confirm they work:
+
+```bash
+task test-python
+```
+
+See [TEST_PYTHON_EXAMPLES.md](TEST_PYTHON_EXAMPLES.md) for details on testing
+the code examples.
+
+## Project structure
+
+| Path | Contents |
+| --- | --- |
+| `content/` | Site content: `services/`, `apis/`, `datasets/`, `posts/` |
+| `static/code/` | Downloadable Python API examples |
+| `layouts/` | Custom templates and shortcodes overriding Hextra defaults |
+| `hugo.yaml` | Hugo site configuration |
+| `Taskfile.yaml` | Build, serve, and deploy tasks |
+
+Content pages live under `content/` and use the `code` shortcode
+(`layouts/_shortcodes/code.html`) to embed the example scripts.
+
+## Contributing
+
+Markdown content follows [markdownlint](https://github.com/DavidAnson/markdownlint)
+conventions — notably asterisk-style lists (MD004), blank lines around lists
+(MD032), and angle-bracketed bare URLs (MD034).
+
+## License
+
+Licensed under the Apache License, Version 2.0. See [LICENSE](LICENSE).