Skip to main content
Version: 0.8.0

Statistical Classification (KBLI & KBKI)

The Statistical Classification API provides access to Indonesia's standardized classification systems from BPS (Badan Pusat Statistik): KBLI (Klasifikasi Baku Lapangan Usaha Indonesia / Indonesian Standard Industrial Classification) and KBKI (Klasifikasi Baku Komoditi Indonesia / Indonesian Standard Commodity Classification). These classification systems are fundamental frameworks for organizing and categorizing economic activities and commodities in Indonesian statistics.

KBLI and KBKI serve as the backbone for statistical data collection, economic analysis, and policy formulation across Indonesia. Understanding these classifications is essential for researchers, economists, business analysts, and policymakers who work with Indonesian economic and statistical data.

Understanding Statistical Classifications

Statistical classifications provide standardized frameworks for data organization:

  • Economic Activity Classification (KBLI): Systematic categorization of economic activities and industries
  • Commodity Classification (KBKI): Structured classification of goods and commodities
  • Hierarchical Organization: Multi-level classification from broad categories to specific activities
  • International Alignment: Classifications aligned with international standards while reflecting Indonesian economic structure
  • Version Management: Multiple versions reflecting economic evolution and methodological improvements

Classification System Structure

KBLI (Indonesian Standard Industrial Classification)

KBLI organizes economic activities into a hierarchical structure:

  • Category (1 letter): Broad economic sectors (A-U)
  • Primary Group (2 digits): Major economic divisions within categories
  • Group (3 digits): Specific economic activities within primary groups
  • Sub-group (4 digits): Detailed activities within groups
  • Cluster (5 digits): Most specific level of economic activity classification

KBKI (Indonesian Standard Commodity Classification)

KBKI organizes commodities and goods into structured levels:

  • Section (1 digit): Broad commodity categories (0-4)
  • Division (2 digits): Major commodity groups within sections
  • Group (3 digits): Specific commodity types within divisions
  • Classes (4 digits): Detailed commodity categories
  • Sub-class (5 digits): Specific commodity sub-categories
  • Commodity Group (7 digits): Detailed commodity groupings
  • Commodity (10 digits): Individual commodity items

Enums

ClassificationType

ClassificationType is the base class for determining the type of classification. This class is then extended by KBLIType and KBKIType.

KBLIType

EnumValueDescription
KBLI.y2009kbli2009KBLI year 2009
KBLI.y2015kbli2015KBLI year 2015
KBLI.y2017kbli2017KBLI year 2017
KBLI.y2020kbli2020KBLI year 2020

To make a request to the detail endpoint, the KBLI code needs to be formatted in the kbli_year_code format. This class facilitates this formatting through the urlParamGenerator method.

Example:

final url = KBLIType.y2009.urlParamGenerator('24');
/// result: kbli_2009_24
final value = KBLIType.y2009.value;
/// result: kbli2009
final year = KBLIType.y2009.year;
/// result: 2009

KBKIType

EnumValueDescription
KBKI.y2015kbki2015KBKI year 2015

Example:

final url = KBKIType.y2015.urlParamGenerator('24');
/// result: kbki_2015_24
final value = KBKIType.y2015.value;
/// result: kbki2015
final year = KBKIType.y2015.year;
/// result: 2015

ClassificationLevel

ClassificationLevel is the base class for determining the group/level of classification.

KBLILevel

EnumValueDescription
KBLILevel.categorycategoryRepresents the main classification. Marked with a single alphabet.
KBLILevel.primaryGroupprimary groupDetailed description from category, each coded with two digits.
KBLILevel.groupgroupFurther details from the primary group, each coded with three digits.
KBLILevel.subGroupsubgroupFurther detail from a group's economic activities, coded with four digits.
KBLILevel.clusterclusterDistinguishes activities within a subgroup, coded with five digits.

Example:

