Serialization
The core value types expose three uniform forms. Where they're available lists them.
The three methods
| Method | Purpose | Stability |
|---|---|---|
.toStr() |
Single-line human-readable summary | Not stable. For logs and debug UI only. |
.toJson() |
Pretty JSON, full structure | Stable. HTTP bodies, files, verifier input. |
.toJsonl() |
Single-line JSON, no whitespace | Stable. Line-delimited log sinks, streaming. |
Where they're available
.toStr() / .toJson() / .toJsonl() are defined on:
OctetRegionOctetVerdictLatLonH3CellInterval
Examples
OctetRegion
let r = OctetRegion.disc(center: LatLon(37.422, -122.084), radiusMeters: 250)
r.toStr() // "Disc at (37.4220, -122.0840), r=250 m"
r.toJsonl() // {"shape":"ellipse","center":{"latitude":37.422,...},...}
val r = OctetRegion.disc(LatLon(37.422, -122.084), 250.0)
r.toStr() // "Disc at (37.4220, -122.0840), r=250 m"
r.toJsonl() // {"shape":"ellipse","center":{"latitude":37.422,...},...}
Discs round-trip as ellipses in the JSON form (the underlying type is EllipseRegion with equal axes). The human-readable .toStr() form keeps the "Disc" label for readability.
OctetVerdict
verdict.toStr()
// "YES reason=OK atTime=2026-05-28T15:30:00.000Z validity=[...] conf=0.92"
verdict.toJson()
// {
// "result": "YES",
// "reason": "OK",
// "message": "isWithin evaluated on cached proof",
// "queried_at": "2026-05-28T15:30:00.000Z",
// "validity": { "from": "...", "to": "..." },
// "proof": { "id": "...", ..., "proof_bytes_b64": "..." },
// "confidence": { "overall_score": 0.92, ... },
// "achievable_level": null
// }
verdict.toStr()
// "YES reason=OK atTime=2026-05-28T15:30:00.000Z validity=[...] conf=0.92"
verdict.toJson()
// {
// "result": "YES",
// ...
// }
The proof object
.toJson() emits the same proof object on iOS and Android. It carries the proof's identifying fields and the serialized proof itself:
"proof": {
"id": "...",
"level": "COUNTRY",
"timestamp_ms": 1748462400000,
"sdk_version": "3.0.0",
"platform": "ios",
"spoofing_verdict": "VERIFIED",
"confidence": { "overall_score": 0.92, "spoofing_risk_score": 0.03, "flags": [] },
"position_commitment_b64": "...",
"proof_bytes_b64": "..."
}
proof_bytes_b64 is the serialized proof (LocationProof.proofBytes), encoded as standard base64 with padding. You can forward the JSON as is. A verifier needs the decoded bytes, so base64-decode proof_bytes_b64 before you pass it to octet-verify or Octet.verify.
Changes in 3.0
proofJSON carriesspoofing_verdict. It is the proof's assurance tier (VERIFIED,PLAUSIBLE, and so on), the same value asLocationProof.spoofingVerdict, so you can read it without decoding the proof bytes. SeeOctetVerdict.
Changes in 2.0
confidence.flagsJSON isUPPER_SNAKEon iOS. iOS previously emitted Swift case names (vpnActive). It now emitsVPN_ACTIVE, matching Android. This is a breaking change for code that parsestoJson()/toJsonl()on iOS. The typedConfidenceSummary.flagsandtoStr()are unchanged.- Proofs commit a
location_verdict. Under semantic-binding v2 (the default from 2.0), a proof binds the device's own inside/outside answer for its claimed region, and the city and earth geometry. This lives insideproofBytes, checked byoctet-verifyandOctet.verify. It is not a separate JSON field.
When a predicate runs with a sessionNonce (see Proof Binding), the proof material commits a hash of that nonce. Only the hash is serialized, never the raw nonce.
The stability commitment in the table above applies to non-proto fields today. The proto fields become stable when the proto-JSON path lands. Until then, to forward proof material to a verifier, pass the LocationProof value itself (it is a typed proto on both platforms), not verdict.toJson().
Helper free functions (Android)
In addition to the methods, Android exposes:
fun whatisRegion(r: OctetRegion): String // equivalent to r.toStr(); NOT stable
fun regionToStr(r: OctetRegion): String // STABLE canonical machine form
regionToStr is the stable wire form behind region.toJson()'s shape, iso_code, and other fields. Same content, more compact representation, suitable for log diffs and idempotency keys.
iOS exposes only the method form: region.toStr().
See also
OctetRegionOctetVerdict- License Types. License types have no
.toStr(),.toJson()or.toJsonl(). Read fields directly.