Quickstart

Add body scanning to your iOS app: capture, on-device measurement, and the full member experience — results, history, trends, sharing. Your member's measurements are computed on their phone and stay there.

1. Install the SDK

In Xcode: File → Add Package Dependencies, paste the package URL, pick the latest version. Requires iOS 17; your app builds and runs in the Simulator, and real scans need a Face ID iPhone.

Package URL
https://github.com/Visualize-KK/visualize-sdk

2. Get your keys

The portal issues a key pair per app. The publishable key pk_live_… ships in your app. The secret key sk_live_… stays on your server — it is shown once at issuance and never again.

Set the app's Bundle ID and Team ID in the portal to exactly match the app you ship. Device attestation binds to Team ID.Bundle ID; if the portal values don't match your built app, every scan is refused with an attestation error — and the message won't point at the bundle, so it's a hard one to guess. Copy both straight from Xcode's Signing & Capabilities.

3. Mint a session token on your server

Your backend exchanges the secret key for a short-lived session token per member action. host_user_ref is your own stable ID for the member — it is also how billing counts a monthly active user, so keep it consistent.

bash
curl https://api.visualizeme.ai/v1/sessions \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"host_user_ref": "user_842"}'

# 201
# {"session_token": "vst_...", "expires_at": "2026-09-16T12:15:00Z"}

4. Present the scanner

Configure once at launch, then present the member home — it handles preparation, the scan flow, results, history, and trends. The token provider closure is called once per preparation and once per scan; mint a fresh token from your backend each time.

swift
import VisualizeSDK

// At launch. The key can live in Info.plist instead (VZPublishableKey).
await Visualize.configure(
    .init(publishableKey: "pk_live_..."),
    engine: AVIXScanEngine())

// Wherever your UI offers scanning:
Visualize.presentHome(from: viewController) {
    try await myBackend.mintSessionToken()   // your server, step 3
}

The first scan on a device downloads the ~180 MB model bundle, once — cached, resumable, Wi-Fi by default, updated over the air. Details and the prepare() call that moves the wait into onboarding: Scanning → Preparation and the model download.

Prefer your own results UI? Call Visualize.startScan(sessionToken:presentingFrom:) directly — it returns a ScanResult with the measurements. See Scanning.

5. Receive scan outcomes

Set a webhook URL on your app in the portal and your backend receives a signed scan.completed event for every scan — the verified record you can bill and build on. See Webhooks.

Configuration

The SDK reads these from your app's Info.plist — set them from your xcconfig so nothing lives in source. The publishable key is required and has two homes: pass it in code, or set it here and configure with .fromHostConfiguration(). The other two only override defaults.

KeyMeaning
VZPublishableKeyYour pk_live_…, so it stays out of source. Alternative to passing it in code.
VZEnvironmentproduction (the default), staging, or development.
VZAPIBaseURLAn explicit API host, overriding VZEnvironment. Set it only if your onboarding instructions say so — pilot integrations receive a host here; removing the key returns the app to production.
Info.plist
<key>VZPublishableKey</key>
<string>$(VZ_PUBLISHABLE_KEY)</string>

<!-- Required — capture uses the front TrueDepth camera. -->
<key>NSCameraUsageDescription</key>
<string>Scanning uses the front camera to measure your body.</string>
Release.xcconfig
VZ_PUBLISHABLE_KEY = pk_live_...

Then configuring at launch needs no values in code at all:

swift
try await Visualize.configureFromHostConfiguration(engine: AVIXScanEngine())

Nothing set means production. An app shipped with no configuration reaches the real service rather than failing quietly.

Runnable samples

Two working samples — a minimal iOS app and a one-file Docker backend — take you from zero to a scan. The Run the samples guide walks through both, step by step.

Privacy default: no measurement ever reaches Visualize. Results exist on the member's device and in your app. Server-side results are a separate, consent-gated opt-in — see Results delivery.