# Share a Papermill Notebook Run — One URL per Parameter Set

Canonical: https://commareports.com/share-papermill-report
Published: 2026-09-01

> Papermill executes a notebook with parameters; nbconvert renders it. Publish the result to Comma so every run has a link, a revision history, and somewhere for the reviewer to leave a note.

# Share a Papermill run

Papermill solved the boring half of notebooks: parameterize one, execute
it headlessly, get an output notebook per parameter set. What it does not
solve is that the output is another `.ipynb` — a file format whose
audience is people with a Jupyter install and time.

The run that matters is the one someone else reads.

## Publish it

```bash
papermill weekly.ipynb "out-$REGION.ipynb" \
  -p region "$REGION" -p as_of "$(date +%F)" || true

jupyter nbconvert --to html --embed-images --no-input "out-$REGION.ipynb"

curl -fsS -X PATCH \
  "https://commareports.com/api/v1/reports/$COMMA_REPORT_ID" \
  -H "Authorization: Bearer $COMMA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --rawfile html "out-$REGION.html" \
        --arg title "Weekly — $REGION — $(date +%F)" \
        '{title: $title, html: $html}')"
```

`|| true` on the papermill line is deliberate. Papermill exits non-zero
when a cell raises and still writes the traceback into the output
notebook, and that is precisely the run you want at a URL rather than
buried in a CI log.

`PATCH` on a saved report id per region is the shape that pays off: one
stable URL per parameter set, a revision per run, and a diff between any
two runs. A fresh `POST` every execution gives you a graveyard of
one-off links instead.

Use a [scoped token](/docs/api-tokens) with `reports:write` only.

## What the URL changes

- **A run has a history.** Revision N versus revision N−1 is the actual
  question — did the number move, and when. See
  [revisions and diffs](/share-html-report).
- **Reviewers annotate the run.** A threshold that fired, a segment that
  looks wrong: the note anchors to the output cell. See
  [commenting on HTML](/comment-on-html).
- **Failures are readable.** The traceback renders as a page rather than
  as log output someone has to go find.
- **Private by default** — team, domain-gated, or named reviewers. See
  the [sharing model](/docs/sharing).

## Put it on a cron

Papermill exists so notebooks can run unattended, so the publish should
be unattended too. A [routine](/docs/routines) executes the notebook and
refreshes the report on a schedule — see
[scheduled HTML reports](/features/routines/scheduled-html-reports) and
[weekly analytics digests](/features/routines/weekly-analytics-digest).

## Limits

- **HTML body: 5 MB.** `--embed-images` inlines figures; a plot-heavy run
  approaches the ceiling. Downsample, or publish a summary notebook and
  attach the full output as an [asset](/docs/api).
- **Scripts run, sandboxed**: `allow-scripts`, no `allow-same-origin`.
- **60 requests/minute per token.**

## Try it

Comma is free — unlimited reports, unlimited commenters, unlimited
revision history.

**[Create your first report →](https://commareports.com/)**

### Related

- [nbconvert exports](/share-nbconvert-html) — the render step on its own
- [Jupyter notebooks](/share-jupyter-notebook-html) · [Cron for agents](/features/routines/cron-for-ai-agents)
- [Publish from CI](/docs/ci) · [API tokens](/docs/api-tokens)
