Use this file to discover all available pages before exploring further.
The tenant resolve endpoint is designed to be called before the login form is displayed. Given a company identifier, it confirms whether the tenant exists in the system and returns that tenant’s visual theme configuration as a JSON string. The frontend uses this response to apply company-specific branding — colours, logos, and metadata — for both light and dark modes before the user ever enters their credentials. This endpoint is fully anonymous and requires no authentication token.
Call this endpoint as early as possible in the page lifecycle (e.g., during the initial app load or when the user types their company ID) so that theme styles are applied before the login UI is rendered, preventing a flash of unstyled content.
The company identifier to look up. Must be a non-empty string after trimming whitespace. This value is matched against the tenant registry to determine whether a database-per-tenant record exists.
A JSON-encoded string containing the tenant’s theme configuration. When null, no custom theme is defined and the application should fall back to its default styles. When present, parse this string to obtain a TenantTheme object with the following shape:
Tenant was found; data contains tenantExists: true and optional styles.
400 Bad Request
Validation
idCompany was missing or blank after trimming.
404 Not Found
NotFound
The specified company ID does not match any registered tenant.
Always check the success and errorType fields in the response body alongside the HTTP status code to determine the exact outcome. Error HTTP status codes are assigned by the ApiResponseFilter middleware based on the errorType returned by the controller.
The following example shows the full frontend pattern: call the endpoint, parse jsonStyles, and apply CSS custom properties for the active colour scheme.
interface TenantThemeTokens { [cssVariable: string]: string;}interface TenantTheme { light: TenantThemeTokens; dark: TenantThemeTokens; meta: { companyName?: string; logoUrl?: string; faviconUrl?: string; [key: string]: unknown; };}interface TenantResolveDto { tenantExists: boolean; jsonStyles: string | null;}interface ApiResponse<T> { success: boolean; message: string; data: T | null; errorType: string | null; traceId: string | null; details: string | null;}async function resolveTenant(idCompany: string): Promise<TenantResolveDto> { const response = await fetch("/api/security/v1/tenant/resolve", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ idCompany: idCompany }), }); const result: ApiResponse<TenantResolveDto> = await response.json(); if (!result.success || !result.data) { // errorType will be "Validation" or "NotFound" throw new Error(`Tenant resolution failed [${result.errorType}]: ${result.message}`); } return result.data;}function applyTenantTheme(jsonStyles: string): void { const theme: TenantTheme = JSON.parse(jsonStyles); // Detect the user's preferred colour scheme const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches; const tokens = prefersDark ? theme.dark : theme.light; // Apply CSS custom properties to the document root const root = document.documentElement; for (const [variable, value] of Object.entries(tokens)) { root.style.setProperty(variable, value); } // Apply branding metadata if (theme.meta.companyName) { document.title = theme.meta.companyName; } if (theme.meta.faviconUrl) { const link = (document.querySelector("link[rel='icon']") as HTMLLinkElement) ?? document.createElement("link"); link.rel = "icon"; link.href = theme.meta.faviconUrl; document.head.appendChild(link); }}// Usage: called on the pre-login / company-selection screenasync function initTenantBranding(idCompany: string): Promise<void> { const tenant = await resolveTenant(idCompany); if (tenant.jsonStyles) { applyTenantTheme(tenant.jsonStyles); } // tenant.tenantExists is true here — proceed to show the login form}