Datasets
The whole index, as CSV and JSON, under CC BY 4.0. These files are the canonical form of this site — the HTML is a rendering of them rather than the other way round. If a figure on a page disagrees with the dataset, the dataset is right and the correction goes in the log.
Download
Every file is generated by the same build that generates the pages, from the same objects. There is no separate export step that could drift.
| File | Format | Rows | Columns | Contents |
|---|---|---|---|---|
| reports.csv | text/csv | 6,722 | 39 | One row per assay report. The core table; every other artefact is a rollup of it. |
| reports.json | application/json | 6,722 | 39 | The same rows with a typed field manifest attached. |
| batches.csv | text/csv | 1,154 | 18 | One row per physical lot, with reproducibility, COA divergence and shared-bulk links. |
| batches.json | application/json | 1,154 | 18 | Batch rollups with the field manifest. |
| compounds.csv | text/csv | 66 | 22 | Compound registry: analytical properties, acceptance specification, observed distribution. |
| compounds.json | application/json | 66 | 22 | Compound registry with the field manifest. |
| suppliers.csv | text/csv | 20 | 24 | Scorecard summary, one row per supplier. Identical arithmetic to the scorecard pages. |
| suppliers.json | application/json | 20 | 24 | Scorecard summary with the field manifest. |
Also available: the field-by-field data dictionary, the licence and attribution terms, and the static endpoint listing.
Schema
Four tables, three foreign keys, no surprises. reports is the fact table; batches, compounds and suppliers are dimensions.
reports.compound_slug → compounds.compound_slug reports.supplier_key → suppliers.supplier_key reports.batch_slug → batches.batch_slug batches.supplier_key → suppliers.supplier_key batches.compound_slug → compounds.compound_slug batches.parent_batch → batches.batch_slug (shared-bulk link, nullable)
Nulls are meaningful and are never filled. A null peptide_content_pct means the test was not ordered, not that the content was zero — and it is null on 42 % of rows, which is the single most important thing to know before analysing this dataset.
Invariants the build asserts
These hold on every row of reports.csv. They are checked at build time and the build fails if any row breaks one.
purity + total_impurities = 100.00 ± 0.02
largest_impurity ≤ total_impurities
water + counter_ion + residual
+ peptide_content = 100.00 ± 0.02 (where content is present)
target_content = peptide_content × purity ÷ 100
recovered_mg = gross_fill × target_content ÷ 100
pct_of_claim = recovered_mg ÷ label_claim × 100
observed_mono = theoretical_mono × (1 + ppm_error ÷ 1e6)
The chromatogram on each record page is drawn from the peak table rather than generated beside it, so a figure and its table cannot disagree either. That is not an invariant you can check from the CSV, but it is the reason the CSV can be trusted.