CSC

Data structures

Core v3 TypeScript structures for countries, administrative areas, places, districts, spatial results, and timezones.

Country

interface Country {
  id: number;
  name: string;
  iso2: string; // "TR", "US", "DE"
  iso3: string; // "TUR", "USA", "DEU"
  numericCode: string; // "792", "840", "276"
  phoneCode: string; // "90", "1", "49"
  capital: string; // "Ankara", "Washington", "Berlin"
  currency: string; // "TRY", "USD", "EUR"
  currencyName: string; // "Turkish lira", "US Dollar", "Euro"
  currencySymbol: string; // "₺", "$", "€"
  tld: string; // ".tr", ".us", ".de"
  native: string; // "Türkiye", "United States"
  region: string; // "Asia", "Americas", "Europe"
  regionId?: number;
  subregion: string; // "Western Asia", "Northern America"
  subregionId?: number;
  nationality?: string; // "Turkish", "American", "German"
  timezones: Timezone[];
  translations: Record<CountryTranslationLocale, string | null>;
  translationMissingLocales: CountryTranslationLocale[];
  translationSource: string;
  latitude: string | null; // "39.00000000" or null
  longitude: string | null; // "35.00000000" or null
  emoji: string; // "🇹🇷"
  emojiU: string; // "U+1F1F9 U+1F1F7"
  codeAuthority: string; // "ISO 3166/MA"
  codeStatus: 'officially-assigned' | 'user-assigned';
  metadataSource: string; // "country-metadata-policy:v1"
  metadataVerifiedAt: string; // "2026-08-08"
}

null is used when no single defensible centre exists. Use getCountryCoverage(iso2) to distinguish missing, notApplicable, and unknown; see Data coverage.

XK is a user-assigned code, not an officially assigned ISO 3166 code. Country name and currency changes, aliases, effective dates, and sources are versioned in data/country-metadata-policy.json.

emoji is a Unicode regional-indicator sequence, not an image asset or a cross-platform rendering contract. Some Windows configurations display TR, AF, and similar letter pairs instead of a color flag. Use iso2 to resolve an SVG or PNG flag asset when the interface must look consistent across operating systems. See Country flags in browser interfaces.

Example

{
  "id": 225,
  "name": "Türkiye",
  "iso2": "TR",
  "iso3": "TUR",
  "phoneCode": "90",
  "capital": "Ankara",
  "currency": "TRY",
  "currencySymbol": "₺",
  "region": "Asia",
  "subregion": "Western Asia",
  "emoji": "🇹🇷",
  "latitude": "39.00000000",
  "longitude": "35.00000000",
  "codeAuthority": "ISO 3166/MA",
  "codeStatus": "officially-assigned",
  "metadataVerifiedAt": "2026-08-08"
}

Shared entity classification

State and city records carry an explicit semantic layer in addition to their legacy source collection:

interface GeographicEntityClassification {
  entityType: 'administrative-area' | 'settlement';
  administrativeLevel: number | null;
  placeType: string;
  parentId: number;
  lifecycleStatus: 'current' | 'historical' | 'review-required';
  validFrom: string | null;
  validTo: string | null;
  classificationConfidence:
    'source-or-explicit-rule' | 'name-inferred' | 'country-default' | 'source-collection-default';
  entityLevelSource: string;
}

State

interface State extends GeographicEntityClassification {
  id: number;
  name: string; // "Istanbul", "California"
  countryId: number; // 225, 233
  countryCode: string; // "TR", "US"
  countryName: string; // "Türkiye", "United States"
  stateCode: string; // "34", "CA"
  type: StateType | null; // canonical lower-case enum
  typeStatus: 'available' | 'unknown';
  typeReasonCode: 'source-type-missing' | null;
  typeSource: string;
  latitude: string | null; // "41.01384310" or null with an exception
  longitude: string | null; // "28.94966760" or null with an exception
  coordinateType:
    'point-on-surface' | 'source-point-unspecified' | 'child-place-median' | 'unavailable';
  coordinateSource: string;
  coordinateVerifiedAt: string | null;
  coordinateValidation: string;
  coordinateStatus: 'verified' | 'derived' | 'exception' | 'review-required';
}

