@lineai/municipal-intel
Version:
AI-first municipal data API providing natural language descriptions of building permits and planning applications from major US cities
699 lines • 62.9 kB
JavaScript
/**
* Built-in Municipal Data Sources Registry
* Core sources provided with the package
*/
export const builtInRegistry = {
version: "1.0.0",
lastUpdated: "2025-01-30",
sources: {
ca: {
name: "California",
municipalities: [
{
id: "sf",
name: "San Francisco",
state: "CA",
type: "api",
api: {
type: "socrata",
baseUrl: "https://data.sfgov.org",
defaultDataset: "buildingPermits",
datasets: {
buildingPermits: {
endpoint: "/resource/i98e-djp9.json",
name: "Building Permits",
// Original fields array - many were incorrect or missing
// fields: ["permit_number", "permit_type", "status", "street_number", "street_name", "description", "estimated_cost", "filed_date", "issued_date"],
// UNION of field dump + sample data (ALL fields from API responses)
fields: [
"adu",
"application_submission_method",
"approved_date",
"block",
"completed_date",
"data_as_of",
"data_loaded_at",
"description",
"estimated_cost",
"existing_construction_type",
"existing_construction_type_description",
"existing_occupancy",
"existing_units",
"existing_use",
"filed_date",
"fire_only_permit",
"issued_date",
"last_permit_activity_date",
"location",
"lot",
"neighborhoods_analysis_boundaries",
"number_of_existing_stories",
"number_of_proposed_stories",
"permit_creation_date",
"permit_number",
"permit_type",
"permit_type_definition",
"plansets",
"point_source",
"primary_address_flag",
"proposed_construction_type",
"proposed_construction_type_description",
"proposed_occupancy",
"proposed_units",
"proposed_use",
"record_id",
"revised_cost",
"status",
"status_date",
"street_name",
"street_number",
"street_suffix",
"supervisor_district",
"unit",
"zipcode" // inconsistent - not in all records
],
fieldMappings: {
submitDate: "permit_creation_date",
approvalDate: "issued_date",
value: "revised_cost",
address: "street_name",
id: "permit_number",
status: "status",
description: "description",
title: "description"
// applicant: No applicant field available in this dataset
},
getFullAddress: (data) => {
const parts = [
data.street_number,
data.street_name,
data.street_suffix
].filter(Boolean);
const address = parts.join(' ');
return data.zipcode ? `${address}, ${data.zipcode}` : address || 'Unknown Address';
},
getDescription: (data) => {
const parts = [];
// Permit type and description
if (data.permit_type)
parts.push(data.permit_type);
if (data.description)
parts.push(data.description);
// Address with full context
const addressParts = [data.street_number, data.street_name, data.street_suffix].filter(Boolean);
if (addressParts.length > 0) {
const address = addressParts.join(' ');
parts.push(`at ${address}, San Francisco, CA${data.zipcode ? ` ${data.zipcode}` : ''}`);
}
// Status and cost
const statusInfo = [];
if (data.status)
statusInfo.push(`(${data.status})`);
if (data.revised_cost && !isNaN(Number(data.revised_cost))) {
statusInfo.push(`$${Number(data.revised_cost).toLocaleString()}`);
}
if (statusInfo.length > 0)
parts.push(statusInfo.join(' '));
// Filing date
if (data.permit_creation_date) {
try {
const date = new Date(data.permit_creation_date);
parts.push(`filed ${date.toLocaleDateString()}`);
}
catch (e) {
// Skip invalid dates
}
}
return parts.filter(Boolean).join(' ') || 'San Francisco Building Permit';
}
},
planningApplications: {
endpoint: "/resource/6zqd-wh5d.json",
name: "Planning Department Project Applications",
fields: ["record_id", "project_name", "project_address", "project_description", "case_number", "filed_date"],
fieldMappings: {
submitDate: "filed_date",
id: "record_id",
title: "project_name",
address: "project_address",
description: "project_description"
},
getFullAddress: (data) => {
return data.project_address || 'Unknown Address';
},
getDescription: (data) => {
const anyData = data;
const parts = [];
if (anyData.project_name)
parts.push(anyData.project_name);
if (anyData.project_address) {
parts.push(`at ${anyData.project_address}, San Francisco, CA`);
}
if (anyData.project_description)
parts.push(`- ${anyData.project_description}`);
if (anyData.filed_date) {
try {
const date = new Date(anyData.filed_date);
parts.push(`filed ${date.toLocaleDateString()}`);
}
catch (e) {
// Skip invalid dates
}
}
return parts.filter(Boolean).join(' ') || 'San Francisco Planning Application';
}
}
},
authentication: {
required: false,
recommended: true,
type: "app_token",
header: "X-App-Token"
},
rateLimit: {
withToken: 1000,
withoutToken: "shared",
period: "hour"
}
},
urls: {
planning: "https://sfplanning.org/project-applications",
building: "https://sfdbi.org/building-permits"
},
priority: "high"
},
{
id: "la",
name: "Los Angeles",
state: "CA",
type: "api",
api: {
type: "socrata",
baseUrl: "https://data.lacity.org",
defaultDataset: "buildingPermitsCurrent",
datasets: {
buildingPermitsCurrent: {
endpoint: "/resource/pi9x-tg5x.json",
name: "LA Building Permits (2020-Present)",
// UNION of all fields found across multiple API samples
fields: [
"adu_changed",
"apc",
"apn",
"business_unit",
"cd",
"cnc",
"cofo_date",
"construction",
"cpa",
"ct",
"du_changed",
"ev",
"geolocation",
"height",
"hl",
"issue_date",
"junior_adu",
"lat",
"lon",
"permit_group",
"permit_nbr",
"permit_sub_type",
"permit_type",
"pin_nbr",
"primary_address",
"refresh_time",
"solar",
"square_footage",
"status_date",
"status_desc",
"submitted_date",
"type_lat_lon",
"use_code",
"use_desc",
"valuation",
"work_desc",
"zip_code",
"zone"
],
fieldMappings: {
submitDate: "submitted_date",
approvalDate: "issue_date",
value: "valuation",
address: "primary_address",
id: "permit_nbr",
status: "status_desc",
description: "work_desc",
title: "work_desc"
},
getFullAddress: (data) => {
const address = data.primary_address || '';
return data.zip_code ? `${address}, ${data.zip_code}` : address || 'Unknown Address';
},
getDescription: (data) => {
const parts = [];
// Permit type and subtype
if (data.permit_sub_type)
parts.push(data.permit_sub_type);
if (data.permit_type)
parts.push(data.permit_type);
// Work description
if (data.work_desc)
parts.push(`${data.work_desc}`);
// Address with full context
if (data.primary_address) {
const address = `at ${data.primary_address}, Los Angeles, CA${data.zip_code ? ` ${data.zip_code}` : ''}`;
parts.push(address);
}
// Cost and status
const statusInfo = [];
if (data.valuation && !isNaN(Number(data.valuation))) {
statusInfo.push(`($${Number(data.valuation).toLocaleString()})`);
}
if (data.status_desc)
statusInfo.push(data.status_desc);
if (statusInfo.length > 0)
parts.push(statusInfo.join(' '));
// Submit date
if (data.submitted_date) {
try {
const date = new Date(data.submitted_date);
parts.push(`submitted ${date.toLocaleDateString()}`);
}
catch (e) {
// Skip invalid dates
}
}
return parts.filter(Boolean).join(' ') || 'Los Angeles Building Permit';
}
},
buildingPermits: {
endpoint: "/resource/xnhu-aczu.json",
name: "LA BUILD PERMITS (Legacy - Corrupted Dates)",
// Original fields array - contained incorrect field name
// fields: ["pcis_permit", "permit_type", "permit_sub_type", "latest_status", "issue_date", "address_start", "street_name", "work_description", "valuation_amount"],
// Actual fields from API dump
fields: [
"address_end",
"address_start",
"applicant_first_name",
"applicant_last_name",
"assessor_book",
"assessor_page",
"assessor_parcel",
"block",
"census_tract",
"contractor_address",
"contractor_city",
"contractor_state",
"contractors_business_name",
"floor_area_l_a_building_code_definition",
"floor_area_l_a_zoning_code_definition",
"initiating_office",
"issue_date",
"latest_status",
"license",
"license_expiration_date",
"license_type",
"location_1",
"lot",
"of_residential_dwelling_units",
"of_stories",
"pcis_permit",
"permit_category",
"permit_sub_type",
"permit_type",
"principal_first_name",
"principal_last_name",
"principal_middle_name",
"reference_old_permit",
"status_date",
"street_direction",
"street_name",
"street_suffix",
"tract",
"valuation",
"work_description",
"zip_code",
"zone"
],
fieldMappings: {
submitDate: "issue_date",
approvalDate: "issue_date",
value: "valuation",
address: "street_name",
id: "pcis_permit",
status: "latest_status",
description: "work_description",
title: "work_description"
// applicant: Could use applicant_first_name + applicant_last_name or contractors_business_name
},
getFullAddress: (data) => {
const parts = [
data.address_start,
data.street_direction,
data.street_name,
data.street_suffix
].filter(Boolean);
const address = parts.join(' ');
return data.zip_code ? `${address}, ${data.zip_code}` : address || 'Unknown Address';
},
getDescription: (data) => {
const parts = [];
// Permit type
if (data.permit_type)
parts.push(data.permit_type);
// Work description
if (data.work_description)
parts.push(`${data.work_description}`);
// Address with full context
const addressParts = [
data.address_start,
data.street_direction,
data.street_name,
data.street_suffix
].filter(Boolean);
if (addressParts.length > 0) {
const address = `at ${addressParts.join(' ')}, Los Angeles, CA${data.zip_code ? ` ${data.zip_code}` : ''}`;
parts.push(address);
}
// Cost and status
const statusInfo = [];
if (data.latest_status)
statusInfo.push(`(${data.latest_status})`);
if (data.valuation && !isNaN(Number(data.valuation))) {
statusInfo.push(`$${Number(data.valuation).toLocaleString()}`);
}
if (statusInfo.length > 0)
parts.push(statusInfo.join(' '));
// Issue date
if (data.issue_date) {
try {
const date = new Date(data.issue_date);
parts.push(`issued ${date.toLocaleDateString()}`);
}
catch (e) {
// Skip invalid dates
}
}
return parts.filter(Boolean).join(' ') || 'Los Angeles Building Permit (Legacy)';
}
}
},
},
priority: "high"
}
]
},
ny: {
name: "New York",
municipalities: [
{
id: "nyc",
name: "New York City",
state: "NY",
type: "api",
api: {
type: "socrata",
baseUrl: "https://data.cityofnewyork.us",
defaultDataset: "dobPermitIssuance",
datasets: {
dobPermitIssuance: {
endpoint: "/resource/ipu4-2q9a.json",
name: "DOB Permit Issuance",
fields: [
"bin__",
"bldg_type",
"block",
"borough",
"community_board",
"dobrundate",
"expiration_date",
"filing_date",
"filing_status",
"gis_census_tract",
"gis_council_district",
"gis_latitude",
"gis_longitude",
"gis_nta_name",
"house__",
"issuance_date",
"job__",
"job_doc___",
"job_start_date",
"job_type",
"lot",
"non_profit",
"owner_s_business_name",
"owner_s_business_type",
"owner_s_first_name",
"owner_s_last_name",
"owner_s_phone__",
"permit_sequence__",
"permit_si_no",
"permit_status",
"permit_subtype",
"permit_type",
"permittee_s_business_name",
"permittee_s_first_name",
"permittee_s_last_name",
"permittee_s_license__",
"permittee_s_license_type",
"permittee_s_phone__",
"self_cert",
"street_name",
"work_type",
"zip_code"
],
fieldMappings: {
submitDate: "filing_date",
approvalDate: "issuance_date",
address: "street_name",
id: "permit_si_no",
status: "permit_status",
title: "job_type"
},
getFullAddress: (data) => {
const parts = [
data.house__,
data.street_name
].filter(Boolean);
const address = parts.join(' ');
return data.zip_code ? `${address}, ${data.zip_code}` : address || 'Unknown Address';
},
getDescription: (data) => {
const parts = [];
// Job type (main permit type)
if (data.job_type)
parts.push(data.job_type);
// Address with full context
const addressParts = [data.house__, data.street_name].filter(Boolean);
if (addressParts.length > 0) {
const address = addressParts.join(' ');
const location = data.borough ? `${address}, ${data.borough}, New York, NY` : `${address}, New York, NY`;
if (data.zip_code) {
parts.push(`at ${location} ${data.zip_code}`);
}
else {
parts.push(`at ${location}`);
}
}
// Status
if (data.permit_status)
parts.push(`(${data.permit_status})`);
// Filing date
if (data.filing_date) {
try {
const date = new Date(data.filing_date);
parts.push(`filed ${date.toLocaleDateString()}`);
}
catch (e) {
// Skip invalid dates
}
}
return parts.filter(Boolean).join(' ') || 'New York City DOB Permit';
}
},
dobNowBuildApproved: {
endpoint: "/resource/rbx6-tga4.json",
name: "DOB NOW: Build – Approved Permits",
fields: [
"applicant_business_address",
"applicant_business_name",
"applicant_first_name",
"applicant_last_name",
"applicant_license",
"applicant_middle_name",
"approved_date",
"bin",
"block",
"borough",
"c_b_no",
"estimated_job_costs",
"expired_date",
"filing_reason",
"filing_representative_business_name",
"filing_representative_first_name",
"filing_representative_last_name",
"house_no",
"issued_date",
"job_description",
"job_filing_number",
"lot",
"owner_business_name",
"owner_name",
"permittee_s_license_type",
"street_name",
"work_on_floor",
"work_permit",
"work_type"
],
fieldMappings: {
submitDate: "issued_date",
approvalDate: "approved_date",
value: "estimated_job_costs",
address: "street_name",
id: "job_filing_number",
status: "work_permit",
title: "job_description"
},
getFullAddress: (data) => {
const parts = [
data.house_no,
data.street_name
].filter(Boolean);
return parts.join(' ') || 'Unknown Address';
},
getDescription: (data) => {
const parts = [];
// Job description
if (data.job_description)
parts.push(data.job_description);
// Address with full context
const addressParts = [data.house_no, data.street_name].filter(Boolean);
if (addressParts.length > 0) {
const address = addressParts.join(' ');
const location = data.borough ? `${address}, ${data.borough}, New York, NY` : `${address}, New York, NY`;
parts.push(`at ${location}`);
}
// Cost and status
const statusInfo = [];
if (data.estimated_job_costs && !isNaN(Number(data.estimated_job_costs))) {
statusInfo.push(`($${Number(data.estimated_job_costs).toLocaleString()})`);
}
if (data.work_permit)
statusInfo.push(data.work_permit);
if (statusInfo.length > 0)
parts.push(statusInfo.join(' '));
// Issue/approval date
if (data.issued_date) {
try {
const date = new Date(data.issued_date);
parts.push(`issued ${date.toLocaleDateString()}`);
}
catch (e) {
// Skip invalid dates
}
}
else if (data.approved_date) {
try {
const date = new Date(data.approved_date);
parts.push(`approved ${date.toLocaleDateString()}`);
}
catch (e) {
// Skip invalid dates
}
}
return parts.filter(Boolean).join(' ') || 'New York City DOB NOW Build Permit';
}
},
activeMajorProjects: {
endpoint: "/resource/n5mv-nfpy.json",
name: "Active Major Construction Projects",
fields: ["project_id", "project_name", "borough", "project_description", "project_start_date", "expected_completion_date", "total_construction_floor_area_sq_ft", "total_units", "construction_type"],
fieldMappings: {
submitDate: "project_start_date",
id: "project_id",
title: "project_name",
description: "project_description",
value: "total_construction_floor_area_sq_ft"
},
getFullAddress: (_data) => {
return 'Unknown Address'; // This dataset doesn't have address fields
},
getDescription: (data) => {
const anyData = data;
const parts = [];
// Project name
if (anyData.project_name)
parts.push(anyData.project_name);
// Location
if (anyData.borough) {
parts.push(`in ${anyData.borough}, New York, NY`);
}
// Project details
const details = [];
if (anyData.construction_type)
details.push(anyData.construction_type.toLowerCase());
if (anyData.total_construction_floor_area_sq_ft && !isNaN(Number(anyData.total_construction_floor_area_sq_ft))) {
const sqft = Number(anyData.total_construction_floor_area_sq_ft);
if (sqft >= 1000000) {
details.push(`${(sqft / 1000000).toFixed(1)}M sq ft`);
}
else if (sqft >= 1000) {
details.push(`${(sqft / 1000).toFixed(0)}K sq ft`);
}
else {
details.push(`${sqft.toLocaleString()} sq ft`);
}
}
if (anyData.total_units && !isNaN(Number(anyData.total_units))) {
details.push(`${Number(anyData.total_units).toLocaleString()} units`);
}
if (details.length > 0)
parts.push(details.join(', '));
// Completion date
if (anyData.expected_completion_date) {
try {
const date = new Date(anyData.expected_completion_date);
parts.push(`completion expected ${date.toLocaleDateString()}`);
}
catch (e) {
// Skip invalid dates
}
}
return parts.filter(Boolean).join(': ').replace(': : ', ': ') || 'New York City Major Construction Project';
}
}
},
authentication: {
required: false,
recommended: true,
type: "app_token"
}
},
urls: {
dob: "https://www1.nyc.gov/site/buildings/index.page",
planning: "https://www1.nyc.gov/site/planning/index.page"
},
priority: "high"
}
]
},
fl: {
name: "Florida",
municipalities: []
}
},
commonFields: {
required: ["id", "name", "state", "type", "priority"],
optional: ["urls", "coverage", "updateFrequency", "enabled", "lastChecked", "lastError"],
typeEnum: ["api", "portal", "scraping"]
},
implementationPriorities: {
high: ["sf", "nyc", "la"],
medium: [],
low: []
}
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXVuaWNpcGFsLXJlZ2lzdHJ5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2RhdGEvbXVuaWNpcGFsLXJlZ2lzdHJ5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7R0FHRztBQVdILE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBbUI7SUFDN0MsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLFlBQVk7SUFDekIsT0FBTyxFQUFFO1FBQ1AsRUFBRSxFQUFFO1lBQ0YsSUFBSSxFQUFFLFlBQVk7WUFDbEIsY0FBYyxFQUFFO2dCQUNkO29CQUNFLEVBQUUsRUFBRSxJQUFJO29CQUNSLElBQUksRUFBRSxlQUFlO29CQUNyQixLQUFLLEVBQUUsSUFBSTtvQkFDWCxJQUFJLEVBQUUsS0FBSztvQkFDWCxHQUFHLEVBQUU7d0JBQ0gsSUFBSSxFQUFFLFNBQVM7d0JBQ2YsT0FBTyxFQUFFLHdCQUF3Qjt3QkFDakMsY0FBYyxFQUFFLGlCQUFpQjt3QkFDakMsUUFBUSxFQUFFOzRCQUNSLGVBQWUsRUFBRTtnQ0FDZixRQUFRLEVBQUUsMEJBQTBCO2dDQUNwQyxJQUFJLEVBQUUsa0JBQWtCO2dDQUN4Qix5REFBeUQ7Z0NBQ3pELG9KQUFvSjtnQ0FDcEosb0VBQW9FO2dDQUNwRSxNQUFNLEVBQUU7b0NBQ04sS0FBSztvQ0FDTCwrQkFBK0I7b0NBQy9CLGVBQWU7b0NBQ2YsT0FBTztvQ0FDUCxnQkFBZ0I7b0NBQ2hCLFlBQVk7b0NBQ1osZ0JBQWdCO29DQUNoQixhQUFhO29DQUNiLGdCQUFnQjtvQ0FDaEIsNEJBQTRCO29DQUM1Qix3Q0FBd0M7b0NBQ3hDLG9CQUFvQjtvQ0FDcEIsZ0JBQWdCO29DQUNoQixjQUFjO29DQUNkLFlBQVk7b0NBQ1osa0JBQWtCO29DQUNsQixhQUFhO29DQUNiLDJCQUEyQjtvQ0FDM0IsVUFBVTtvQ0FDVixLQUFLO29DQUNMLG1DQUFtQztvQ0FDbkMsNEJBQTRCO29DQUM1Qiw0QkFBNEI7b0NBQzVC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