Skip to article

Federal contract data · API implementation

The USAspending API: federal contract data at the right grain.

Build a reliable USAspending API pipeline for federal contracts with award filters, transaction grain, pagination, downloads and validation.

Published August 10, 202626 min readBy DanielReviewed by Alexandra

Use USAspending award search to discover a bounded contract population, then collect transactions or a generated file when the question is about activity. Keep prime contracts, IDVs, child orders, account data, and subawards at separate grains. Preserve signed obligations—including de-obligations—and use the monthly Full/Delta archive instead of paging through a nationwide history.

The API is public, V2 is current, and the official endpoint index says authorization is not presently required. That makes the first request easy. The hard part is choosing the representation that answers the question without repeating cumulative dollars, treating a vehicle ceiling as spend, or calling a late disclosure a new contract.

This guide owns that implementation boundary. For manual research, use the awarded-government-contracts guide. For the FPDS-to-SAM.gov engineering transition, use the Contract Awards API migration guide. For opportunity notices before award, use the SAM.gov Opportunities API guide.

Choose the smallest USAspending access mode that fits the job
01

Bounded discovery

POST /api/v2/search/spending_by_award/

Award-summary rows matching explicit filters and selected fields

Interactive research, narrow slices and award-ID discovery

02

Award drill-down

GET /api/v2/awards/{generated_internal_id}/

One award summary with agencies, recipient, dates, amounts and contract attributes

Record pages, enrichment and source-level spot checks

03

Action history

POST /api/v2/transactions/

Base action and later modifications, including negative obligations

Change history, deobligations and auditable amount reconstruction

04

Filtered export

POST /api/v2/download/search/

Asynchronous CSV job; poll the status URL returned by the API

Larger reproducible extracts without walking every JSON result page

05

Fiscal-year archive

Award Data Archive full / delta files

Pre-generated agency and fiscal-year transaction files

Historical bootstrap, periodic replay and API reconciliation

06

Database-scale work

PostgreSQL database snapshot

A 1.5 TB-plus restore path that can take hours

Research that truly needs the relational database, not routine collection

The JSON API is excellent for bounded collection. Large history is usually safer as an asynchronous download or archive replay.

USAspending API: the short answer

Build the pipeline in this order:

  1. Write down whether the output represents award summaries, contract transactions, IDVs, child orders, account-linked spending, or subawards.
  2. Fetch the current award-type reference and query prime contract codes A, B, C, and D separately from IDV codes.
  3. Use POST /api/v2/search/spending_by_award/ to discover a bounded population and retain generated_internal_id.
  4. Send an explicit date type. action_date, date_signed, last_modified_date, and new_awards_only answer different questions.
  5. Request at most 100 award rows, sort explicitly, and continue with both cursor values returned in page_metadata.
  6. Call GET /api/v2/awards/{generated_id}/ for one award's richer attributes and POST /api/v2/transactions/ for its action history.
  7. Treat federal_action_obligation as a signed transaction amount. Do not replace negative values with zero.
  8. Use POST /api/v2/download/search/ for a reproducible filtered transaction extract, then poll the returned status URL and save the completed ZIP promptly.
  9. Bootstrap a national or multi-year mirror from Contracts Full files and retain every monthly Delta in sequence; rebaseline if a delta is missed.
  10. Store raw requests, responses, files, hashes, source dates, schemas, counts, and validation results before publishing normalized data.

The source is comprehensive, but it is not instantaneous or semantically flat. A reliable collector makes the chosen grain and cutoff visible in every output.

Choose API, downloads, archives, or a database snapshot

USAspending exposes several access routes because one route cannot serve every workload.

Use award search for discovery

POST /api/v2/search/spending_by_award/ powers the Advanced Search award table. It is useful for finding a bounded set of awards by date, agency, recipient, location, NAICS, PSC, competition attributes, and other filters. It returns selected summary fields rather than the full contract transaction schema.

The route is a discovery surface, not a national replication protocol. Its current page limit is 100, the underlying search window is bounded, and results can change while a long crawl is running. The limit is enforced by the current pagination validator. Use narrow partitions and cursor continuation, or switch to a file route.

Use award detail and transaction history for focused enrichment

Once search returns a generated_internal_id, the award-detail endpoint supplies the richer award representation: identity, recipient, agencies and offices, dates, values, parent IDV, NAICS and PSC, place of performance, and linked account aggregates.

