# Put the rows of a table's closed periods into packs: one note per period (`<table> <key>.md` in the

`POST /datanotes/operations/pack_rows/` (operation `pack_rows`)

Put the rows of a table's closed periods into packs: one note per period (`<table> <key>.md` in the
table's folder), a `##` section per row, `key:: value` lines for its values. The table needs a `pack`
option (create_table / alter_table, e.g. `"{occurred_at:YYYY-MM}"`). A period is closed
`pack_after_days` days after it ends (default 7); `key` packs only that period.
Nothing changes for the engine and its readers: select_rows, links, the graph and the change feed
still see each row at its path, with its values, text and file_modified (no change event, no new
version). Links from other notes to a packed row become `[[pack#row]]`, which Obsidian follows too.
A row stays a note of its own (`excluded`, with the reason) when it changed in the last 24 hours, has a
`#` or `##` heading in its text, is not at the path its values give, or its note is not in the form
the engine writes. The engine also packs on its own once a day (setting `autoPack`). Needs the engine
service. Journaled: undo_migration takes the rows out again. Use `dry_run` to see `packs` first.

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `X-Datanotes-Actor` | header | `string` | no | JSON: on whose behalf the write is made, recorded in the journal (`harness`, `model`, `session`). |

## Request body

`application/json`, required

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `table` | `string` | yes |  |  |
| `key` | `string \| null` | no | `null` | Only the period of this key (e.g. "2026-10"); every closed period when absent. |
| `dry_run` | `boolean` | no | `false` |  |

## Responses

| Status | Description | Body |
| --- | --- | --- |
| 200 | Done. | `PackRowsResult` (application/json) |
| 400 | Bad input: the body is not a JSON object, or an argument is unknown, missing or of the wrong type. | `Error` (application/json) |
| 401 | Missing or wrong bearer token. | `Error` (application/json) |
| 403 | A named token beyond its permissions (the engine's administration, tables outside its `write` patterns, schema changes without `ddl`). | `Error` (application/json) |
| 404 | Unknown table, view, migration, note or folder. | `Error` (application/json) |
| 409 | Ambiguous table name: it matches several tables (`paths` or `tables` lists them). | `AmbiguousName` (application/json) |
| 500 | Unexpected error. | `Error` (application/json) |

The schemas named here are in [openapi.json](https://datanotes.dev/openapi.json) (`components.schemas`).
