---
title: "Save and load the page as JSON"
url: https://recursiveai.org/oneocr/cookbook/page-json/
description: "Write a page to oneocr.page JSON, the documented and versioned format, and read it back under limits."
version: "1.0.0"
---

# Save and load the page as JSON

Write a page to `oneocr.page` JSON, the documented and versioned format, and read it back under limits.

```csharp
using OneImage;
using OneOcr;

OcrEngine engine = OcrEngine.LoadBundled();
OcrPage page = Image.Load("receipt.png").Ocr(engine, new OcrOptions { Dpi = 192 });

var options = new OcrPageJsonOptions { Indented = true, IncludeChars = false };
string json = OcrPageJson.ToJson([page], options);
File.WriteAllText("receipt.page.json", json);

IReadOnlyList<OcrPage> again = OcrPageJson.Parse(File.ReadAllText("receipt.page.json"));
Console.WriteLine($"{json.Length} characters; read back: {again.Count} page, {again[0].Words.Count} words");
Console.WriteLine($"equal records: {again[0].Words.SequenceEqual(page.Words)}; same JSON: {OcrPageJson.ToJson(again, options) == json}");

string[] lines = json.Split('\n');
Console.WriteLine(string.Join('\n', lines.Take(9)));
int w = Array.FindIndex(lines, l => l.Contains("\"words\""));
Console.WriteLine(string.Join('\n', lines.Skip(w).Take(12)));
```

```text
27949 characters; read back: 1 page, 40 words
equal records: False; same JSON: True
{
  "format": "oneocr.page",
  "version": 1,
  "pageCount": 1,
  "pages": [
    {
      "index": 0,
      "width": 920,
      "height": 940,
              "words": [
                {
                  "text": "Corner",
                  "bounds": [314,69,445,100
                  ],
                  "visible": true,
                  "source": "ocr",
                  "confidence": 0.9839,
                  "rawConfidence": 0.9999
                },
                {
                  "text": "Market",
```

- The JSON is deterministic: the same pages give the same bytes, and writing a page read back from JSON gives the same JSON again.
- It is not a lossless copy of the objects in memory. Coordinates are rounded to three decimals and confidences to four, which is why the records read back don’t compare equal to the originals. Store the JSON, not the in-memory page, when you need to compare later.
- `bounds` are `[left, top, right, bottom]` with y running down; every element has a `source` (`ocr`, `textLayer` or `llm`). The member names match OnePDF’s `onepdf.extraction`. The whole format is in [oneocr.page JSON](https://recursiveai.org/oneocr/docs/page-json/).
- `OcrPageJson.Parse` checks sizes and depth against `OcrLimits` and throws `OcrFormatException` on bad input, so it is safe on files you didn’t write.
- `IncludeChars = false` leaves out the per-character boxes, which make up most of the file.
