Augmented Reality (AR)

Enable AR experiences for your 3D configurator projects. Desktop users see a QR code that carries the shopper's exact configuration via an AR handoff session; mobile users launch native AR viewers (Scene Viewer on Android, AR Quick Look on iOS) with a live-baked model of the configured scene.

Upload USDZ File (iOS)

Upload a .usdz file for native iOS AR Quick Look support. Without a USDZ file, iOS devices may fall back to a less reliable GLB-based AR experience.

POST/projects/:id/usdz
curl -X POST \
  ".../projects/PROJECT_ID/usdz" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -F "[email protected]"

# Response:
{
  "success": true,
  "usdzId": "uuid",
  "usdzPath": "userId/project-usdz/...",
  "fileName": "model.usdz"
}

Tip: Convert GLB to USDZ using Apple's Reality Converter (macOS), Blender's USDZ export, or online tools like glb-to-usdz.com.

Delete USDZ File

DELETE/projects/:id/usdz/:usdzId

Upload AR Snapshot (Public Share)

Upload a configured-scene GLB or USDZ snapshot for AR. Public — validated by the share token (plus share password and the owner's billing status, like every share endpoint). The body is the raw binary; content type and magic bytes are checked. Max 50 MB. Rate limited to 3 requests per 5 seconds per project + IP.

POST/share/:projectId/:token/ar-upload?kind=glb|usdz&reuse=<uploadId?>
curl -X POST \
  ".../share/PROJECT_ID/SHARE_TOKEN/ar-upload?kind=glb" \
  -H "Content-Type: model/gltf-binary" \
  --data-binary "@configured.glb"

# Response:
{
  "success": true,
  "uploadId": "550e8400-e29b-41d4-a716-446655440000",
  "url": "https://...signed-url... (valid 1 hour)"
}

# kind=glb  → Content-Type: application/octet-stream or model/gltf-binary
# kind=usdz → Content-Type: application/octet-stream or model/vnd.usdz+zip
# reuse=<uploadId> (optional, strict UUID): overwrite a previous upload
#   in place — a rolling per-tab object for live re-exports. Omit it for
#   an immutable snapshot (used by AR handoff sessions).

Snapshots are stored at unique per-upload paths, so concurrent shoppers never overwrite each other's AR models. Objects older than 24 hours are purged automatically.

Create AR Handoff Session

Bind previously-uploaded GLB/USDZ snapshots plus the shopper's current selections to a short session id. The desktop QR encodes the share URL with ?ar=1&ars=<sessionId> so the phone launches AR from the baked model immediately and restores the exact configuration. Public — share-token validated. Rate limited to 5 sessions per minute per project + IP. JSON body, max 256 KB.

POST/share/:projectId/:token/ar-session
// Request body:
{
  "glbUploadId": "550e8400-...",   // required — from ar-upload (kind=glb)
  "usdzUploadId": "7c9e6679-...",  // optional — from ar-upload (kind=usdz)
  "slices": {                       // optional — selection state to restore
    "dropdownSelections": { ... },
    "selectMaterialSelections": { ... },
    "checkboxSelections": { ... },
    "numeralValues": { ... },
    "modularPlacedModules": { ... }
    // ...same slice shapes as saved configurations
  }
}

// Response:
{
  "success": true,
  "sessionId": "a1b2c3d4e5f6a7b8c9d0",
  "expiresAt": "2026-07-24T12:00:00.000Z"  // 24-hour TTL
}

Fetch AR Handoff Session

Called by the shared viewer when the URL carries ?ar=1&ars=<sessionId>. Returns freshly-signed model URLs (1 hour) plus the saved selection slices. Public — share-token validated.

GET/share/:projectId/:token/ar-session/:sessionId
// Response:
{
  "success": true,
  "glbUrl": "https://...signed-url...",
  "usdzUrl": "https://...signed-url...",  // present when a USDZ was baked
  "slices": { ... },                       // or null
  "expiresAt": "2026-07-24T12:00:00.000Z"
}

// 404 — session not found
// 410 { "expired": true } — session older than 24 hours

Track AR Analytics Event

Record AR interaction events. This endpoint is public (no auth) and used via sendBeacon from the viewer. Fire-and-forget.

POST/ar-analytics
{
  "event": "ar_launch_ios",
  "projectId": "PROJECT_ID",
  "shareToken": "optional",
  "meta": { "source": "qr_code" }
}

// Valid event types:
// ar_dialog_open, ar_qr_copy, ar_qr_open_tab,
// ar_launch_ios, ar_launch_android,
// ar_auto_launch, ar_page_view,
// ar_session_created, ar_session_restored,
// ar_launch_failed, ar_prompt_shown,
// ar_prompt_accepted

Get AR Analytics Summary

Fetch aggregated AR analytics for a project (requires auth).

GET/projects/:id/ar-analytics
// Response:
{
  "projectId": "...",
  "totalEvents": 142,
  "byEvent": {
    "ar_dialog_open": 58,
    "ar_launch_ios": 41,
    "ar_launch_android": 29,
    "ar_qr_copy": 14
  },
  "lastUpdated": "2026-03-17T...",
  "recentEvents": [...]
}

Public USDZ URL (Share Viewer)

Get a signed URL for a shared project's pre-uploaded USDZ file. Used by the share viewer as the iOS fallback when no configured USDZ snapshot is available.

GET/share/:projectId/usdz

Upload Configured GLB (Deprecated)

Deprecated. The legacy AR upload wrote every shopper's snapshot to one fixed path per project, so concurrent shoppers overwrote each other. It is kept only for previously-deployed share bundles — use /share/:projectId/:token/ar-upload (unique per-upload paths + share-token validation) for anything new.

POST/ar-upload/:projectId

AR Project Settings

AR behavior is controlled via Project Settings fields. Set these when saving a project:

{
  "enableAR": true,           // Master toggle
  "arUsdzFileName": "...",    // iOS fallback USDZ file name
  "arUsdzModelPath": "...",   // Storage path (set by upload)
  "arUsdzModelId": "...",     // Storage ID (set by upload)
  "arMobileCta": true,        // "View in your space" button on
                              // mobile share views (default true)
  "arAutoLaunch": true,       // Prompt mobile visitors to view
                              // the product in AR (banner)
  "arAnalyticsEnabled": true  // Track AR events
}

Continue reading