final isValid = KBLILevel.category.validateCode('A');
/// result: true
final value = KBLILevel.category.value;
/// result: category

KBKILevel

EnumValueDescription
KBKILevel.sectionsectionGeneral classification outline, 1-digit code, 5 sections, 0-4.
KBKILevel.divisiondivisionDetailed description from section, 2-digit code.
KBKILevel.groupgroupFurther details from division, 3-digit code.
KBKILevel.classesclassesFurther details from group, 4-digit code.
KBKILevel.subClasssubclassDetailed from classes, 5-digit code.
KBKILevel.commodityGroupcommodity groupDetailed from sub-classes, 7-digit code.
KBKILevel.commoditycommodityDetailed from commodity group, 10-digit code.

Parameters

ParameterTypeDescription
typeClassificationTypeSpecifies the classification type from the KBLIType or KBKIType enum (required)
levelClassificationLevel?Specifies the classification level from the KBLILevel or KBKILevel enum (optional)
langDataLanguageLanguage used for KBLI/KBKI data (default: DataLanguage.id)
pageintPage number (default: 1)
perPageintNumber of data per page (default: 10)

Examples

1. Get KBLI Categories (Top Level)

// Fetch all KBLI 2020 categories (broad economic sectors)
final result = await StadataFlutter.instance.list.statisticClassifications(
type: KBLIType.y2020,
level: KBLILevel.category,
lang: DataLanguage.id,
);

final classificationsList = result.data;
final pagination = result.pagination;

// Display pagination information
print('Current Page: ${pagination.page}');
print('Total Pages: ${pagination.pages}');
print('Data Count in This Page: ${pagination.count}');
print('Per Page: ${pagination.perPage}');
print('Total: ${pagination.total}');
print('------------------------');

// Display KBLI categories
for (final classification in classificationsList) {
print('Classification ID: ${classification.id}');
print('Title: ${classification.title}');
print('Description: ${classification.description}');
print('Type: ${classification.type?.value}');
print('Level: ${classification.level?.value}');
print('Last Update: ${classification.lastUpdate}');
print('Release Date: ${classification.releaseDate}');
print('------------------------');
}

2. Explore KBLI Hierarchy (Manufacturing Sector)

// Explore the manufacturing sector hierarchy in KBLI 2020
class KBLIExplorer {
static Future<void> exploreManufacturingHierarchy() async {
try {
// 1. Get Category C (Manufacturing)
final categories = await StadataFlutter.instance.list.statisticClassifications(
type: KBLIType.y2020,
level: KBLILevel.category,
lang: DataLanguage.id,
);

final manufacturing = categories.data
.where((item) => item.id.startsWith('C') ||
item.title.toLowerCase().contains('manufaktur'))
.firstOrNull;

if (manufacturing != null) {
print('=== Manufacturing Category ===');
print('ID: ${manufacturing.id}');
print('Title: ${manufacturing.title}');
print('Description: ${manufacturing.description}');
}

// 2. Get Primary Groups within Manufacturing
final primaryGroups = await StadataFlutter.instance.list.statisticClassifications(
type: KBLIType.y2020,
level: KBLILevel.primaryGroup,
lang: DataLanguage.id,
);

final manufacturingGroups = primaryGroups.data
.where((item) => item.id.startsWith('1') || item.id.startsWith('2') || item.id.startsWith('3'))
.take(5)
.toList();

print('\\n=== Manufacturing Primary Groups (Sample) ===');
for (final group in manufacturingGroups) {
print('${group.id}: ${group.title}');
print(' Description: ${group.description}');
}

// 3. Get detailed groups for food manufacturing (if available)
final detailedGroups = await StadataFlutter.instance.list.statisticClassifications(
type: KBLIType.y2020,
level: KBLILevel.group,
lang: DataLanguage.id,
);

final foodGroups = detailedGroups.data
.where((item) => item.title.toLowerCase().contains('makanan') ||
item.title.toLowerCase().contains('food'))
.take(3)
.toList();

print('\\n=== Food Manufacturing Groups ===');
for (final group in foodGroups) {
print('${group.id}: ${group.title}');
print(' Description: ${group.description}');
}

} catch (e) {
print('Error exploring KBLI hierarchy: $e');
}
}
}

