Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ti-infinite/GSMApplication/llms.txt

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.

Endpoint

POST /api/security/v1/tenant/resolve
Authentication: None — the entire TenantController is decorated with [AllowAnonymous]. Content-Type: application/json

Request Body

idCompany
string
required
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.

Response

All responses use the ApiResponse<T> envelope.
success
boolean
true when the company was found and resolved successfully.
message
string
Human-readable status. Returns "Tenant is valid." on success, or "Company is invalid or inactive." on failure.
data
object | null
Present only when success is true.
errorType
string | null
Populated only when success is false. One of: Validation (missing or empty idCompany), NotFound (tenant not found in the registry).
traceId
string | null
Optional correlation identifier for distributed tracing.
details
string | null
Optional extended error detail in non-production environments.

HTTP Status Codes

StatuserrorTypeScenario
200 OKTenant was found; data contains tenantExists: true and optional styles.
400 Bad RequestValidationidCompany was missing or blank after trimming.
404 Not FoundNotFoundThe 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.

Examples

cURL

curl --request POST \
  --url https://your-gateway-host/api/security/v1/tenant/resolve \
  --header 'Content-Type: application/json' \
  --data '{
    "idCompany": "GSM001"
  }'

TypeScript — resolve and apply tenant theme

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 screen
async 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
}

Success response example

{
  "success": true,
  "message": "Tenant is valid.",
  "data": {
    "tenantExists": true,
    "jsonStyles": "{\"light\":{\"--color-primary\":\"#0055CC\",\"--color-background\":\"#FFFFFF\",\"--color-text\":\"#111111\"},\"dark\":{\"--color-primary\":\"#4D9EFF\",\"--color-background\":\"#1A1A2E\",\"--color-text\":\"#F0F0F0\"},\"meta\":{\"companyName\":\"GSM Corp\",\"logoUrl\":\"/assets/gsm-logo.svg\",\"faviconUrl\":\"/assets/favicon.ico\"}}"
  },
  "errorType": null,
  "traceId": null,
  "details": null
}

Tenant not found response example

{
  "success": false,
  "message": "Company is invalid or inactive.",
  "data": null,
  "errorType": "NotFound",
  "traceId": null,
  "details": null
}

Validation error response example

{
  "success": false,
  "message": "Company is invalid or inactive.",
  "data": null,
  "errorType": "Validation",
  "traceId": null,
  "details": null
}

Build docs developers (and LLMs) love