POST /api/v2/transactions/ supplies the action history used on the award page. That is the right route for understanding how one award's obligation changed over time. It is not the most efficient way to hydrate millions of awards.

Use generated downloads for a filtered extract

POST /api/v2/download/search/ starts an asynchronous ZIP generation job. It can return awards and transactions for the same filter contract, with CSV, TSV, or pipe-separated text output. Use it when a bounded analytical population needs more columns or more transaction rows than interactive search should deliver.

Use Full and Delta files for a maintained mirror

The Award Data Archive publishes Contracts_Full files by fiscal year and a cross-year Contracts_Delta file containing additions, corrections, and deletions since the prior monthly generation. The official Federal Spending Guide distinguishes these pre-generated archives from on-demand prime-transaction files.

For a nationwide warehouse, this is usually the durable route: establish a Full baseline, retain each Delta artifact, apply its correction indicator, and periodically rebuild to test the result.

Use the PostgreSQL snapshot only when the product needs the database

Treasury also publishes a PostgreSQL database snapshot. It is appropriate when downstream work genuinely needs USAspending's relational model, broad endpoint parity, or large joins across many source tables. It is a major operational commitment—the official API repository points to a populated production snapshot and restore workflow—so do not choose it merely to avoid writing one filtered download.

Filter to prime contracts and contract IDVs

The current award-type reference is available at:

GET https://api.usaspending.gov/api/v2/references/award_types/

For prime contracts, the live reference maps:

  • A to BPA Call;
  • B to Purchase Order;
  • C to Delivery Order; and
  • D to Definitive Contract.

Contract IDVs use a separate family: IDV_A, IDV_B, IDV_B_A, IDV_B_B, IDV_B_C, IDV_C, IDV_D, and IDV_E. They cover vehicles such as government-wide acquisition contracts, indefinite-delivery contracts, schedules, basic ordering agreements, and blanket purchase agreements.

Fetch the reference at runtime and snapshot it with the run. Descriptions and other award families can evolve. More importantly, do not send prime contract and IDV families in the same spending_by_award request: they expose different field maps and the current validator rejects mixed families.

The population decision should be explicit:

  • Contract actions and awarded work: query AD.
  • Vehicles and ceilings: query the IDV family separately.
  • Orders under vehicles: query AD, then retain the parent-award relationship.
  • Subcontracts: use subaward data as a separate reported population, not another prime-contract type.
  • Financial assistance: use the assistance codes and schemas, not the contract pipeline.

Do not freeze a UI label into the primary key. A BPA call and delivery order can both point to a parent vehicle, while a definitive contract usually does not. The type code describes the procurement form; it does not establish uniqueness.

Preserve awards, transactions, orders, and IDVs

USAspending's Analyst's Guide defines a prime award transaction as the base action or a later amendment or modification. A prime award summary rolls up the transactions that share the award's unique key. A transaction row is therefore not a separate contract, and an award-summary row is not an action taken during every period in which it appears.

Three grains that must stay distinct
01

Transaction

One reported contract action

federal_action_obligation

Keep base actions and modifications, including negative deobligations, as separate rows.

02

Award summary

Transactions rolled up under one source award key

total_obligated_amount

Use generated_internal_id or the documented unique key; PIID alone is not a universal key.

03

IDV / vehicle

Parent vehicle that can contain orders or calls

ceiling is not order obligation

Link through parent award context; do not add a vehicle ceiling to child-order obligations.

Safe direction: retain transactions, derive an award summary, then attach parent-vehicle context. Never reverse that relationship by treating every total as an additive row.

Use these storage grains:

  • contract_awards: one prime contract award summary, keyed by contract_award_unique_key or the generated award ID.
  • contract_transactions: one base action or modification, keyed by contract_transaction_unique_key or the source transaction ID.
  • contract_idvs: one ordering vehicle, keyed by its generated IDV identifier.
  • contract_relationships: one parent-IDV to child-award relationship, keyed by the parent and child source keys.
  • award_accounts: one set of account-linked award dimensions for a reporting period.
  • contract_subawards: one reported downstream subaward, using a source-derived composite rather than SubAwardNumber alone.

