Artifacts
One extraction, four artifacts. The JSON is the record; the other three are stateless transforms of it that you request by posting the JSON back.
The JSON result
Section titled “The JSON result”Every extraction returns the same body, whichever endpoint ran it:
extraction: every tract, every course with the sentence it was read from.groundtruth_verdicts: one entry per tract, withstatus,reasons,closure_ratio,computed_acres, and the computedgeometry. See verdicts.document_verdict: present only on documents that produce no tracts (plats, utility as-builts). Null on deeds and easements, which speak through the array above.usage,model,engine_version,document: what the read cost, what ran it, and the filename echoed back.attestation: the signature block, below.
The post-back artifacts
Section titled “The post-back artifacts”All three take the response you already hold. All three are free and unmetered: the document was already paid for, and a customer at their quota can still collect work they bought.
POST /v1/certificate renders the extraction as the
certificate PDF a buyer files. It verifies the
attestation signature first and refuses a payload that does not match, so a
verdict edited in a text editor cannot produce a certificate.
POST /v1/dxf returns an R2010 DXF of every tract with computed geometry,
drawn in the traverse’s own plane.
POST /v1/geopackage is the GIS twin: local-plane tract and call layers,
plus a WGS 84 layer for aliquot tracts the PLSS fabric located, which opens
already placed.
All three refuse honestly when there is nothing to make. An extraction with no
drawable geometry answers 422 nothing_to_draw, and one with no tracts and no
document verdict answers 422 nothing_to_certify: a blanket easement or a
lot-and-block conveyance carries a burden or a reference, not a boundary. The
burden and reference fields are in the JSON you already hold.
Two more routes accept the same post-back and re-sign what they change:
POST /v1/locate fills PLSS corner positions, and POST /v1/corrections
applies operator corrections and recomputes the verdicts. Both verify the
signature first, for the same reason the certificate does.
The attestation
Section titled “The attestation”"attestation": { "document_sha256": "9f2c…", "extracted_at": "2026-08-16T14:02:11Z", "signature": "b41a…"}The signature is an HMAC-SHA256 over the whole response body with the signature field itself excluded, serialized canonically: sorted keys, compact separators, ASCII escaped. The document hash and the timestamp sit inside the signed content, which is what binds this extraction to that document at that moment; outside the signature, the hash could be swapped for another document’s without breaking anything.
The certificate route recomputes this signature over the bytes it receives and refuses a mismatch. The DXF and GeoPackage routes do not check it: they draw whatever geometry the body carries, because the drawing is not the deliverable the signature exists to protect.
A server with no signing key configured returns an honest response with an
empty signature, and the certificate later refuses it with
attestation_unavailable rather than 500ing mid-extraction.
Test-key fixtures are re-attested as they are served, so certificate post-back works in the sandbox against any deployment.
Store the bytes, never re-serialize
Section titled “Store the bytes, never re-serialize”The signature covers a canonical serialization of the response, and JSON does
not distinguish 1758.0 from 1758 on the wire. Parse the response in
JavaScript and JSON.stringify it back, and a stated acreage of 1758.0
comes out as 1758; the server reads that as an integer, the canonical bytes
change, and the signature stops matching. The extraction is still perfectly
honest, and the certificate refuses it anyway, with attestation_mismatch.
So: hold the response body as the bytes or text the API sent, and post exactly that. Never round-trip an extraction through your own JSON encoder before certifying it. Re-serializing usually works and occasionally does not, and “occasionally” is the failure mode that reaches production.
The same rule applies to what /v1/locate and /v1/corrections return: each
answer is re-signed, so the body they hand back is the new thing to store.
Keep the JSON
Section titled “Keep the JSON”The API does not store extractions; the post-back routes exist so it never has to. Async and batch results are held seven days after the first fetch and thirty days without one, and after that the JSON you kept is the only copy. The certificate, DXF, and GeoPackage can be regenerated from it at any time, for free, as long as the bytes are the ones the API returned.