3. Compare KBLI Versions

// Compare classification changes across KBLI versions
Future<void> compareKBLIVersions() async {
try {
final versions = [KBLIType.y2015, KBLIType.y2017, KBLIType.y2020];
final versionData = <KBLIType, List<StatisticClassification>>{};

// Get categories for each version
for (final version in versions) {
final result = await StadataFlutter.instance.list.statisticClassifications(
type: version,
level: KBLILevel.category,
lang: DataLanguage.id,
);
versionData[version] = result.data;

await Future.delayed(Duration(milliseconds: 300));
}

print('=== KBLI Version Comparison ===');
for (final entry in versionData.entries) {
print('${entry.key.value}: ${entry.value.length} categories');

// Show sample categories
for (final category in entry.value.take(3)) {
print(' ${category.id}: ${category.title}');
}
print('---');
}

// Analyze classification evolution
final kbli2015 = versionData[KBLIType.y2015] ?? [];
final kbli2020 = versionData[KBLIType.y2020] ?? [];

print('\\n=== Evolution Analysis ===');
print('KBLI 2015 categories: ${kbli2015.length}');
print('KBLI 2020 categories: ${kbli2020.length}');

// Find common categories by ID
final common2015Ids = kbli2015.map((c) => c.id).toSet();
final common2020Ids = kbli2020.map((c) => c.id).toSet();
final commonIds = common2015Ids.intersection(common2020Ids);

print('Common categories: ${commonIds.length}');
print('New in 2020: ${common2020Ids.difference(common2015Ids).length}');
print('Removed since 2015: ${common2015Ids.difference(common2020Ids).length}');

} catch (e) {
print('Version comparison error: $e');
}
}

4. Explore KBKI Commodity Classification

// Explore KBKI commodity classification structure
class KBKIExplorer {
static Future<void> exploreKBKIStructure() async {
try {
// 1. Get all sections (top level)
final sections = await StadataFlutter.instance.list.statisticClassifications(
type: KBKIType.y2015,
level: KBKILevel.section,
lang: DataLanguage.id,
);

print('=== KBKI 2015 Sections ===');
for (final section in sections.data) {
print('Section ${section.id}: ${section.title}');
print(' Description: ${section.description}');
}

// 2. Get divisions within a specific section
final divisions = await StadataFlutter.instance.list.statisticClassifications(
type: KBKIType.y2015,
level: KBKILevel.division,
lang: DataLanguage.id,
perPage: 20,
);

print('\\n=== KBKI Divisions (Sample) ===');
for (final division in divisions.data.take(10)) {
print('Division ${division.id}: ${division.title}');

// Check for derived classifications
if (division.derived.isNotEmpty) {
print(' Derived items: ${division.derived.length}');
for (final derived in division.derived.take(2)) {
print(' - ${derived.code}: ${derived.title}');
}
}
}

// 3. Get commodity groups for analysis
final commodityGroups = await StadataFlutter.instance.list.statisticClassifications(
type: KBKIType.y2015,
level: KBKILevel.commodityGroup,
lang: DataLanguage.id,
perPage: 15,
);

print('\\n=== Commodity Groups (Sample) ===');
for (final group in commodityGroups.data.take(5)) {
print('Group ${group.id}: ${group.title}');
print(' Description: ${group.description}');
print(' Last Update: ${group.lastUpdate}');

if (group.tags.isNotEmpty) {
print(' Tags: ${group.tags.join(', ')}');
}
}

} catch (e) {
print('KBKI exploration error: $e');
}
}
}

5. Advanced Classification Analysis

