import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# 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:

- `OctetRegion`
- `OctetVerdict`
- `LatLon`
- `H3Cell`
- `Interval`

## Examples

### `OctetRegion`

<Tabs groupId="platform">
  <TabItem value="swift" label="Swift (iOS)">

```swift
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,...},...}
```

  </TabItem>
  <TabItem value="kotlin" label="Kotlin (Android)">

```kotlin
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,...},...}
```

  </TabItem>
</Tabs>

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`

<Tabs groupId="platform">
  <TabItem value="swift" label="Swift (iOS)">

```swift
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, ... }
// }
```

  </TabItem>
  <TabItem value="kotlin" label="Kotlin (Android)">

```kotlin
verdict.toStr()
// "YES reason=OK atTime=2026-05-28T15:30:00.000Z validity=[...] conf=0.92"

verdict.toJson()
// {
//   "result": "YES",
//   ...
// }
```

  </TabItem>
</Tabs>

## 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:

```json
"proof": {
  "__future_flag__": "OCTET_FUTURE_FLAG :: LocationProof full proto-JSON",
  "id": "...",
  "timestamp_ms": 1748462400000,
  "sdk_version": "1.1.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:

```kotlin
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

- [`OctetRegion`](/docs/api-reference/octet-region/)
- [`OctetVerdict`](/docs/api-reference/octet-verdict/)
- [License Types](/docs/api-reference/license-types/). No `.toStr()` etc. on license types at v1. Read fields directly.
