space ocr
GuidesArticlesPricingDocs
developer

An OCR API with source coordinates and an explicit review contract

Trace extracted values to box and quad source coordinates, process data.review.flagged, and inspect cells[path] evidence without relying on a fixed confidence threshold.

8 min read· 2026-08-31

Most OCR APIs can return text, geometry, or recognition scores. For an auditable workflow, the useful contract is more explicit: business values, source coordinates, supporting evidence, and the list of paths that need review should be addressable separately.

In space ocr, extracted data lives in data.values. A path such as total or items[0].amount addresses data.cells[path], which can include box, quad, verified, review, and evidence. The same path grammar is used by data.review.flagged, so a review UI can move directly from a flagged item to its source region. For coordinate-format comparisons, see an OCR API with bounding boxes.

Source coordinates and a review contract

Recognition confidence and text-to-page matching can be useful diagnostic signals, but neither should be presented as a universal acceptance rule. The current public review queue is data.review.flagged. Each item contains a path and reasons; use that path to inspect data.cells[path].

The cell's evidence.match_ratio, when present, describes character coverage from a supporting OCR comparison. It is evidence, not a fixed product-level confidence gate. A cell can also be flagged because a required field is missing, a pattern or range is violated, or a positional declaration is unresolved.

✓ Verified

How coordinates stay checkable. The extracted value is cross-checked against OCR observations on the page, and geometry is returned separately from the business value. evidence.printed_text can be compared with data.values[path]; neither is automatically declared the sole truth. Coordinates and cross-checks surface mismatches, but two systems can still agree on the same misread, so business-rule validation remains important.

What comes back per path

  • data.values: business data in the requested schema.
  • data.cells[path].box: axis-aligned coordinates on a 0–1000 normalized grid.
  • data.cells[path].quad: four points that follow page rotation.
  • data.cells[path].verified and review: the verification verdict and review reasons.
  • data.cells[path].evidence: supporting OCR comparison details.
  • data.review.flagged: the human-review work list.
  • data.normalized: deterministic parsed values for declared date, number, and integer fields.
  • data.image: the width and height used to convert normalized coordinates to pixels.
extract fields — every value comes back with source coordinates
1
2
3
4
5
6
7
8
9
10
11
12
curl -s https://api.space-ocr.com/ocr/fields \
  -H "Authorization: Bearer $SPACE_OCR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "image": "https://example.com/receipt.jpg",
    "imageType": "url",
    "fields": [
      { "name": "merchant", "type": "string", "required": true },
      { "name": "date", "type": "date", "required": true },
      { "name": "total", "type": "number", "required": true, "min": 0 }
    ]
  }'

Build the queue from review.flagged

Do not scan fields against a fixed match-ratio threshold. Iterate data.review.flagged; for each flag.path, fetch data.cells[flag.path] and show its review.reasons, box or quad, and relevant evidence. The reviewer sees the printed region while editing the corresponding value from data.values.

review_flagged.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import json, os, urllib.request

body = json.dumps({
    "image": "https://example.com/receipt.jpg",
    "imageType": "url",
    "fields": [
        {"name": "merchant", "type": "string", "required": True},
        {"name": "date", "type": "date", "required": True},
        {"name": "total", "type": "number", "required": True, "min": 0},
    ],
}).encode()
req = urllib.request.Request(
    "https://api.space-ocr.com/ocr/fields", data=body,
    headers={"Authorization": f"Bearer {os.environ['SPACE_OCR_API_KEY']}",
             "Content-Type": "application/json"},
)
data = json.load(urllib.request.urlopen(req))["data"]
values, cells = data.get("values", {}), data.get("cells", {})

for flag in data.get("review", {}).get("flagged", []):
    path = flag["path"]
    cell = cells.get(path, {})
    print({"path": path, "value": values.get(path),
           "reasons": flag.get("reasons", []),
           "box": cell.get("box"), "quad": cell.get("quad"),
           "evidence": cell.get("evidence")})

A review tool can draw the cell coordinates without re-running OCR. Convert a horizontal coordinate with x / 1000 * data.image.width and a vertical coordinate with y / 1000 * data.image.height. Use the documented edit workflow if the corrected value must be stored, and retain an audit record appropriate to your application. See building an OCR audit trail and validating OCR with bounding boxes.

Select a flagged path and highlight its box or quad in the response coordinate frame.

Query stored results without re-running OCR

After asynchronous uploads have been processed into a sheet, GET /view reads stored rows and supports the documented server-side where, sort, select, limit, and offset options. Use it for business-data queries; use the review information stored with each result rather than assuming match ratio is a queryable sheet column. Consult /docs for the current boxes option and exact response shape.

query stored rows
1
2
3
4
5
6
7
8
curl -s -G https://api.space-ocr.com/view \
  -H "Authorization: Bearer $SPACE_OCR_API_KEY" \
  --data-urlencode "path=/invoices/2026-08" \
  --data-urlencode "where=total>=40000" \
  --data-urlencode "sort=-invoice_date" \
  --data-urlencode "select=vendor,total,invoice_date" \
  --data-urlencode "boxes=1" \
  --data-urlencode "limit=50"

How to build a review-before-trust OCR pipeline

  1. Declare fields and validation
    Use fields with the documented required, type, pattern, range, enum, label, near, or not_near declarations that fit the document.
  2. Read values and the review queue
    Keep business data in data.values and iterate data.review.flagged for paths that need attention.
  3. Resolve source coordinates
    For every flagged path, open data.cells[path] and draw its box or quad using data.image dimensions.
  4. Review with evidence
    Show review reasons and relevant evidence, including printed text where present, without treating one score as proof.
  5. Store and query results
    Use the documented edit and stored-sheet APIs, and retain downstream validation appropriate to the business process.
What are source coordinates in an OCR API?
They are the page locations associated with extracted paths. space ocr exposes a 0–1000 box and a four-point quad in data.cells[path], using data.image as the pixel-conversion frame.
How is match ratio different from the review verdict?
evidence.match_ratio is a supporting character-coverage signal. The review workflow uses data.review.flagged and cells[path].review rather than a fixed public ratio threshold.
How do I route values to human review?
Iterate data.review.flagged, use each path to retrieve data.cells[path], and display its reasons and box or quad beside the corresponding extracted value.
Can I query stored OCR data without re-running OCR?
Yes. GET /view reads stored sheet rows and provides documented server-side filters, sorting, projection, pagination, and an option for coordinates.
Can source coordinates prove a value is correct?
No. They provide traceable evidence and make mismatches easier to inspect, but two systems can agree on the same error. Keep declared validation and downstream business checks.
Related