A PIID by itself is not the safest government-wide key. The generated contract key also accounts for agency and parent-IDV components. A UEI identifies the recipient, not the award. Keep the source-generated identifiers intact even if a warehouse adds its own surrogate key.

An IDV can contain contract awards and other IDVs. Its ceiling or potential value is not additive with the obligations on orders underneath it. Store parent and child records separately and choose one level before aggregating.

Make the first USAspending contract search request

The production endpoint is:

POST https://api.usaspending.gov/api/v2/search/spending_by_award/

This request returns contract awards with qualifying action activity in the first ten days of August 2026:

curl --fail-with-body -sS \
  --request POST \
  --url https://api.usaspending.gov/api/v2/search/spending_by_award/ \
  --header "Content-Type: application/json" \
  --data '{
    "filters": {
      "award_type_codes": ["A", "B", "C", "D"],
      "time_period": [{
        "start_date": "2026-08-01",
        "end_date": "2026-08-10",
        "date_type": "action_date"
      }]
    },
    "fields": [
      "Award ID",
      "Recipient Name",
      "Recipient UEI",
      "Award Amount",
      "Total Outlays",
      "Description",
      "Start Date",
      "End Date",
      "Last Modified Date",
      "Awarding Agency",
      "Awarding Agency Code",
      "Awarding Sub Agency",
      "Awarding Sub Agency Code",
      "NAICS",
      "PSC",
      "Contract Award Type",
      "generated_internal_id"
    ],
    "page": 1,
    "limit": 100,
    "sort": "Last Modified Date",
    "order": "desc"
  }'

The official spending-by-award contract requires filters and fields. Field names are exact and mostly display-style labels, with snake-case exceptions such as generated_internal_id. Treat the accepted field inventory as an API contract test.

A successful response has this shape:

{
  "spending_level": "awards",
  "limit": 100,
  "results": [
    {
      "internal_id": 361192699,
      "Award ID": "1202SB26M1828",
      "generated_internal_id":
        "CONT_AWD_1202SB26M1828_12C2_1202SB26T7445_12C2"
    }
  ],
  "page_metadata": {
    "page": 1,
    "hasNext": true,
    "last_record_unique_id": 361090664,
    "last_record_sort_value": "1786232434000"
  },
  "messages": []
}

Persist both the request and the response. internal_id is a database surrogate; the confusingly named generated_internal_id is the stable generated award identifier preferred by downstream detail routes. Also retain the messages array: the service uses it for warnings and implementation guidance.

Build an explicit USAspending request contract

A replayable USAspending search contract

Canonical award-summary route

https://api.usaspending.gov/api/v2/search/spending_by_award/
Method
POST with a JSON body
Public access
No authorization is currently required

Collector invariants

  • Filters are conjunctive: separate categories narrow one another.
  • The query is evidence: retain the exact body, retrieval time and response hash.
  • The identifier is source data: do not synthesize identity from labels.
01
filters.time_period

Every search

Send start_date, end_date and an explicit date_type

action_date can match an award because one qualifying transaction falls inside the window

02
filters.award_type_codes

Every contract search

Use A, B, C and D for contract awards

IDV codes describe a different population; add them only when vehicles are in scope

03
fields

Every summary search

Request only the columns the collector maps and validates

Include generated_internal_id; displayed Award ID can repeat across agency context

04
page + limit

Every summary search

Set both explicitly and continue while page_metadata.hasNext is true

Persist page metadata and prove that adjacent pages are distinct

05
sort + order

Every paged search

Choose a deterministic order and retain the request body

A page number without a stable query contract is not a replayable checkpoint

Make date meaning part of the query

The official search-filter contract supports several award-search date types:

  • action_date selects by transaction activity associated with the award;
  • date_signed refers to the base transaction's signed date;
  • last_modified_date selects records changed in the source representation; and
  • new_awards_only restricts results to awards whose base transaction date falls in the interval.

Always send one. If date_type is omitted, the documented defaults differ between the start and end comparisons. An explicit contract is easier to test and explain.

The sample request does not mean every returned contract began between August 1 and August 10. It means the award matched the action-date search behavior for that interval. Retrieve transactions before labeling the result “contracts awarded this week.”

Name the agency role

USAspending distinguishes awarding and funding agencies, and top-tier and sub-tier agencies. A filter such as:

{
  "agencies": [{
    "type": "awarding",
    "tier": "toptier",
    "name": "Department of Agriculture"
  }]
}

