Search opportunities
Updated 9/17/2025 see our OpenAPI doc for most recent changes.
Endpoint: POST /v1/opportunities/search
POST /v1/opportunities/search
Search for grant opportunities using various filters and criteria.
Caveats
Search will only return a maximum of 10,000 opportunities. Any opportunties past that will be culled for performance. If you are receiving the maximum amount of opportunities as a response there is a good chance that you are not getting all possible results returned. In that case it is recommended to add more filters to get a smaller subset of opportunities. If you want to get an export of all opportunities see the extracts endpoint.
Search should return the same data as GET opportunity, except attachments are not included and the data is cached in search hourly.
Get Opportunity Details
Endpoints:
GET /v1/opportunities/{opportunity_id}
(UUID format)
Retrieve detailed information about a specific opportunity.
Search Parameters
The opportunity search endpoint accepts the following parameters:
Query Parameters
query
(string, optional): Free-text search across multiple fieldsExample:
"research"
,"education funding"
Maximum length: 100 characters
query_operator
(string, optional): How to combine search termsValues:
"AND"
(default),"OR"
Filters
Agency & Organization
top_level_agency
: Filter by agency codeExample:
{"one_of": ["USAID", "DOC"]}
Funding Details
funding_instrument
: Type of fundingValues:
"cooperative_agreement"
,"grant"
, etc.Example:
{"one_of": ["grant"]}
funding_category
: Category of fundingValues:
"recovery_act"
,"arts"
,"natural_resources"
, etc.
Eligibility
applicant_type
: Who can applyValues:
"state_governments"
,"county_governments"
,"individuals"
, etc.Example:
{"one_of": ["state_governments", "nonprofits"]}
Status & Timing
opportunity_status
: Current statusValues:
"forecasted"
,"posted"
,"closed"
,"archived"
Example:
{"one_of": ["posted", "forecasted"]}
post_date
: When opportunity was postedExample:
{"start_date": "2024-01-01", "end_date": "2024-12-31"}
close_date
: Application deadlineExample:
{"start_date": "2024-06-01"}
Financial Filters
award_floor
: Minimum award amountExample:
{"min": 10000}
award_ceiling
: Maximum award amountExample:
{"max": 1000000}
expected_number_of_awards
: Expected number of awardsExample:
{"min": 5, "max": 25}
estimated_total_program_funding
: Total program fundingExample:
{"min": 100000, "max": 250000}
Other Filters
assistance_listing_number
: Specific CFDA numberFormat:
##.###
(e.g., "45.149")Example:
{"one_of": ["45.149"]}
is_cost_sharing
: Whether cost sharing is requiredExample:
{"one_of": [true]}
Pagination & Sorting
pagination
(required): Controls result pagination and sorting{ "page_offset": 1, "page_size": 25, "sort_order": [ { "order_by": "opportunity_id", "sort_direction": "descending" } ] }
Sort Options:
relevancy
,opportunity_id
,opportunity_number
opportunity_title
,post_date
,close_date
agency_code
,agency_name
,top_level_agency_name
award_floor
,award_ceiling
Response Format
format
(optional): Response formatValues:
"json"
(default),"csv"
CSV format returns a downloadable file
Code Examples
import requests
import json
# Your API configuration
API_KEY = "your_api_key_here"
BASE_URL = "https://api.simpler.grants.gov"
headers = {
"X-API-Key": API_KEY,
"Content-Type": "application/json"
}
# Basic search request
search_payload = {
"query": "research",
"filters": {
"opportunity_status": {"one_of": ["posted", "forecasted"]},
"funding_instrument": {"one_of": ["grant"]},
"agency": {"one_of": ["NSF", "NIH"]}
},
"pagination": {
"page_offset": 1,
"page_size": 25,
"sort_order": [
{
"order_by": "post_date",
"sort_direction": "descending"
}
]
}
}
# Make the request
response = requests.post(
f"{BASE_URL}/v1/opportunities/search",
headers=headers,
json=search_payload
)
if response.status_code == 200:
data = response.json()
opportunities = data["data"]
print(f"Found {len(opportunities)} opportunities")
for opp in opportunities:
print(f"- {opp['opportunity_title']}")
print(f" Agency: {opp['agency_name']}")
print(f" Deadline: {opp.get('close_date', 'No deadline specified')}")
print()
else:
print(f"Error: {response.status_code} - {response.text}")
Response Format
JSON Response Structure
{
"message": "Success",
"data": [
{
"opportunity_id": "12345678-1234-1234-1234-123456789012",
"opportunity_number": "EPA-R9-SFUND-23-003",
"opportunity_title": "Superfund Site Remediation Research",
"agency_code": "EPA",
"agency_name": "Environmental Protection Agency",
"post_date": "2024-01-15",
"close_date": "2024-06-30",
"opportunity_status": "posted",
"funding_instrument": "grant",
"funding_category": "environment",
"award_floor": 50000,
"award_ceiling": 500000,
"estimated_total_program_funding": 2000000,
"expected_number_of_awards": 4,
"applicant_types": ["nonprofits", "universities"],
"summary": "Funding for research into innovative remediation technologies...",
"is_cost_sharing": false
}
],
"pagination_info": {
"page_offset": 1,
"page_size": 25,
"total_pages": 15,
"total_records": 367
},
"facet_counts": {
"agency_name": {
"EPA": 45,
"NSF": 32,
"NIH": 28
},
"funding_instrument": {
"grant": 89,
"cooperative_agreement": 16
}
}
}
Error Handling
Common HTTP Status Codes
200 OK: Request successful
400 Bad Request: Invalid request parameters
401 Unauthorized: Missing or invalid API key
403 Forbidden: API key lacks required permissions
429 Too Many Requests: Rate limit exceeded
500 Internal Server Error: Server error
Error Response Format
{
"message": "Error description",
"status_code": 400,
"errors": [
{
"field": "pagination.page_size",
"message": "Must be between 1 and 100"
}
]
}
Last updated
Was this helpful?