// Comprehensive analysis of classification data
class ClassificationAnalyzer {
static Future<void> analyzeClassificationData() async {
try {
// 1. Analyze KBLI data completeness across levels
final kbliLevels = [
KBLILevel.category,
KBLILevel.primaryGroup,
KBLILevel.group,
KBLILevel.subGroup,
KBLILevel.cluster,
];

print('=== KBLI 2020 Level Analysis ===');
for (final level in kbliLevels) {
final result = await StadataFlutter.instance.list.statisticClassifications(
type: KBLIType.y2020,
level: level,
lang: DataLanguage.id,
perPage: 50,
);

print('${level.value}: ${result.pagination.total} items');

// Analyze data quality
final withDescription = result.data
.where((item) => item.description.isNotEmpty)
.length;

final withTags = result.data
.where((item) => item.tags.isNotEmpty)
.length;

print(' Items with description: $withDescription');
print(' Items with tags: $withTags');

await Future.delayed(Duration(milliseconds: 200));
}

// 2. Analyze classification relationships
final groupsWithDerived = await StadataFlutter.instance.list.statisticClassifications(
type: KBLIType.y2020,
level: KBLILevel.group,
lang: DataLanguage.id,
);

final itemsWithRelationships = groupsWithDerived.data
.where((item) => item.derived.isNotEmpty || item.previous.isNotEmpty)
.length;

print('\\n=== Relationship Analysis ===');
print('Groups with relationships: $itemsWithRelationships');

// 3. Publication metadata analysis
final classifications = await StadataFlutter.instance.list.statisticClassifications(
type: KBLIType.y2020,
level: KBLILevel.category,
lang: DataLanguage.id,
);

final withISBN = classifications.data
.where((item) => item.isbn != null && item.isbn!.isNotEmpty)
.length;

final withURL = classifications.data
.where((item) => item.url != null && item.url!.isNotEmpty)
.length;

print('Classifications with ISBN: $withISBN');
print('Classifications with URL: $withURL');

} catch (e) {
print('Analysis error: $e');
}
}
}

Properties

StatisticClassification

PropertyTypeDescription
idStringUnique identifier for KBLI/KBKI
typeClassificationType?Classification type (KBLI/KBKI)
levelClassificationLevel?Classification level within hierarchy
sourceStringData source information
titleStringOfficial title of the classification
descriptionStringDetailed description of the classification
isbnString?ISBN number for publication reference
issnString?ISSN number for serial publication
catalogueNumberString?Official catalogue number
publicationNumberString?Publication reference number
lastUpdateDateTimeDate of last update
releaseDateDateTimeOfficial release date
locationString?Publication or source location
urlString?Official URL reference
mfdString?Manufacturing date information
previousList<ClassificationItem>List of previous classification items
derivedList<ClassificationItem>List of derived classification items
flagboolClassification status flag
tagsList<String>Associated tags for categorization

ClassificationItem

PropertyTypeDescription
codeStringClassification code identifier
titleStringTitle of the classification item
descriptionStringDetailed description of the item

Common Use Cases

Economic Sector Analysis

// Analyze economic sectors using KBLI data
Future<void> analyzeEconomicSectors() async {
try {
final sectors = await StadataFlutter.instance.list.statisticClassifications(
type: KBLIType.y2020,
level: KBLILevel.category,
lang: DataLanguage.id,
);

print('=== Indonesian Economic Sectors (KBLI 2020) ===');
for (final sector in sectors.data) {
print('${sector.id}: ${sector.title}');

// Identify key sectors
final isKeyEconomic = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J']
.contains(sector.id);

if (isKeyEconomic) {
print(' ⭐ Key Economic Sector');
}

print(' Description: ${sector.description}');

if (sector.derived.isNotEmpty) {
print(' Sub-classifications: ${sector.derived.length}');
}

print('---');
}

} catch (e) {
print('Economic sector analysis error: $e');
}
}

Business Classification Mapping

