@lineai/gov-deals
v1.1.1
Published
Explore Federal contracts for government building renovations, city hall renovations, courthouse updates, library modernizations, federal building improvement contracts, base housing and facilities upgrades.
Maintainers
Readme
@lineai/gov-deals
A TypeScript library for exploring federal contracts and opportunities for government building renovations, including city halls, courthouses, libraries, federal buildings, and base housing upgrades.
Features
- 🔍 Advanced Search: Find government contracts by keywords, NAICS codes, location, and more with intelligent filtering
- 🧭 AI-Powered Guidance: Built-in search tips and suggestions to help optimize queries for better results
- 🏗️ Construction-Focused: Built-in helpers for construction industry NAICS codes
- 📄 Multiple Access Methods: Get opportunities by ID, URL, or comprehensive search
- 🔄 Type-Safe: Full TypeScript support with runtime validation using Zod
- ⚡ Efficient: Optimized filters and pagination to handle large result sets
- 🛠️ Multiple Data Sources:
- SAM.gov API: Live federal opportunities with all filters working correctly
- CSV Files: Local data for offline development
- Supabase: Historical opportunities database (no API key required)
- 📊 Historical Analysis: Access 70,000+ historical opportunities for research
- 🎯 Filter Accuracy: All major filters (NAICS, PSC, set-aside, geographic, dates) verified and working
Installation
npm install @lineai/gov-dealsQuick Start
Using SAM.gov API (Live Data)
import { SamApi } from '@lineai/gov-deals';
// Initialize with your SAM.gov API key
const api = new SamApi({
apiKey: process.env.SAM_API_KEY
});
// Search for construction opportunities
const results = await api.opportunities.searchConstruction({
keywords: 'renovation'
}, {
limit: 25
});
// Get specific opportunity details
const opportunity = await api.opportunities.getById('notice-id');
const description = await api.opportunities.getDescription('notice-id');
// Get opportunity by SAM.gov URL
const opp = await api.opportunities.getByUrl('https://sam.gov/opp/abc123.../view');Using Supabase (Historical Data - No API Key Required)
import { createSupabaseApi } from '@lineai/gov-deals';
// Initialize with Supabase credentials
const api = createSupabaseApi(
'https://your-project.supabase.co',
'your-anon-key'
);
// Same interface as SamApi
const results = await api.opportunities.search({
naicsCodes: ['236220'], // Commercial construction
placeOfPerformanceStates: ['CA', 'TX'],
postedFrom: '2025-01-01'
}, {
limit: 50
});Important Note: All historical records in the Supabase database have active: "No" status as they represent past opportunities. When searching historical data:
- Don't use
activeOnly: trueas it will return zero results - Use date ranges to find opportunities from specific time periods
- All opportunities are inactive but contain valuable historical information
Using CSV Files (Offline Development)
import { CsvApi } from '@lineai/gov-deals';
// Initialize with CSV file path
const api = new CsvApi({
csvPath: './data/opportunities.csv'
});
// Same interface for searching
const results = await api.opportunities.search({
keywords: 'courthouse'
});Search with AI-Powered Guidance
The library provides intelligent search tips to help optimize your queries:
const results = await api.opportunities.search({
keywords: 'construction repair', // Multiple keywords use AND logic
naicsCodes: ['999999'] // Non-existent code
});
// Results include helpful tips:
console.log(results.searchTips);
// [
// "Multiple keywords use AND logic - try single keywords for broader results",
// "No results for specified codes - try broader classification codes or remove code filters"
// ]AI Guidance Features
- Multiple Keywords: Warns about AND logic behavior
- Geographic Searches: Explains keyword vs filter differences
- Invalid Operators: Alerts about unsupported OR/AND/| operators
- Filter Optimization: Suggests combinations for better results
- Data Quality: Warns about potential issues with certain filter types
Search Filters
All data sources support the same comprehensive search filters:
interface SearchFilters {
// Text search
keywords?: string; // Search in titles
// Classification
naicsCodes?: string[]; // NAICS industry codes
pscCodes?: string[]; // Product/Service codes
// Opportunity types
types?: OpportunityType[]; // 'o' = Solicitation, 's' = Special Notice, etc.
// Set-asides
setAsideTypes?: SetAsideType[]; // 'SBA', 'WOSB', 'HZC', etc.
// Location
placeOfPerformanceStates?: string[]; // State codes: ['CA', 'TX']
placeOfPerformanceZips?: string[]; // ZIP codes
// Dates
postedFrom?: string; // YYYY-MM-DD
postedTo?: string; // YYYY-MM-DD
responseDeadlineFrom?: string; // YYYY-MM-DD
responseDeadlineTo?: string; // YYYY-MM-DD
// Status
activeOnly?: boolean; // Filter active opportunities
}Construction Industry Focus
The library includes built-in support for construction-related NAICS codes:
import { CONSTRUCTION_NAICS_CODES, getConstructionNAICSCodes } from '@lineai/gov-deals';
// Pre-configured construction search
const results = await api.opportunities.searchConstruction();
// Get all construction NAICS codes
const naicsCodes = getConstructionNAICSCodes();
// Returns: ['236220', '236210', '238210', ...]
// Check if a NAICS code is construction-related
const isConstruction = isConstructionNAICS('236220'); // trueIncluded Construction NAICS Codes
- 236220: Commercial and Institutional Building Construction
- 236210: Industrial Building Construction
- 236118: Residential Remodeling
- 238210: Electrical Contractors
- 238220: Plumbing, Heating, and Air-Conditioning
- 238310: Drywall and Insulation
- 238320: Painting and Wall Covering
- 238910: Site Preparation
- 238160: Roofing Contractors
- 238110: Poured Concrete Foundation
Opportunity Types
Use these codes for the types filter:
| Code | Description |
|------|-------------|
| o | Solicitation |
| p | Presolicitation |
| a | Award Notice |
| s | Special Notice |
| k | Combined Synopsis/Solicitation |
| u | Justification |
| r | Sources Sought |
| g | Sale of Surplus Property |
| i | Intent to Bundle Requirements |
Set-Aside Types
Common set-aside codes for the setAsideTypes filter:
| Code | Description |
|------|-------------|
| SBA | Total Small Business |
| WOSB | Women-Owned Small Business |
| EDWOSB | Economically Disadvantaged WOSB |
| HZC | HUBZone Competitive |
| HZS | HUBZone Sole Source |
| SDVOSBC | Service-Disabled Veteran-Owned (Competitive) |
| SDVOSBS | Service-Disabled Veteran-Owned (Sole Source) |
| 8A | 8(a) Sole Source |
| 8AN | 8(a) Set-Aside |
| VSA | Veteran-Owned (VA specific) |
Verified Filter Behavior
All search filters have been thoroughly tested and verified to work correctly:
✅ Working Filters
- Keywords: Case-insensitive, searches titles only, multiple keywords use AND logic
- NAICS Codes: 100% accuracy, supports all formats (2-6 digits)
- PSC Codes: 100% accuracy, proper classification filtering
- Set-Aside Types: All types working, realistic result distributions
- Geographic Filters: State filters working, zip codes work with real data
- Date Ranges: Posted dates working perfectly, proper validation
- Opportunity Types: 6/7 types working (Special Notice has data quality issues)
🧭 Search Tips Provided
The library automatically provides contextual guidance:
- Multiple Keywords:
"maintenance repair"→ Suggests single keywords for broader results - State Names in Keywords:
"Texas construction"→ Suggests using state filter instead - Invalid Operators:
"construction OR repair"→ Explains operators don't work - Rare Set-Asides:
HZCfilter → Suggests more common alternatives likeSBA - High Results: Large result sets → Suggests adding more filters
- Zero Results: No matches → Provides specific suggestions based on filters used
Examples
Find Recent Construction Opportunities in Multiple States
const results = await api.opportunities.search({
naicsCodes: ['236220', '238210'],
placeOfPerformanceStates: ['CA', 'TX', 'FL'],
postedFrom: '2025-01-01',
types: ['o', 'k'], // Solicitations and Combined Synopsis
setAsideTypes: ['SBA', 'WOSB']
}, {
limit: 100,
page: 1
});
console.log(`Found ${results.totalRecords} opportunities`);
results.opportunitiesData.forEach(opp => {
console.log(`${opp.title} - ${opp.naicsCode} - ${opp.placeOfPerformance?.state}`);
});Search by Keywords and Location
const results = await api.opportunities.search({
keywords: 'courthouse renovation',
placeOfPerformanceStates: ['NY'],
responseDeadlineFrom: '2025-07-01'
});Get Full Opportunity Details
// Get basic opportunity data
const opportunity = await api.opportunities.getById('abc123');
// Get full description (often contains detailed requirements)
const description = await api.opportunities.getDescription('abc123');
// Get opportunity from SAM.gov URL (flexible input handling)
const opp1 = await api.opportunities.getByUrl('https://sam.gov/opp/abc123.../view');
const opp2 = await api.opportunities.getByUrl('sam.gov/opp/abc123.../view');
const opp3 = await api.opportunities.getByUrl('abc123'); // Just the ID
const opp4 = await api.opportunities.getByUrl('invalid-url'); // Returns undefinedData Sources Comparison
| Feature | SAM.gov API | Supabase | CSV | |---------|-------------|----------|-----| | Real-time data | ✅ | ❌ | ❌ | | Historical data | ❌ | ✅ (71,969+ records) | ✅ | | API key required | ✅ | ❌ | ❌ | | Internet required | ✅ | ✅ | ❌ | | Search performance | Good | Excellent | Good | | Data completeness | Full | Full | Depends on CSV | | Active opportunities | ✅ | ❌ (all inactive) | Depends on CSV | | Date range | Current | 2018-2025 | Depends on CSV | | AI Search Guidance | ✅ | ✅ | ✅ | | Verified Filters | ✅ All working | ✅ All working | ✅ All working | | URL-based Access | ✅ getByUrl() | ✅ getByUrl() | ✅ getByUrl() |
Environment Variables
# For SAM.gov API
SAM_API_KEY=your-sam-gov-api-key
# For Supabase (optional - can pass directly to function)
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_ANON_KEY=your-anon-keyError Handling
The library throws typed errors for better error handling:
import { ApiError, AuthenticationError, ValidationError } from '@lineai/gov-deals';
try {
const results = await api.opportunities.search({ /* ... */ });
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Invalid API key');
} else if (error instanceof ValidationError) {
console.error('Invalid search parameters:', error.message);
} else if (error instanceof ApiError) {
console.error('API error:', error.status, error.message);
}
}TypeScript Support
Full TypeScript support with strict typing:
import type {
SamOpportunity,
SamOpportunitySearchFilters,
OpportunityType,
SetAsideType
} from '@lineai/gov-deals';
// All responses and parameters are fully typed
const filters: SamOpportunitySearchFilters = {
naicsCodes: ['236220'],
types: ['o'] as OpportunityType[],
activeOnly: true
};Contributing
See CONTRIBUTING.md for development setup and guidelines.
License
MIT
Additional Documentation
- Search Guidance System - Complete guide to AI-powered search tips and filter behavior
- API Comparison Guide - Detailed comparison of SAM.gov, Supabase, and CSV data sources
- Supabase Integration Guide - Guide for using the Supabase historical data API
- Historical Data Guide - Working with historical opportunities data
- Implementation Guide - Technical implementation details
