Serialization
Every public API object exposes three uniform forms.
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
- Swift (iOS)
- Kotlin (Android)
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,...},...}
Note that 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
- Swift (iOS)
- Kotlin (Android)
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": { "__future_flag__": "...", "id": "...", ... },
// "confidence": { "__future_flag__": "...", "overall_score": 0.92, ... }
// }
verdict.toStr()
// "YES reason=OK atTime=2026-05-28T15:30:00.000Z validity=[...] conf=0.92"
verdict.toJson()
// {
// "result": "YES",
// ...
// }
v1 caveat: proto-backed fields are placeholders
LocationProof and ConfidenceSummary are protobuf-backed types. Their full proto-JSON encoding is deferred to a later SDK release to keep platform output consistent (the Android side uses protobuf-javalite, which lacks JsonFormat).
For v1, .toJson() emits a placeholder object for those nested structures:
"proof": {
"__future_flag__": "OCTET_FUTURE_FLAG :: LocationProof full proto-JSON",
"id": "...",
"timestamp_ms": 1748462400000,
"sdk_version": "1.0.0",
"platform": "ios"
}
The __future_flag__ marker is the SDK's signal that this field's full encoding is not yet stable. Identifying fields (id, timestamp_ms, sdk_version, platform) are populated, so log diffs and routing remain useful.
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, integrators who need to forward proof material to a verifier should 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. No
.toStr()etc. on license types at v1. Read fields directly.