does not mean the same thing as a funding-agency filter. Preserve both roles and their codes. Do not collapse them into one agency column unless the published metric explicitly chooses a role.

Use codes for classification

NAICS describes the industry; PSC describes the product or service bought. Store code and description separately, snapshot the reference used, and avoid grouping by a truncated label. For market analysis, declare whether parent prefixes are intentionally rolled up. The government contract analysis guide shows how to publish classification coverage with the result.

Paginate and partition every bounded query

The award-search page limit is currently 100. The response supplies hasNext, last_record_unique_id, and last_record_sort_value. Continue with both cursor values:

{
  "page": 2,
  "limit": 100,
  "sort": "Last Modified Date",
  "order": "desc",
  "last_record_unique_id": 361090664,
  "last_record_sort_value": "1786232434000"
}

Keep filters, fields, sort, order, and limit unchanged. Treat both cursor values as opaque and save them with the raw page. Increment page for coherent metadata, but do not reinterpret the cursor as a row offset.

The current award-search implementation sets a 50,000-record result window. Cursor continuation avoids simple offset failure, but it does not turn a changing nationwide result set into a snapshot. Partition large jobs before collection:

  1. Choose a non-overlapping date interval and explicit date type.
  2. Split further by awarding agency or another stable category if the count remains large.
  3. Record partition bounds in the run manifest.
  4. Complete or fail the whole partition; do not silently publish a partial page series.
  5. Replay an overlap after the main run to capture late and corrected records.

For a full national history, stop designing ever-smaller search partitions and use the archive.

Build a complete USAspending API collector

A reliable USAspending collector
  1. 01

    Bound the query

    Fix award types, dates, date_type, agencies and fields; estimate the population before extraction.

  2. 02

    Capture raw evidence

    Store the request body, response, retrieval time, page metadata and content hash before normalization.

  3. 03

    Resolve source identity

    Use generated_internal_id for award detail and transaction retrieval; retain PIID and parent context as attributes.

  4. 04

    Separate the grains

    Persist action rows, award summaries and IDV relationships in different models with explicit amount semantics.

  5. 05

    Scale with downloads

    For large slices, submit an asynchronous export and poll the exact status_url returned by the API.

  6. 06

    Reconcile and publish

    Compare counts and amounts with the archive, explain late arrivals, then expose an accepted snapshot.

A successful HTTP response proves transport. The retained contract, source identity, grain model and reconciliation record prove a usable data release.

This Python example shows a bounded award-discovery loop. It is intentionally a discovery collector, not a nationwide mirror:

import json
import time
from pathlib import Path

import requests

BASE_URL = "https://api.usaspending.gov"
OUTPUT = Path("raw/usaspending/2026-08-10")
OUTPUT.mkdir(parents=True, exist_ok=True)

payload = {
    "filters": {
        "award_type_codes": ["A", "B", "C", "D"],
        "time_period": [{
            "start_date": "2026-08-01",
            "end_date": "2026-08-10",
            "date_type": "last_modified_date",
        }],
    },
    "fields": [
        "Award ID",
        "Recipient Name",
        "Recipient UEI",
        "Award Amount",
        "Last Modified Date",
        "generated_internal_id",
    ],
    "page": 1,
    "limit": 100,
    "sort": "Last Modified Date",
    "order": "asc",
}

session = requests.Session()
seen = set()

while True:
    response = session.post(
        f"{BASE_URL}/api/v2/search/spending_by_award/",
        json=payload,
        timeout=(10, 90),
    )
    response.raise_for_status()
    body = response.json()

    page_number = body["page_metadata"]["page"]
    raw_path = OUTPUT / f"awards-{page_number:05d}.json"
    raw_path.write_text(json.dumps({
        "request": payload,
        "response": body,
    }, indent=2))

    for row in body["results"]:
        award_id = row["generated_internal_id"]
        if award_id in seen:
            raise RuntimeError(f"duplicate award in partition: {award_id}")
        seen.add(award_id)

    metadata = body["page_metadata"]
    if not metadata["hasNext"]:
        break

    payload["page"] += 1
    payload["last_record_unique_id"] = metadata["last_record_unique_id"]
    payload["last_record_sort_value"] = metadata["last_record_sort_value"]
    time.sleep(0.25)

