You are viewing v3.0.0 of the docs. The latest is v3.1.2.
Docs/Mobile SDK/API Reference

Predicates

The three predicate methods on OctetSdk.loc. All three are async (Swift) / suspend (Kotlin) and do not throw. A runtime problem produces an INDETERMINATE verdict.

isWithin

The primary predicate. Tests whether the device's provable location at atTime (default now) is inside region.

public func isWithin(
    region: OctetRegion,
    atTime: Date = Date(),
    sessionNonce: Data? = nil,
    decisionRef: String? = nil,
    forceFresh: Bool = false
) async -> OctetVerdict
suspend fun isWithin(
    region: OctetRegion,
    atTime: Instant = Instant.now(),
    sessionNonce: ByteArray? = null,
    decisionRef: String? = null,
    forceFresh: Boolean = false,
): OctetVerdict

Example

let v = await sdk.loc.isWithin(
    region: .country(isoCode: "US"),
    atTime: Date()
)
if v.result == .yes { ship(v.proof!) }
val v = sdk.loc.isWithin(
    region = OctetRegion.country("US"),
    atTime = Instant.now()
)
if (v.result == OctetVerdict.Result.YES) ship(v.proof!!)

isOutside

Tests whether the device's provable location at atTime (default now) is outside region.

public func isOutside(
    region: OctetRegion,
    atTime: Date = Date(),
    sessionNonce: Data? = nil,
    decisionRef: String? = nil,
    forceFresh: Bool = false
) async -> OctetVerdict
suspend fun isOutside(
    region: OctetRegion,
    atTime: Instant = Instant.now(),
    sessionNonce: ByteArray? = null,
    decisionRef: String? = null,
    forceFresh: Boolean = false,
): OctetVerdict
Caution

isOutside is a separate query, not the negation of isWithin. A YES from isOutside carries a proof that the device is outside region, and a verifier checks that proof the same way as any other. An INDETERMINATE from isWithin does not mean the device is outside. Negating it would merge two outcomes: the device is not inside region, and the SDK could not tell.


contains

Tests whether the point center is within tol meters of the device's provable location.

public func contains(
    center: LatLon,
    tol: Meters,
    atTime: Date = Date(),
    sessionNonce: Data? = nil,
    decisionRef: String? = nil,
    forceFresh: Bool = false
) async -> OctetVerdict
suspend fun contains(
    center: LatLon,
    tol: Meters,
    atTime: Instant = Instant.now(),
    sessionNonce: ByteArray? = null,
    decisionRef: String? = null,
    forceFresh: Boolean = false,
): OctetVerdict

Mathematically equivalent to isWithin(region: .disc(center: center, radiusMeters: tol), atTime:). Kept as a distinct verb because the device-centric reading is the natural one for proximity use cases ("am I near the delivery dropoff", "did I arrive at the geofence").

PLAUSIBLE containment

A disc answer, from contains(...) or a disc isWithin(...), carries an assurance tier on its proof. By default a disc query answers YES or NO only from a VERIFIED proof, and otherwise returns INDETERMINATE. New in 3.0: setting OctetConfig.advanced.acceptPlausibleContainment = true lets it answer from a PLAUSIBLE proof as well. Tight tolerances pass only with a tight location fix. Read proof.spoofingVerdict before treating a YES as authoritative.

let config = OctetConfig(
    licenseKey: "",
    advanced: AdvancedConfig(acceptPlausibleContainment: true))
val config = OctetConfig(
    licenseKey = "",
    advanced = AdvancedConfig(acceptPlausibleContainment = true))

Custom predicates

isWithin is the load-bearing primitive, and contains is a one-line wrapper over it. Custom predicates can be built the same way:

extension OctetLoc {
    func isNear(_ center: LatLon, _ tol: Meters) async -> OctetVerdict {
        await isWithin(region: .disc(center: center, radiusMeters: tol))
    }
    func isInsideAny(_ regions: [OctetRegion]) async -> OctetVerdict? {
        for r in regions {
            let v = await isWithin(region: r)
            if v.result == .yes { return v }
        }
        return nil
    }
}
suspend fun OctetLoc.isNear(center: LatLon, tol: Meters): OctetVerdict =
    isWithin(OctetRegion.disc(center, tol))

suspend fun OctetLoc.isInsideAny(regions: List<OctetRegion>): OctetVerdict? {
    for (r in regions) {
        val v = isWithin(r)
        if (v.result == OctetVerdict.Result.YES) return v
    }
    return null
}

Time semantics

All three predicates take an optional atTime. See Time Semantics for the live / historical / future regimes and the per-resolution validity windows. Default is "now". Future times beyond ±2 s come back INDETERMINATE / FUTURE_TIME.

Proof binding and freshness

All three predicates take three optional controls over which proof answers the call:

  • sessionNonce (opaque bytes, 1 to 512) binds the proof to one login. The SDK commits a hash of the nonce inside the signed proof, so a verifier can confirm the proof was made for that login. An empty or over-512-byte nonce returns INDETERMINATE / INVALID_SESSION_NONCE.
  • decisionRef (1 to 256 characters) binds the uploaded proof to one authorization decision, tagging the upload envelope with decision_ref and region_ref. An over-256-character ref returns INDETERMINATE / INVALID_DECISION_REF, with no network call. Pass nil / null, not an empty string, when there is no decision.
  • forceFresh bypasses the freshness buffer and mints a proof for this call, with none of the binding semantics above.

Each of sessionNonce and decisionRef forces a fresh proof. Setting forceFresh as well has no additional effect.

let nonce = try await loginBackend.issueNonce()
let v = await sdk.loc.isWithin(region: .country(isoCode: "US"), sessionNonce: nonce)
if v.result == .yes { send(v.proof!, to: loginBackend) }

Proof Binding explains when to use each, and how a bound proof is verified.

See also

TermsPrivacy© 2026 Understone, Inc. d/b/a Octet