// Map business activities to KBLI codes
class BusinessClassificationMapper {
static Future<Map<String, String>> mapBusinessActivities() async {
final businessMapping = <String, String>{};

try {
// Get detailed business activities (sub-group level)
final activities = await StadataFlutter.instance.list.statisticClassifications(
type: KBLIType.y2020,
level: KBLILevel.subGroup,
lang: DataLanguage.id,
perPage: 100,
);

for (final activity in activities.data) {
// Create mapping for common business terms
final keywords = activity.title.toLowerCase();

if (keywords.contains('makanan') || keywords.contains('food')) {
businessMapping['Food Production'] = activity.id;
} else if (keywords.contains('teknologi') || keywords.contains('software')) {
businessMapping['Technology'] = activity.id;
} else if (keywords.contains('perdagangan') || keywords.contains('retail')) {
businessMapping['Retail Trade'] = activity.id;
} else if (keywords.contains('konstruksi') || keywords.contains('construction')) {
businessMapping['Construction'] = activity.id;
}
}

print('=== Business Activity Mapping ===');
businessMapping.forEach((business, kbliCode) {
print('$business → KBLI Code: $kbliCode');
});

return businessMapping;

} catch (e) {
print('Business mapping error: $e');
return {};
}
}
}

Integration with Other APIs

Cross-Reference with Statistical Data

// Use classifications to understand statistical data context
Future<void> integrateWithStatisticalData() async {
try {
// Get manufacturing classifications
final manufacturing = await StadataFlutter.instance.list.statisticClassifications(
type: KBLIType.y2020,
level: KBLILevel.primaryGroup,
lang: DataLanguage.id,
);

final manufacturingGroups = manufacturing.data
.where((item) => item.title.toLowerCase().contains('industri'))
.toList();

print('=== Manufacturing Classifications ===');
for (final group in manufacturingGroups.take(5)) {
print('${group.id}: ${group.title}');

// This could be used to filter economic data
print(' Use for filtering economic statistics by sector ${group.id}');
print(' Related to industrial production data');
}

// Commodity classifications for trade data
final commodities = await StadataFlutter.instance.list.statisticClassifications(
type: KBKIType.y2015,
level: KBKILevel.division,
lang: DataLanguage.id,
);

print('\\n=== Commodity Classifications for Trade Analysis ===');
for (final commodity in commodities.data.take(3)) {
print('${commodity.id}: ${commodity.title}');
print(' Use for: Import/Export data analysis');
print(' Trade balance calculations by commodity group');
}

} catch (e) {
print('Integration error: $e');
}
}

Error Handling

Statistical Classification API methods return Future<ListResult<StatisticClassification>> and may throw specific exceptions:

  • StatisticClassificationException: Classification-related errors (invalid type, level errors)
  • ApiException: Network or API-related errors
  • ApiKeyNotFoundException: Invalid or missing API key
try {
final result = await StadataFlutter.instance.list.statisticClassifications(
type: KBLIType.y2020,
level: KBLILevel.category,
lang: DataLanguage.id,
);

// Process successful result
print('Found ${result.data.length} classifications');

} on StatisticClassificationException catch (e) {
print('Classification error: ${e.message}');
// Handle classification type or level errors

} on ApiException catch (e) {
print('API error: ${e.message}');
// Handle network connectivity or API service errors

} catch (e) {
print('Unexpected error: $e');
// Handle any other unexpected errors
}

Performance Considerations

  • Hierarchy Navigation: Use appropriate levels to avoid retrieving excessive data
  • Version Selection: Choose the most relevant KBLI/KBKI version for your use case
  • Pagination Management: Implement efficient pagination for large classification datasets
  • Relationship Processing: Handle derived and previous classifications efficiently
  • Caching Strategy: Cache frequently accessed classifications as they change infrequently
  • Code Validation: Use built-in validation methods for classification codes
  • Language Considerations: Consider both Indonesian and English versions for international users