Production code also needs bounded retry behavior for connection failures, 429 responses, and eligible 5xx responses; exponential backoff with jitter; Retry-After support when present; a maximum wall-clock time; and a failed-run state. USAspending does not publish a numeric API rate quota. Do not invent one or interpret the absence of authorization as unlimited capacity.

Write immutable raw evidence before normalization. A failed transform can be corrected from the saved source response; a discarded response cannot.

Retrieve award details and transaction history

Use the generated award ID returned by search:

curl --fail-with-body -sS \
  "https://api.usaspending.gov/api/v2/awards/CONT_AWD_1202SB26M1828_12C2_1202SB26T7445_12C2/"

The award-detail contract calls the same value generated_unique_award_id. Preserve the ID even when the naming changes across endpoints. Nulls are normal in historical records and optional attributes; do not convert null to zero, empty text, or “not applicable” without evidence.

For transaction history:

curl --fail-with-body -sS \
  --request POST \
  --url https://api.usaspending.gov/api/v2/transactions/ \
  --header "Content-Type: application/json" \
  --data '{
    "award_id":
      "CONT_AWD_1202SB26M1828_12C2_1202SB26T7445_12C2",
    "page": 1,
    "limit": 5000,
    "sort": "action_date",
    "order": "asc"
  }'

The transaction-history contract allows up to 5,000 rows per page and returns hasNext, next, previous, and hasPrevious, but no total. Continue until hasNext is false and reconcile the unique transaction IDs.

The endpoint returns action date, action type, modification number, description, and the transaction's obligation. It does not expose the complete procurement transaction schema. Use a generated contract download or archive file when the model needs competition, solicitation, pricing, legislative mandate, or other full D1 attributes.

Calculate obligations without false totals

The USAspending Analyst's Guide separates a transaction's federal_action_obligation from the award's cumulative obligated amount:

  • A positive action obligation increases the government's binding commitment.
  • A zero-dollar action can still change dates, scope, description, or administrative attributes.
  • A negative action obligation is a de-obligation that reduces an earlier commitment.
  • The cumulative obligated amount is the signed sum over the award's transaction history.
  • An outlay is an actual payment, not another name for an obligation.

For activity in a period:

net_obligations_in_period
  = sum(federal_action_obligation)
    for transactions whose action_date is in the period

Retain negative and zero values. Do not sum the repeated cumulative award amount on every transaction row. Do not add prime-award obligations and subaward amounts; a subaward describes downstream use of the prime award and would double-count the funding.

Contract values need equally careful labels:

  • Base and exercised options describes the currently exercised contract value.
  • Potential value includes options that may never be exercised.
  • Obligations describe binding commitments created or reduced by actions.
  • Outlays describe payments drawn from linked financial data.

Potential value is not spend, guaranteed revenue, or current commitment. The award-value guide and analysis denominator guide cover the interpretation in more depth.

Use generated downloads for bounded extracts

Start a filtered transaction download with the same population contract:

curl --fail-with-body -sS \
  --request POST \
  --url https://api.usaspending.gov/api/v2/download/search/ \
  --header "Content-Type: application/json" \
  --data '{
    "filters": {
      "award_type_codes": ["A", "B", "C", "D"],
      "time_period": [{
        "start_date": "2026-08-01",
        "end_date": "2026-08-10",
        "date_type": "last_modified_date"
      }]
    },
    "spending_level": ["transactions"],
    "file_format": "csv"
  }'

The service currently returns HTTP 200 with a job description rather than HTTP 202:

{
  "status_url": "https://api.usaspending.gov/api/v2/download/status?file_name=...",
  "file_name": "PrimeTransactions_....zip",
  "file_url": "https://files.usaspending.gov/generated_downloads/....zip",
  "download_request": {}
}

Poll the exact status_url returned by the service. The download-status contract defines ready, running, finished, and failed, plus row, column, size, elapsed-time, and error fields.

When status is finished:

  1. Download the returned file_url, following redirects and accepting either an absolute or relative URL.
  2. Save the ZIP immediately; the status documentation describes same-day jobs.
  3. Verify the HTTP response, ZIP integrity, expected members, row counts, and required headers.
  4. Record SHA-256, byte size, request payload, status response, retrieval time, source cutoff, and parser version.
  5. Extract into a run-scoped immutable directory before normalization.

