# Getting Started with Sites Source: https://www.nianticspatial.com/docs/nsdk/how-to/sites/getting_started/ ## Overview The Sites feature provides an API for querying hierarchical data in the Niantic Spatial platform. This guide will help you get started using Sites in your application. The Sites feature organizes data in a hierarchical structure: **Organization** -> **Site** -> **Asset**. Your application starts at the **Organization** level, which is resolved directly from your access token (see below). ## Requirements The Sites feature requires authentication using Niantic Spatial Auth. Your application must be authenticated before using any Sites API methods. To authenticate: 1. Ensure you have access the [Niantic Spatial Portal](https://scaniverse.nianticspatial.com) where you can manage your organizations, sites, and assets. 2. Set up auth in your application by following the [Auth guide](https://www.nianticspatial.com/docs/nsdk/auth_getting_started) ## Your access token and Organization Your access token is scoped to an Organization. That tells the SDK which Organization's data your app can access. Use `requestSelfOrganizationInfo` to get that Organization's information. For a code example, see [Get your organization](#2-get-your-organization). ## Basic Usage The Sites API follows a simple pattern: Make requests and handle results. All requests are asynchronous and return struct data that represents the Sites entity you are requesting. ### 1. Acquire a Sites Session ### Platform: kotlin ```kotlin val sitesSession = nsdkSession.sites.acquire() ``` ### Platform: swift ```swift let sitesSession = nsdkSession.acquireSitesSession() ``` ### Platform: unity Add the Sites component to your unity scene's gameobject (image: Sites Client Manager component in Unity Inspector) Then add a reference to the Sites component to your monobehaviour: ```csharp [SerializeField] private SitesClientManager _sitesClientManager; ``` ### 2. Get your organization Resolve your organization directly from the access token with `requestSelfOrganizationInfo`. ### Platform: kotlin ```kotlin val orgResult = sitesSession.requestSelfOrganizationInfo() val organization = orgResult.organizations.firstOrNull() if (organization != null) { println("Organization: ${organization.name}") val orgId = organization.id } ``` ### Platform: swift ```swift let orgResult = try await sitesSession.requestSelfOrganizationInfo() if let organization = orgResult?.organizations.first { print("Organization: \(organization.name)") let orgId = organization.id } ``` ### Platform: unity ```csharp var orgResult = await _sitesClientManager.GetSelfOrganizationInfoAsync(); if (orgResult.Status == SitesRequestStatus.Success && orgResult.Organizations.Count > 0) { var organization = orgResult.Organizations[0]; Debug.Log($"Organization: {organization.Name}"); var orgId = organization.Id; } ``` ### 3. Query Sites Browse sites within an organization, using the `orgId` from the previous step: ### Platform: kotlin ```kotlin val sitesResult = sitesSession.requestSitesForOrganization(orgId) sitesResult.sites.forEach { site -> println("Site: ${site.name}") } ``` ### Platform: swift ```swift let sitesResult = try await sitesSession.requestSitesForOrganization(orgId: orgId) if let sites = sitesResult?.sites { for site in sites { print("Site: \(site.name)") } } ``` ### Platform: unity ```csharp var sitesResult = await _sitesClientManager.GetSitesForOrganizationAsync(orgId); if (sitesResult.Status == SitesRequestStatus.Success) { foreach (var site in sitesResult.Sites) { Debug.Log($"Site: {site.Name}"); } } ``` ### 4. Query Assets Discover spatial assets available at a site: ### Platform: kotlin ```kotlin val assetsResult = sitesSession.requestAssetsForSite(siteId) assetsResult.assets.forEach { asset -> println("Asset: ${asset.name} (${asset.assetType})") } ``` ### Platform: swift ```swift let assetsResult = try await sitesSession.requestAssetsForSite(siteId: siteId) if let assets = assetsResult?.assets { for asset in assets { print("Asset: \(asset.name) (\(asset.assetType))") } } ``` ### Platform: unity ```csharp var assetsResult = await _sitesClientManager.GetAssetsForSiteAsync(siteId); if (assetsResult.Status == SitesRequestStatus.Success) { foreach (var asset in assetsResult.Assets) { Debug.Log($"Asset: {asset.Name} ({asset.AssetType})"); } } ``` ### 5. Choose a Site for VPS2 localization To precisely localize to a Site, retain its **Site ID** from the Site query and confirm it has a production VPS asset. The Site ID identifies the localization target; the localized asset ID identifies the VPS map that matched after localization. ### Platform: kotlin ```kotlin val assetsResult = sitesSession.requestAssetsForSite(siteId) val vpsAsset = assetsResult.assets.firstOrNull { asset -> asset.assetType == AssetType.VPS_INFO && asset.deployment == AssetDeploymentType.PRODUCTION } val canLocalize = vpsAsset != null // Use siteId with vps2Session.localize(siteId) to start map-relative localization. ``` ### Platform: swift ```swift let assetsResult = try await sitesSession.requestAssetsForSite(siteId: siteId) // Split the lookup into intermediate values to keep the example easy to read. let assets: [AssetInfo] = assetsResult?.assets ?? [] let vpsAsset: AssetInfo? = assets.first { (asset: AssetInfo) in asset.assetType == .vpsInfo && asset.deployment == .production } let canLocalize = vpsAsset != nil // Use siteId with vps2Session.localize(siteId:) to start map-relative localization. ``` ### Platform: unity ```csharp var assetsResult = await _sitesClientManager.GetAssetsForSiteAsync(siteId); bool canLocalize = false; if (assetsResult.Status == SitesRequestStatus.Success) { foreach (var asset in assetsResult.Assets) { if (asset.AssetType == AssetType.VpsInfo && asset.Deployment == AssetDeploymentType.Production) { canLocalize = true; // Use siteId with TryLocalize(...) to start map-relative localization. break; } } } ``` To start map-relative localization for a Site, pass its Site ID to ### Platform: swift`localize(siteId:)`### Platform: kotlin`localize(siteId)`### Platform: unity`ARVps2Manager.TryLocalize(siteId)`. For an example that localizes to a Site and places content at the localized asset, see [Place virtual content with VPS2](https://www.nianticspatial.com/docs/nsdk/how-to/vps2/placing_virtual_content/). To learn which status to read while waiting for localization, see [Tracking states](https://www.nianticspatial.com/docs/nsdk/features/vps2/#tracking-states). ## Next Steps ### Platform: kotlin - Explore the full [API reference](https://www.nianticspatial.com/docs/api/kotlin/com.nianticspatial.nsdk.sites.SitesSession) ### Platform: swift - Explore the full [API reference](https://www.nianticspatial.com/docs/api/swift/NSDK.class-NSDKSitesSession) ### Platform: unity - Explore the full [API reference](https://www.nianticspatial.com/docs/api/unity/NianticSpatial.NSDK.AR.Sites.SitesClient)