Company Bootstrap API
Company Bootstrap API
The Company Bootstrap API is the foundational layer that loads agency-specific configuration when the myProp portal starts. It connects to the AgentOS (letmc.com) API to retrieve branding, branch data, currency settings, and form enumerations — all scoped to a specific agency identified by its short name (URL slug).
Introduced in: v0.1.12
Overview
On portal load, bootstrapCompany is the primary entry point. It verifies the agency exists, then fetches all remaining configuration in parallel. Individual functions are also available for targeted calls.
company.bootstrap ← verifyCompany + branding + branches + currency + enums (parallel)
tRPC Endpoints
All endpoints live under the company.* namespace.
company.status
Auth: Public (no authentication required)
Health check confirming the company bootstrap service is reachable. Use this to verify API connectivity before attempting authenticated calls.
company.verify
Auth: Protected
Verifies that an agency exists by its short name.
Input:
{ shortName: string }
Response: CompanyInfo or null if not found.
Behaviour:
- Returns
nullon 404 (agency not found). - Throws on other API errors — company existence is considered critical.
company.branding
Auth: Protected
Fetches the agency's theme/branding configuration.
Input:
{ shortName: string }
Response: CompanyBranding
Behaviour: Returns all-null defaults if the AgentOS API returns a 404 or any other error. Branding is non-critical and will never block bootstrap.
company.branches
Auth: Protected
Fetches all branch offices for the agency (lettings and sales branches merged).
Input:
{ shortName: string }
Response: CompanyBranch[]
Behaviour: 404s on either lettings or sales branches are treated as "not available" and return an empty array for that type.
company.currency
Auth: Protected
Fetches the agency's currency settings.
Input:
{ shortName: string }
Response: CurrencyInfo
Behaviour: Defaults to GBP ({ isoCode: "GBP", symbol: "£", name: "British Pound" }) if not configured or unavailable.
company.enums
Auth: Protected
Fetches dropdown/enumeration values for portal forms.
Input:
{ shortName: string }
Response: FormEnums
Behaviour: Individual enum types that return 404 are treated as empty arrays — partial results are returned rather than failing the whole call.
company.bootstrap
Auth: Protected
Compound call that fetches all agency configuration in a single request. This is the recommended entry point for portal initialisation.
Input:
{ shortName: string }
Response:
{
company: CompanyInfo | null;
branding: CompanyBranding;
branches: CompanyBranch[];
currency: CurrencyInfo;
enums: FormEnums;
}
Behaviour: Verifies the company first. If the company does not exist (null), remaining calls are skipped. Otherwise, branding, branches, currency, and enums are fetched in parallel.
Type Reference
CompanyInfo
interface CompanyInfo {
shortName: string; // The agency's URL slug
companyName: string; // Official agency name
isActive: boolean; // Whether the agency accepts portal logins
address: string | null; // Primary address (concatenated)
phone: string | null;
email: string | null;
website: string | null;
}
CompanyBranding
interface CompanyBranding {
primaryColour: string | null; // Hex, e.g. "#1e40af"
secondaryColour: string | null; // Hex
backgroundColour: string | null; // Hex
textColour: string | null; // Hex
logoUrl: string | null;
iconUrl: string | null;
bannerUrl: string | null;
customCss: string | null; // Raw CSS string
}
All colour values are normalised to valid hex strings. Missing # prefixes are added automatically. Invalid colour values return null.
CompanyBranch
interface CompanyBranch {
branchId: string; // AgentOS branch ID
name: string; // Human-readable branch name
address: string | null;
phone: string | null;
email: string | null;
lettingsPortalUrl: string | null;
salesPortalUrl: string | null;
isActive: boolean;
}
CurrencyInfo
interface CurrencyInfo {
isoCode: string; // ISO 4217 code, e.g. "GBP"
symbol: string; // e.g. "£"
name: string; // e.g. "British Pound"
}
FormEnums
interface FormEnums {
propertyTypes: EnumOption[];
furnishingTypes: EnumOption[];
titles: EnumOption[];
jobPriorities: EnumOption[];
jobStatuses: EnumOption[];
tenancyTypes: EnumOption[];
}
interface EnumOption {
value: string; // Value to store/submit
label: string; // Human-readable label to display
}
AgentOS Field Compatibility
The service layer handles naming inconsistencies in the AgentOS API transparently:
| Variation | Fields handled |
|---|---|
| Colour spelling | PrimaryColour / PrimaryColor (and equivalents for secondary, background, text) |
| Branch ID | OID / BranchID |
Email / EmailAddress | |
| Phone | Phone / Telephone |
| Logo URL | LogoUrl / LogoURL |
| Currency code | ISOCode / CurrencyCode |
Callers always receive the normalised field names defined in the TypeScript interfaces above.
Error Handling
| Scenario | Behaviour |
|---|---|
| Company not found (404) | verifyCompany returns null; bootstrap short-circuits |
| Branding unavailable (404 or error) | Returns all-null defaults |
| Currency unavailable | Returns GBP defaults |
| Individual enum type unavailable (404) | Returns empty array for that type |
| Sales or lettings branches unavailable (404) | Returns empty array for that type |
| API not configured | verifyCompany throws LetmcNotConfiguredError; optional endpoints return defaults |
| Unexpected API errors | Captured via captureError, then re-thrown (for verifyCompany) or swallowed with defaults (for optional endpoints) |
Middleware
The middleware was refactored in v0.1.12 to a two-layer architecture:
- Edge layer — Checks whether the path is public. Public paths (e.g.
company.status) bypass NextAuth entirely. - Auth layer — All protected
company.*endpoints require an authenticated session.
This ensures the health check endpoint remains accessible for monitoring and pre-auth bootstrapping without exposing protected data.