For one known award, the single-contract download route can generate a package containing contract transactions, federal-account funding, subcontracts, a readme, and a data dictionary. That is often more efficient and more complete than stitching together many page endpoints.

Use fiscal-year files and snapshots for bulk history

List the current contract archive artifacts:

curl --fail-with-body -sS \
  --request POST \
  --url https://api.usaspending.gov/api/v2/bulk_download/list_monthly_files/ \
  --header "Content-Type: application/json" \
  --data '{
    "agency": "all",
    "fiscal_year": 2026,
    "type": "contracts"
  }'

The current implementation requires all three fields. agency is all or a top-tier agency database ID, not its three-digit agency code. type is lowercase contracts or assistance. The monthly-file endpoint contract documents the request and response shape.

As of this article's August 10 research cutoff, the live response listed a FY2026 Contracts Full file and an all-fiscal-year Contracts Delta file, both prepared August 6. That is a point-in-time observation, not a permanent filename. Discover the current URLs at runtime.

Full and Delta have different jobs:

  • Full: all selected fiscal-year contract transactions through the preparation date.
  • Delta: additions, corrections, and deletions since the preceding monthly generation, across fiscal years.
  • correction_delete_ind = C: replace or update the identified transaction.
  • correction_delete_ind = D: remove or tombstone the identified transaction.
  • blank correction indicator: add the transaction.

Retain every Delta in arrival order. The listing endpoint exposes the current artifacts, not a guaranteed archive of every delta generation. If one was missed, establish a new Full baseline instead of applying the latest Delta to an older state and calling the result complete.

The files reach back farther than interactive search. The search contract begins at October 1, 2007, while download routes can access award records from fiscal year 2001. For a historical product, publish the start date and the observed completeness by year.

Choose the full database snapshot only when these flattened files cannot support the required joins. A snapshot adds restore time, storage, database upgrades, indexing, and schema operations to the product. Those costs are justified for some research systems, but not for an ordinary filtered contract feed.

Design incremental refreshes and late-data replay

Three synchronization loops, three guarantees
Nightly01

Recent action replay

Re-read overlapping action-date windows for contracts A–D and keep every raw page or completed export.

Required evidence

Distinct pages, unique source IDs, min/max dates, row counts and current-versus-prior hashes.

Periodic02

Award-history refresh

Fetch award detail and transactions for changed awards; retain negative actions and recompute summaries from accepted rows.

Required evidence

Transaction-to-summary reconciliation, deobligation checks and parent-IDV relationship tests.

Monthly / fiscal03

Archive reconciliation

Compare the feed with full or delta Award Data Archive files and replay disclosure windows for delayed records.

Required evidence

Gap report by agency, action date and award type, with DOD and USACE late arrivals reported separately.

The site updates nightly, but source reporting does not share one clock. Contracts are generally available within days; DOD and USACE procurement can be delayed by 90 days.

There is no single “updated since” field that proves every dependent representation is complete. Contract actions, source modifications, USAspending ingestion, File C linkage, and archive publication move on different clocks.

A defensible incremental design uses two lanes:

Frequent API or generated-download lane

Query last_modified_date over an overlapping interval. Re-read existing generated award keys, upsert raw source versions, and preserve a change ledger. The overlap absorbs delayed publication and corrections. Its length should be based on measured lateness, not convenience.

Monthly archive lane

Download and hash every new Delta, apply additions/corrections/deletions transactionally, and compare the resulting fiscal-year totals and key sets with a current Full file. Rebaseline periodically and whenever a delta was missed or validation cannot explain a difference.

An upsert is not a history. Preserve:

  • first-seen and last-seen timestamps;
  • source action date and source last-modified date;
  • fetch time and archive preparation date;
  • raw version hash;
  • change type;
  • prior and current normalized values; and
  • tombstone state for source deletions.

This gives downstream users a way to distinguish “the agency signed an action today” from “a previously signed action appeared or changed in today's data.”

Model reporting lag, linkage, and historical coverage

USAspending is assembled from multiple federal reporting systems. The official data-sources guide identifies File D1 as contract and IDV transaction data sourced from FPDS, while File C is agency account breakdown by award.

