Skip to content

Multi-tenant analytics

Advanced use-case note: this page documents customer-, account-, or shop-facing statistics. Multi-tenant is an organization and access model for statistics, not a collection level by itself. API examples require a plan with tenant API access enabled and a configuration compatible with that restitution level.

For a shared-host product such as market.example.com, Pomelo recommends this model:

ConceptRoleExample
siteGlobal analytics entitymarket.example.com
tenantShop or analytics groupdemo-shop
hostname / pathRouting contextmarket.example.com/demo-shop

site_id stays the marketplace identity. tenant_id stays the stable shop identity. tenant_slug is for routing and tenant_name is for display.

SurfaceVariables
JavaScript SDKtenantId, tenantSlug, tenantName, targetTenantId, targetTenantSlug, targetTenantName
Public API / wiretenant_id, tenant_slug, tenant_name
Internal storagegroup_type, group_id, group_slug, group_name, group_source

Your platform remains the source of truth for tenants and synchronizes that registry into Pomelo. Pomelo then resolves tenant_slug -> tenant_id against that registry.

Attribution follows this order:

  1. explicit tenant_id
  2. explicit tenant_slug
  3. first path segment, for example /demo-shop
  4. no tenant

The path fallback is useful for shop pages, but the registry stays canonical. If an explicit tenant is provided but cannot be resolved, the event stays unresolved and does not fall back to the path. The page filter is therefore not a multi-tenant strategy.

See also: Multi-tenant guide.

<script
defer
src="https://cdn.pomeloanalytics.com/latest/analytics.js"
data-site-id="site_marketplace"
onload="window.pomelo?.setTenant({
tenantId: 'tenant_demo_shop',
tenantSlug: 'demo-shop',
tenantName: 'Demo Shop'
})"
></script>

On tenant pages, replace the standard Pomelo tag with the single tenant-aware tag shown here, or call setTenant() from your framework’s SDK-ready callback on the same script. Do not load analytics.js twice. When this happens during SDK startup, Pomelo applies the tenant context before replaying the buffered startup pageview.

Startup and subsequent pageview, engagement, perf.*, and error.* events then inherit that current tenant.

window.pomelo?.track('boutique.contact_click', {
action_id: 'shop:contact_click',
targetTenantId: 'tenant_demo_shop',
targetTenantSlug: 'demo-shop',
targetTenantName: 'Demo Shop',
});
window.pomelo?.clearTenant();
Terminal window
curl -sS -G "https://api.pomeloanalytics.com/v1/tenants" \
-H "Authorization: Bearer $POMELO_API_TOKEN" \
--data-urlencode "site_id=site_marketplace"
Terminal window
curl -sS -G "https://api.pomeloanalytics.com/v1/metrics/timeseries" \
-H "Authorization: Bearer $POMELO_API_TOKEN" \
--data-urlencode "site_id=site_marketplace" \
--data-urlencode "tenant_id=tenant_demo_shop" \
--data-urlencode "metric=pageviews"
Terminal window
curl -sS -G "https://api.pomeloanalytics.com/v1/metrics/breakdown" \
-H "Authorization: Bearer $POMELO_API_TOKEN" \
--data-urlencode "site_id=site_marketplace" \
--data-urlencode "dimension=tenant"

When dimension=tenant, each row uses the stable tenant_id as key. The response also includes tenant_slug and tenant_name as display labels.

Tokens can be restricted with:

  • allowedSiteIds
  • allowedTenantIds

When a token is restricted to tenants, always send tenant_id on analytics queries.