State coordinates are not all the same kind of “centre.” The record makes the method explicit. A matched Natural Earth Admin-1 polygon uses point-on-surface; source points keep source-point-unspecified; missing defensible points stay null with coordinateStatus: 'exception'. Source hashes, the 25 km country-boundary audit, and every exception are published in data/geography/state-coordinate-policy.json.

Country translations use one BCP 47 key set. Use getCountryTranslation(code, locale) while migrating legacy kr, br, and cn calls to ko, pt-BR, and zh-CN. Missing translations are null, never silently replaced by English. The exact enum, aliases, and 3.0 migration plan are in data/schema-normalization-policy.json.

City

interface City extends GeographicEntityClassification {
  id: number;
  name: string; // "Kadıköy", "Los Angeles"
  stateId: number;
  stateCode: string; // "34", "CA"
  stateName: string; // "Istanbul", "California"
  countryId: number;
  countryCode: string; // "TR", "US"
  countryName: string; // "Türkiye", "United States"
  latitude: string; // "40.98109600"
  longitude: string; // "29.06514473"
  wikiDataId: string; // empty when no supplemental QID is published
}

The legacy state and city arrays preserve upstream rows for compatibility. Use getAdministrativeAreas({ level, countryCode, lifecycleStatus, sourceLayer }) for comparable administrative levels; it defaults to current level 1 from the source-state layer. Use sourceLayer: 'all' to include administrative-area-like source-city rows. Use getSettlements({ countryCode, stateId, lifecycleStatus }) for populated-place rows. Country mappings, confidence rules, historical dates, and the migration contract are published in data/entity-level-policy.json.

wikiDataId is optional supplemental metadata, not a stable or primary identity. Every published non-empty QID is unique in the current snapshot. Confidence, verification reason, Wikidata revision, and rejected/duplicate cleanup evidence are published in data/identity/wikidata-qid-verification.json; use the csc:city:<id> public ID for durable references.

Türkiye district

The explicit district collection currently covers Türkiye and is separate from the compatibility city collection:

interface District {
  id: number;
  publicId: string; // "csc:district:107863"
  name: string; // "Kadıköy"
  aliases: string[];
  entityType: 'district';
  countryId: number;
  countryCode: string;
  countryName: string;
  stateId: number;
  stateCode: string;
  stateName: string;
  latitude: string;
  longitude: string;
  coordinateStatus: 'source' | 'corroborated' | 'corrected' | 'review-required';
  coordinateSource: string;
  coordinateValidation: string;
  geoNameId: number;
  wikiDataId: string | null;
  officialDistrictCode: null;
  officialDistrictCodeStatus: 'not-published-by-validation-source';
  sourceSnapshotDate: string;
}

Do not substitute the package public ID for an official government code. The validation source does not publish a national district code, so officialDistrictCode is intentionally null.

Spatial lookup

interface CoordinatePoint {
  latitude: number;
  longitude: number;
}

interface NearestCenterMatch<T> {
  entityType: 'country' | 'state' | 'city' | 'district';
  entity: T;
  distanceKm: number;
  confidence: 'high' | 'medium' | 'low';
  confidenceBasis: 'center-distance';
}

interface NearestCenterResult {
  query: CoordinatePoint;
  dataVersion: string;
  results: NearestCenterMatch[];
}

Polygon lookup returns matching feature properties separately and reports exact, boundary-or-overlap, or none. Centre proximity and polygon containment are deliberately different contracts.

Timezone

interface Timezone {
  zoneName: string; // "Europe/Istanbul"
  gmtOffset: number; // 10800
  gmtOffsetName: string; // "UTC+03:00"
  abbreviation: string; // "TRT"
  tzName: string; // "Turkey Time"
  observedAt: string; // instant for gmtOffset/gmtOffsetName
  offsetSource: string;
  zoneNameAuthority: 'IANA Time Zone Database';
  labelStatus: 'legacy-descriptive-not-authoritative';
}

zoneName is authoritative. The stored offset is only the observation at observedAt and can differ at another instant because of daylight-saving or rule changes. Calculate runtime values with CountryStateCity.getTimezoneOffset('America/New_York', new Date()); see data/timezone-policy.json.

Optimized City Format

The internal city data uses a compressed format for smaller file sizes:

CompressedFull Field
iid
nname
sstateId
ccountryId
lalatitude
lolongitude
wwikiDataId

The current canonical city JSON is approximately 89 MB and its compact package asset is approximately 12 MB. The library reconstructs full City objects lazily at runtime.

On this page