They complement each other but are not one-to-one rows. File C adds Treasury account, federal account, program activity, object class, disaster code, obligation, and outlay context. D1 adds recipient, location, NAICS/PSC, competition, and procurement attributes. USAspending links them at the award level through a shared award identifier.

When linkage is missing, one side cannot magically supply the other's fields. Publish linkage and missingness rates. Earlier outlay history is also less complete: award outlays became mandatory monthly for all agencies in fiscal year 2022, while earlier reporting was more limited.

The current About the Data disclosure also describes timing limits:

  • agencies generally have three business days to report a contract action to FPDS;
  • FPDS data then move to USAspending on the following morning and publish after that processing;
  • Department of Defense and U.S. Army Corps of Engineers procurement data are published with a 90-day delay; and
  • some urgent or exceptional actions may use a longer reporting window.

Consequently, “today's federal contracts” is provisional. Use a stated cutoff, replay late intervals, and avoid completeness claims for recent DOD/USACE activity.

Historical comparisons need their own caveat. Award records can reach fiscal year 2001 through downloads, Advanced Search starts in fiscal year 2008, and account data begin in 2017. Reporting rules, identifiers, required fields, and outlay coverage changed over time. A long trend should show coverage denominators by year, not just dollar totals.

Validate and reconcile every extraction run

Publish only when all six validation gates pass
01

Request

The saved method, body, filters, date_type, fields, sort and retrieval time can reproduce the slice.

02

Pagination

All pages are distinct, hasNext terminates as expected, and page counts reconcile to the accepted rows.

03

Identity

generated_internal_id, PIID, agency context and parent-award links survive normalization without collision.

04

Amounts

Action obligations, deobligations, award totals, outlays and potential values remain separately named and tested.

05

Coverage

API or export results reconcile with archive files by agency, award type and action date within explained tolerance.

06

Freshness

Normal reporting lag, the 90-day DOD and USACE delay, and monthly File C cadence are visible to consumers.

Row counts alone cannot show whether the award grain changed, a negative action disappeared, an IDV was double counted or a reporting delay was mistaken for zero spending.

Validation should cover population, identity, money, relationships, freshness, and file operations.

Population tests

  • Every page except the last contains the requested number of rows.
  • The last page has hasNext: false.
  • All expected partitions completed and their bounds do not overlap unintentionally.
  • Contract and IDV families were collected separately.
  • API award counts reconcile to the matching generated download within the stated cutoff.
  • Monthly materialization reconciles to current Full files after Delta application.

Identity and relationship tests

  • generated_internal_id is non-null and unique at award grain.
  • Transaction IDs or contract transaction unique keys are unique at transaction grain.
  • PIID-only collisions are counted, not silently overwritten.
  • Parent IDV keys resolve where reported.
  • Recipient UEI is treated as a recipient identifier, never an award key.

Money tests

  • Negative and zero action obligations survive parsing.
  • The signed sum of a complete award history reconciles to cumulative obligations within documented tolerances.
  • Potential value, current value, obligations, and outlays occupy separate columns.
  • Prime and subaward dollars are never added into one “total spending” measure.
  • IDV ceiling/value is not added to child-order obligations.

Operational tests

  • Raw request, response, status, and artifact manifests are complete.
  • Every downloaded ZIP passes checksum and archive-integrity checks.
  • Required members and headers are present; unknown headers are retained and alerted.
  • Timestamps identify action, modification, fetch, and archive preparation separately.
  • Null and missingness rates are compared with a trailing baseline by field and source cohort.
  • Retry exhaustion fails the partition rather than publishing a plausible partial file.

Publish those checks beside the data. A “fresh” timestamp without completeness, lag, and reconciliation evidence is decoration.

Choose USAspending, SAM.gov, or both

The systems overlap in subject matter, not in job.

Use SAM.gov Opportunities for pre-award notices: solicitations, presolicitations, sources sought, amendments, response deadlines, attachments, and notice history. Use the SAM.gov Opportunities API implementation for that pipeline.

Use the SAM.gov Contract Awards API when replacing FPDS Atom feeds or when the application depends on the detailed procurement-action schema and its correction/deletion mechanics. The FPDS migration guide owns that cutover.

Use USAspending for award-centered discovery, transaction obligations, recipient and agency research, downloadable award history, account linkage, outlays, and broader federal-spending context. The government contracts database guide explains where it sits in the wider source map.

