Contracts¶
Contracts are awards (FPDS “definitive contracts”) exposed at /api/contracts/. For field definitions, see the Contracts Data Dictionary.
Endpoints¶
GET /api/contracts/(list + filtering + search + ordering)GET /api/contracts/{key}/(detail)GET /api/contracts/{key}/transactions/(detail transactions)GET /api/contracts/{key}/subawards/(subawards scoped to a contract)
Related “scoped” list endpoints that behave like /api/contracts/:
GET /api/entities/{uei}/contracts/GET /api/idvs/{key}/awards/(child awards under an IDV)GET /api/vehicles/{uuid}/orders/(task orders under a vehicle)
Filtering¶
Swagger is the canonical list of query parameters. These are the core filters most people use day-to-day.
Text / parties¶
| Param | What it does |
|---|---|
search | Full-text-ish search across contract search vectors (good for keywords). |
recipient | Search by recipient/vendor name. |
uei | Filter by recipient UEI (exact). |
piid | Filter by PIID (case-insensitive). |
solicitation_identifier | Filter by solicitation identifier (exact). |
Agencies¶
| Param | What it does |
|---|---|
awarding_agency | Filter by awarding agency (code/name/abbrev; best-effort matching). Implemented via organization UUID for performance; response awarding_office shape unchanged. |
funding_agency | Filter by funding agency (code/name/abbrev; best-effort matching). Implemented via organization UUID for performance; response funding_office shape unchanged. |
Codes / set-asides¶
| Param | What it does |
|---|---|
naics | Filter by NAICS. |
psc | Filter by PSC. |
set_aside | Filter by set-aside. |
Dates / fiscal years¶
All date filters require YYYY-MM-DD format. Invalid dates or inverted ranges return 400. See Date filters for details.
| Param | What it does |
|---|---|
award_date | Award date (exact). |
award_date_gte, award_date_lte | Award date range. |
fiscal_year | Fiscal year (exact, YYYY). |
fiscal_year_gte, fiscal_year_lte | Fiscal year range (YYYY). |
Period of performance¶
| Param | What it does |
|---|---|
pop_start_date_gte, pop_start_date_lte | Period of performance start date range. |
pop_end_date_gte, pop_end_date_lte | Period of performance current end date range. |
expiring_gte, expiring_lte | Ultimate completion date range (useful for “expiring soon”). |
Dollars / types¶
| Param | What it does |
|---|---|
obligated | Filter by obligated amount (exact USD value). |
obligated_gte, obligated_lte | Obligated amount range (USD). |
award_type | Award type code. |
ordering | Sort results (allowlist: award_date, obligated, total_contract_value; prefix with - for descending). |
Filter value syntax (AND / OR)¶
Some filters support basic boolean syntax:
- Use
|orORfor OR - Use
,orANDfor AND
Example: naics=541511|541512
Ordering¶
Contracts support ordering= with a strict allowlist:
award_dateobligatedtotal_contract_value
Examples:
- Newest first:
GET /api/contracts/?ordering=-award_date - Largest obligations first:
GET /api/contracts/?ordering=-obligated
Pagination¶
High-volume award endpoints use cursor-based (keyset) pagination.
- Use
limitto control page size. - Follow the
next/previousURLs in responses. - If you’re constructing requests manually, you’ll typically pass a
cursorparameter from thenextURL.
SDK examples¶
Search + ordering + shaping¶
import os
from tango import ShapeConfig, TangoClient
client = TangoClient(api_key=os.environ["TANGO_API_KEY"])
resp = client.list_contracts(
keyword="cloud services", # SDK maps to API param: search
awarding_agency="4700", # GSA
fiscal_year=2024,
sort="award_date", # SDK maps (sort+order) -> API ordering
order="desc",
limit=10,
shape=ShapeConfig.CONTRACTS_MINIMAL,
)
for c in resp.results:
print(c.piid, c.award_date, c.recipient.display_name)
import { ShapeConfig, TangoClient } from "@makegov/tango-node";
const client = new TangoClient({ apiKey: process.env.TANGO_API_KEY });
const resp = await client.listContracts({
keyword: "cloud services", // SDK maps to API param: search
awarding_agency: "4700", // GSA
fiscal_year: 2024,
sort: "award_date", // SDK maps (sort+order) -> API ordering
order: "desc",
limit: 10,
shape: ShapeConfig.CONTRACTS_MINIMAL,
});
for (const c of resp.results) {
console.log(c.piid, c.award_date, c.recipient.display_name);
}
Cursor pagination (using the next URL)¶
import os
from urllib.parse import parse_qs, urlparse
from tango import TangoClient
client = TangoClient(api_key=os.environ["TANGO_API_KEY"])
resp = client.list_contracts(limit=25, sort="award_date", order="desc")
print("next:", resp.next)
if resp.next:
qs = parse_qs(urlparse(resp.next).query)
cursor = (qs.get("cursor") or [None])[0]
if cursor:
resp2 = client.list_contracts(limit=25, cursor=cursor, sort="award_date", order="desc")
print("page 2 results:", len(resp2.results))
import { TangoClient } from "@makegov/tango-node";
const client = new TangoClient({ apiKey: process.env.TANGO_API_KEY });
const resp = await client.listContracts({ limit: 25, sort: "award_date", order: "desc" });
console.log("next:", resp.next);
if (resp.next) {
const url = new URL(resp.next);
const cursor = url.searchParams.get("cursor");
if (cursor) {
const resp2 = await client.listContracts({ limit: 25, cursor, sort: "award_date", order: "desc" });
console.log("page 2 results:", resp2.results.length);
}
}