SBIR/STTR¶
The SBIR/STTR endpoints expose Small Business Innovation Research and Small Business Technology Transfer topics across every participating agency (DoD, NIH, NSF, NASA, DOE, DOT and more), plus the DoD DSIP solicitation cycles they belong to. For field definitions, see the SBIR Data Dictionary.
Authentication: SBIR endpoints require authentication (API key or OAuth2). Unauthenticated requests receive HTTP 401. Available on every plan, including Free — no tier gating on any field.
Endpoints¶
GET /api/sbir/topics/— SBIR/STTR topics (all agencies). Detail lookup bytopic_id.GET /api/sbir/solicitations/— DoD DSIP solicitation cycles. Detail lookup bysolicitation_id.
Each topic belongs to a parent that funds it — a DoD DSIP cycle, a SAM.gov notice, or a Grants.gov announcement — so you can follow a topic through to the opportunity or grant behind it. Topics span every participating agency; solicitations are DoD (DSIP) only.
Topics¶
GET /api/sbir/topics/ — one record per SBIR/STTR topic. Detail: GET /api/sbir/topics/{topic_id}/.
The parent ladder¶
Each topic links to at most one parent, resolved in priority order:
solicitation(*)— the parent DoD DSIP cycle (most DoD topics), joined on the topic'scycle_nameor itssolicitation_number. When both match, thecycle_namematch wins: topics fed from DSIP carry a cycle name, while a cycle'ssolicitation_numbercan be empty.opportunity(*)— the parent SAM.gov notice (e.g. DOT, ARPA-H topics that hang off a notice).grant(*)— the parent Grants.gov announcement (e.g. NIH topics, joined on opportunity number).
A non-DoD topic with no DSIP parent returns solicitation: null and links through opportunity or grant instead. A topic's own close_date reflects its individual schedule and outranks the parent BAA's window — a topic can close on its own date inside an otherwise-open parent.
Lifecycle: activity¶
activity is derived at query time as open, closed, or unknown (topics with no usable date roster). Filter on it with ?activity=open. solicitation_status is sbir.gov's own raw Open/Closed string (source data, not derived) and is exposed separately.
Filtering¶
Date filters require YYYY-MM-DD (invalid dates or inverted ranges return 400, see Date filters). Apart from agency, these filters are single-value (no | OR).
| Param | What it does |
|---|---|
activity | Lifecycle: open, closed, or unknown. |
agency | Agency, resolved to an organization and rolled up its hierarchy; accepts several values for OR, separated by a pipe or by OR (?agency=DOD OR NSF). Topics carry department-level values (DOD, NSF, DOE, NASA, HHS, DHS, DOT, EPA, DOC, USDA, ED) and link to that department, so a component agency resolves but matches nothing — NIH topics are filed under HHS, and ?agency=NIH returns none. A value that resolves to no organization falls back to a partial match on the raw agency text, with a warning in meta. |
topic_number | Topic number, partial match. |
solicitation_number | Parent solicitation (BAA) number, partial match. |
cycle_name | DoD DSIP cycle name, exact match (case-sensitive), e.g. DOD_SBIR_2026_P1_CBZ. Only topics fed from DSIP carry one; the rest hold an empty string. This differs from cycle_name on /api/sbir/solicitations/, which is a partial match. |
year | Solicitation year (exact). |
doc_source | Document source: grants_gov, dsip, sam_gov, other, none (exact, case-insensitive). |
open_date_after, open_date_before | Open-date range. |
close_date_after, close_date_before | Close-date range. |
release_date_after, release_date_before | Release-date range. |
search | Full-text search over title, description, and topic number. |
There is no program filter on topics — SBIR/STTR program lives on the parent solicitation. Filter topics by their parent instead (solicitation_number), or query /api/sbir/solicitations/?program=STTR.
Ordering¶
ordering= allowlist: activity, close_date, open_date, release_date, year, modified. Default is newest-modified first.
Shaping¶
- List default:
topic_id,title,agency,year,topic_number,solicitation_number,cycle_name,release_date,open_date,close_date,activity,solicitation_status,topic_url,official_solicitation_url - Detail default: every allowed leaf field plus
solicitation(*),opportunity(*),grant(*),organization(*)
Expandable relations and the keys they resolve to:
solicitation(*)→solicitation_id,solicitation_number,title,program,cycle_name,year,start_date,end_date,out_of_cycle,solicitation_statusopportunity(*)→opportunity_id,title,solicitation_number,response_deadlinegrant(*)→grant_id,opportunity_number,title,response_dateorganization(*)→ the canonical 7-key office payload (organization_id,office_code,office_name,agency_code,agency_name,department_code,department_name), resolved from the topic'sagencytext.nullwhen the value resolves to no organization.
Solicitations¶
GET /api/sbir/solicitations/ — one record per DoD DSIP solicitation cycle. Detail: GET /api/sbir/solicitations/{solicitation_id}/.
Lifecycle: activity¶
activity is derived from end_date as open or closed (no unknown state — solicitations always have a cycle window). solicitation_status is the raw feed status token, exposed separately.
BAA documents¶
The documents(*) expansion returns the solicitation's BAA PDF inventory. Each document resolves to document_id, filename, cycle_name, s3_key, file_size, extraction_status, n_pages, n_chars.
Filtering¶
Date filters require YYYY-MM-DD. Single-value (no | OR).
| Param | What it does |
|---|---|
activity | Lifecycle: open or closed. |
program | Program: SBIR or STTR (exact, case-insensitive). |
solicitation_number | Solicitation number, partial match. |
cycle_name | DSIP cycle directory name, partial match. (The topics filter of the same name is an exact match.) |
solicitation_status | Raw feed status token (exact, case-insensitive). |
out_of_cycle | Boolean. |
year | Solicitation year (exact). |
start_date_after, start_date_before | Cycle start-date range. |
end_date_after, end_date_before | Cycle end-date range. |
search | Full-text search over title and solicitation number. |
There is no agency filter — DSIP solicitations are DoD only.
Ordering¶
ordering= allowlist: activity, start_date, end_date, year, modified. Default is newest-modified first.
Shaping¶
- List default:
solicitation_id,solicitation_number,title,program,cycle_name,year,start_date,end_date,out_of_cycle,activity,solicitation_status,sol_download_url - Detail default: every allowed leaf field plus
topics(*),documents(*)andorganization(*)
Expandable relations:
documents(*)→document_id,filename,cycle_name,s3_key,file_size,extraction_status,n_pages,n_charstopics(*)→topic_id,title,agency,topic_number,close_date,topic_url(a reduced view; the full topic shape lives at/api/sbir/topics/)organization(*)→ the canonical 7-key office payload (organization_id,office_code,office_name,agency_code,agency_name,department_code,department_name). Always the Department of Defense, since DSIP solicitations are DoD only.
Pagination¶
Both resources use standard page-number pagination:
page(default 1)limit(default 25, max 100)
Examples¶
# Open HHS topics (this is where NIH topics live), timeline fields
GET /api/sbir/topics/?activity=open&agency=HHS&shape=topic_id,title,agency,open_date,close_date,activity
# A topic with its parent solicitation
GET /api/sbir/topics/?solicitation_number=SB251-01&shape=topic_id,title,topic_number,solicitation(solicitation_number,program,cycle_name)
# Open STTR solicitation cycles with their BAA documents
GET /api/sbir/solicitations/?activity=open&program=STTR&shape=solicitation_id,title,cycle_name,documents(filename,s3_key,n_pages)
# Solicitation detail with topics
GET /api/sbir/solicitations/{solicitation_id}/?shape=solicitation_id,title,program,topics(topic_id,title,close_date)
Notes:
*is only valid inside expansions. Use explicit field lists at the root.- Invalid
shapefields return HTTP 400 with structured validation errors.