| name | usaspending-api-helper |
| description | Expert knowledge of USA Spending API integration including filter building, award type codes, agency tiers, and API endpoints. Use when modifying API requests, adding search filters, debugging API responses, or extending search functionality. |
USA Spending API Helper
This skill provides expert knowledge of the USA Spending API integration used in this project.
API Endpoints
Production Base: https://api.usaspending.gov
Proxied Endpoints in server.js:
POST /api/search→ proxies to/api/v2/search/spending_by_award/POST /api/count→ proxies to/api/v2/search/spending_by_award_count/
Award Type Codes
Contracts
- A: BPA Call (Blanket Purchase Agreement)
- B: Purchase Order
- C: Delivery Order
- D: Definitive Contract
Grants
- 02: Block Grant
- 03: Formula Grant
- 04: Project Grant
- 05: Cooperative Agreement
IDVs (Indefinite Delivery Vehicles)
- IDV_A: GWAC (Government-Wide Acquisition Contract)
- IDV_B: IDC (Indefinite Delivery Contract)
- IDV_B_A: IDV_B_A
- IDV_B_B: IDV_B_B
- IDV_B_C: IDV_B_C
- IDV_C: IDV_C
- IDV_D: IDV_D
- IDV_E: IDV_E
Filter Building Logic (buildFilters() in script.js)
Agency Filters
The application supports two-tier agency filtering:
- Toptier: Main department level (e.g., Department of Defense)
- Subtier: Sub-agency level (e.g., Army, Navy)
Agency Filter Structure:
{
name: "agency_code", // Agency code from API
tier: "toptier|subtier", // Agency tier level
type: "awarding|funding" // Agency relationship to award
}
Logic:
- Check if toptier or subtier agency is selected
- Determine if it's awarding or funding agency
- Add to appropriate filter array
Date Ranges
- Default: Last 180 days if no dates specified
- Format: YYYY-MM-DD
- Structure:
time_period: [{
start_date: "YYYY-MM-DD",
end_date: "YYYY-MM-DD"
}]
Award Types
- Default Behavior: If no award type selected, defaults to contracts A-D
- Multiple Selection: User can select multiple award types
- Validation: Award types are validated against known codes
Keywords
- Searches across award descriptions and recipient names
- Case-insensitive matching
- Supports partial matches
Response Fields
Standard fields requested from the API (see buildFilters() fields array):
Award Information:
Award IDAward AmountAward TypeDescription
Recipient Information:
Recipient Namerecipient_ueirecipient_id
Agency Information:
Awarding AgencyAwarding Sub Agencyawarding_agency_codeFunding AgencyFunding Sub Agencyfunding_agency_code
Additional Fields:
Place of PerformanceInfrastructure OutlaysInfrastructure ObligationsLast Modified DateBase Obligation Date
Common Tasks
Adding a New Search Filter
Update HTML form (
public/index.html):<input type="text" id="newFilterField" placeholder="New Filter">Modify buildFilters() (
public/script.js):const newFilterValue = document.getElementById('newFilterField').value; if (newFilterValue) { filters.new_filter = newFilterValue; }Test filter combinations to ensure compatibility
Update documentation if user-facing change
Modifying API Response Fields
- Locate fields array in
buildFilters()function - Add/remove fields as needed:
fields: [ "Award ID", "Award Amount", "New Field Name" // Add here ] - Update renderResults() to handle new fields in table
- Test with various search queries
Debugging API Issues
Common Issues:
- No results returned: Check date range and award type defaults
- API errors: Check server.js console logs for detailed error messages
- Filter not working: Verify filter structure matches API expectations
- Pagination issues: Ensure limit and page parameters are correct
Debugging Steps:
- Open browser console to see request payload
- Verify filter structure in Network tab
- Check server.js logs for API response errors
- Test query directly against USA Spending API if needed
- Compare working queries with failing ones
Testing API Queries
Test Cases to Consider:
- Empty search (should use defaults)
- Single award type selection
- Multiple award type selection
- Agency filtering (toptier and subtier)
- Date range filtering
- Keyword search
- Pagination (page 1, 2, last page)
- Edge cases (no results, max results)
Implementation Patterns
Error Handling
try {
const response = await fetch('/api/search', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(filters)
});
if (!response.ok) {
throw new Error(`API error: ${response.statusText}`);
}
const data = await response.json();
// Process data
} catch (error) {
console.error('Error fetching results:', error);
// Display user-friendly error
}
Pagination Pattern
const limit = 10; // Records per page
const offset = (currentPage - 1) * limit;
const filters = {
...buildFilters(),
limit: limit,
page: currentPage
};
Dynamic URL Generation
The application generates usaspending.gov URLs for recipients:
const params = new URLSearchParams({
hash: recipientHash,
award_type: selectedAwardTypes
});
const url = `https://www.usaspending.gov/recipient/${recipientId}?${params}`;
Best Practices
- Always validate filter inputs before sending to API
- Use meaningful default values (e.g., last 180 days)
- Log errors with context for easier debugging
- Handle empty results gracefully with user-friendly messages
- Test pagination edge cases (first page, last page, single page)
- Keep award type codes synchronized with USA Spending API documentation
- Cache agency lists if fetching from API to reduce requests
- Validate date ranges (start_date <= end_date)
File Locations
- Server proxy:
server.jslines 15-42 - Client filter logic:
public/script.jsbuildFilters() function - Search form:
public/index.html - Result rendering:
public/script.jsrenderResults() function
Resources
- USA Spending API Documentation: https://api.usaspending.gov/docs/
- Award Data Dictionary: https://www.usaspending.gov/data-dictionary
- Agency Codes: Available via
/api/v2/references/toptier_agencies/endpoint