> For the complete documentation index, see [llms.txt](https://docs.1satordinals.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.1satordinals.com/content-and-resolution/directories.md).

# Directories

An inscription with content type **`ord-fs/json`** is a **directory**. Its body is a JSON object: keys are **single path segment** names, values are **pointers** to other inscriptions (files or nested directories).

**Keys must not contain `/`.** Each directory is one depth only — a flat map of name → pointer. Multi-level URLs (`…/lib/util.js`) come from **recursive** resolution: an entry whose content type is also `ord-fs/json` is another single-level directory, not a key with slashes.

Served by [OrdFS](/content-and-resolution/ordfs.md) under `/content/{outpoint}/…`.

```json
{
  ".": "_0",
  "index.html": "_1",
  "style.css": "_2",
  "lib": "aa11bb22…ff_0",
  "readme.md": "ord://cc33dd…_0"
}
```

### Default entry (empty path)

`GET /content/{dirOutpoint}` with no filepath (and without `?raw`) picks a **default** map key:

| Priority | Key          | Empty-path behavior                                                                                               |
| -------- | ------------ | ----------------------------------------------------------------------------------------------------------------- |
| 1        | `.`          | Serve that pointer **in place** (no redirect). Prefer this for a type-neutral root payload (e.g. a shared image). |
| 2        | `index.html` | **Redirect** to `{path}/index.html`. Prefer this for sites / SPAs.                                                |

`.` wins when both keys exist. Explicit paths such as `/content/{dir}/style.css` are unchanged.

**SPA fallback** (missing last path segment only) still tries `index.html` only — not `.`.

Minimal default-only map:

```json
{ ".": "aa11bb22…ff_0" }
```

```
GET /content/{dirOutpoint}       →  bytes of the pointed-to inscription
GET /content/{dirOutpoint}?raw   →  directory JSON (ord-fs/json)
GET /content/{dirOutpoint}/.     →  same as default when `.` is the map key (optional explicit segment)
```

## Deploying a directory

1. Inscribe each file (and any nested directory inscriptions) as its own 1-sat output.
2. Inscribe the directory itself with:
   * Content type: `ord-fs/json`
   * Body: JSON map as above
3. Prefer putting **siblings in the same transaction** and pointing at them with relative vouts (`_1`, `_2`, …) so one mint tx holds the tree root and leaves. Absolute outpoints work when children live in other txs.
4. Serve via content URL. The directory outpoint is the site root:

```
GET /content/{dirTxid}_{dirVout}/
GET /content/{dirTxid}_{dirVout}/style.css
GET /content/{dirTxid}_{dirVout}/lib/util.js
```

Every pointed-to outpoint must exist in **this OrdFS instance’s** transaction store (same [scope rules](/content-and-resolution/ordfs.md#scope-of-a-deployment) as other content). Missing children 404.

## Pointer forms

| Pointer                    | Meaning                                                                             |
| -------------------------- | ----------------------------------------------------------------------------------- |
| `_N`                       | Output index `N` in the **same transaction** as the directory inscription (sibling) |
| `txid_vout` or `txid.vout` | Absolute outpoint                                                                   |
| `txid` (64 hex)            | Treated as that transaction’s first resolvable content output                       |
| `ord://…`                  | Same as the forms above with an optional `ord://` prefix (stripped)                 |

## Recursive resolution

`GET /content/{pointer}[:seq]/filepath}` drives directory walk:

1. Load the root pointer. If content type is not `ord-fs/json`, serve the bytes as a normal file.
2. If it **is** a directory and **filepath is empty**:
   * With **`?raw`**: return the directory JSON (`Content-Type: ord-fs/json`).
   * Else if map has **`.`**: load that pointer and serve it (in place).
   * Else if map has **`index.html`**: **redirect** to `{path}/index.html`.
   * Else: not found.
3. Split filepath on `/` into segments. For each segment, in order:
   * Look up the name in the **current** directory map.
   * **SPA fallback:** if the name is missing and this is the **last** segment only, use `index.html` if present (not `.`).
   * Load that entry’s pointer (same pointer rules).
   * If there are **more** segments and the loaded content is again `ord-fs/json`, **recurse** into that subdirectory with the remaining path.
   * If this is the last segment (or the entry is not a directory), **serve that content**.
4. Nesting is capped at **8** directory levels (`directory nesting too deep` if exceeded).

Example: `/content/{root}/lib/util.js` where `root` is `ord-fs/json` with `"lib" → subdirOutpoint`, and that subdir is `ord-fs/json` with `"util.js" → fileOutpoint`, loads the file through two map lookups.

Intermediate segments that are not directories (or missing keys mid-path without SPA fallback) fail with not found / bad request as appropriate.

## Practical notes

* Use **`"."`** as the default entry for a single non-HTML payload (or any root you want at `/content/{outpoint}` without a filename).
* Include **`index.html`** for web roots and SPAs that rely on redirect and last-segment fallback.
* Nested apps: put another `ord-fs/json` inscription behind a key (e.g. `"docs"`) and link to `/content/{root}/docs/…`.
* Relative `_N` pointers only work when the directory’s own outpoint is known (normal content serving).

## See also

* [OrdFS](/content-and-resolution/ordfs.md) — gateway resolution, seq, MAP, HTTP routes
* [Streams](/content-and-resolution/streams.md) — large files split across a transfer chain