Use both when a product must connect an opportunity to later procurement actions and spending. Do not assume a perfect one-to-one join. Preserve solicitation, PIID, agency, office, dates, recipient, parent vehicle, and source URLs; score match confidence; and keep unmatched records visible.

WebTruffle's free US federal contract awards dataset is a bounded USAspending-derived prime-award snapshot with suppliers and award-recipient relationships. The US federal awards Python guide owns post-download verification, joins, cumulative-amount semantics, and changed-window exports. Use this API guide when you need source request design, transactions, IDVs, generated downloads, or recurring collection. The EU/UK awards dataset remains a separate jurisdictional product.

USAspending API production checklist

Before the first production run:

  • State the output grain and analytical question.
  • Snapshot /api/v2/references/award_types/.
  • Query AD separately from the IDV family.
  • Choose and document action_date, date_signed, last_modified_date, or new_awards_only.
  • Name awarding versus funding agency scope.
  • Request generated_internal_id and retain source keys unchanged.
  • Set fields, sort, order, page, and limit explicitly.
  • Continue with both returned cursor values.
  • Partition large search jobs and define the source cutoff.
  • Save raw pages before normalization.
  • Treat action obligations as signed values.
  • Separate obligations, current value, potential value, and outlays.
  • Preserve IDV-to-order relationships without adding their values.
  • Use generated downloads for broad filtered transaction extracts.
  • Poll the returned status URL and archive completed files promptly.
  • Bootstrap nationwide history from Full files.
  • Retain and apply each Delta's add, correction, and deletion semantics.
  • Rebaseline when a Delta is missed.
  • Replay overlapping intervals for corrections and late disclosures.
  • Publish lag, coverage, linkage, missingness, and validation evidence.

Frequently asked questions

Does the USAspending API require an API key?

No. The current official endpoint index says USAspending endpoints do not require authorization. Still use bounded concurrency, timeouts, backoff, and downloads for large jobs. The documentation publishes no numeric rate quota, so do not claim that the service is unlimited.

Which USAspending endpoint returns federal contracts?

Use POST /api/v2/search/spending_by_award/ with award type codes A, B, C, and D to discover prime contract awards. Use the award-detail endpoint for one richer award, the transactions endpoint for its action history, and generated or archive downloads for a wider transaction schema.

What is generated_internal_id?

It is USAspending's generated award identifier returned by search and preferred by award-detail and transaction-history routes. The detail response calls the same concept generated_unique_award_id. Retain it exactly; do not replace it with PIID or UEI.

Should I query contracts and IDVs together?

No. Prime contract codes and IDV codes have different field contracts, and current award search validates them as separate families. Query them separately, preserve parent-child relationships, and decide which level a metric represents before aggregating.

Does action_date return only newly awarded contracts?

No. At award-summary grain, an action-date search can return an existing award because it has qualifying transaction activity. Use new_awards_only or inspect the base transaction when the question is specifically about new awards, and retrieve transaction history before labeling activity.

How do I calculate contract spending for a period?

Sum transaction-level federal_action_obligation for action dates in the period and retain negative de-obligations. Call the result net obligations. Do not sum cumulative award values, potential value, or repeated summary amounts across transaction rows. Use outlays only when the claim is about actual payments.

How far back does USAspending contract data go?

Award downloads can reach fiscal year 2001, while Advanced Search begins in fiscal year 2008. Agency account data begin in 2017, and mandatory monthly award-outlay reporting for all agencies is newer. Treat long historical comparisons as changing-coverage series.

What is the best route for all federal contract transactions?

Use Contracts Full files to establish fiscal-year baselines and retain each monthly Contracts Delta for additions, corrections, and deletions. A nationwide API page crawl is slower, mutable during collection, and constrained by a bounded search window.

How fresh is USAspending contract data?

Normal procurement reporting involves agency reporting time plus ingestion and publication time. DOD and U.S. Army Corps of Engineers procurement has a 90-day publication delay. Use explicit cutoffs, overlapping replay, and recent-period caveats instead of calling the latest day complete.

Is USAspending a replacement for SAM.gov?

No. USAspending is strongest for award-centered spending and account context. SAM.gov Opportunities covers pre-award notices, while the SAM.gov Contract Awards API carries the detailed procurement-action path that replaced FPDS Atom. Many products need more than one source and an explicit join model.