Skip to content

Vehicles

Vehicles are a solicitation-centric grouping of multiple IDVs (the "thing people usually mean" when they say "this vehicle"), exposed at /api/vehicles/.

If you want the conceptual model first, start with Getting Started – Vehicles. For field definitions, see the Vehicles Data Dictionary.

Endpoints

  • GET /api/vehicles/ (list + filtering + search + ordering)
  • GET /api/vehicles/{uuid}/ (detail; supports shaping)
  • GET /api/vehicles/{uuid}/awardees/ (the underlying IDVs; supports ?search= and shaping)
  • GET /api/vehicles/{uuid}/orders/ (task orders / contracts under all IDVs in the vehicle; behaves like /api/contracts/)

Filtering

The list endpoint supports a rich filter set across enums, reference codes, org hierarchy, numeric ranges, and dates. Multi-value enum filters use pipe (|) for OR semantics, e.g. ?vehicle_type=A|B|C.

Param What it does
search Full-text vehicle search (solicitation identifier + aggregated award terms).
vehicle_type Vehicle (IDV) type code (e.g. A, B). Multi-value via \|. Case-insensitive.
type_of_idc Type of IDC code. Multi-value via \|.
contract_type Contract type code (J, M, etc.). Multi-value via \|.
set_aside Set-aside type (8A, 8AN, BICiv, etc.). Multi-value via \|.
who_can_use Who-can-use code.
naics_code NAICS code (exact integer).
psc_code Product / Service Code.
program_acronym Program acronym (SEWP, OASIS, GSA Schedule, etc.).
agency Awarding agency or department. Examples: GSA, DOD, DHS. Multi-value via \|.
organization_id Awarding organization UUID (exact match).
total_obligated_min / total_obligated_max Total obligated USD lower / upper bound.
idv_count_min / idv_count_max Number of child IDVs lower / upper bound.
order_count_min / order_count_max Number of task orders lower / upper bound.
fiscal_year Fiscal year (YYYY).
award_date_after / award_date_before Award-date range (YYYY-MM-DD). Invalid dates or inverted ranges return 400.
last_date_to_order_after / last_date_to_order_before Last-date-to-order range (YYYY-MM-DD).

Range filters are not exposed for vehicle_obligations or awardee_count. Use the corresponding total_obligated_min/max and order_count_min/max parameters instead — they cover the same use cases against the precomputed rollup fields.

GET /api/vehicles/{uuid}/awardees/ supports ?search= for entity-aware full-text search across the underlying IDVs (PIID, key, solicitation_identifier, NAICS, PSC, recipient name / address). Pagination is page-based.

On the detail endpoint (GET /api/vehicles/{uuid}/), ?search= does not search vehicles — it filters the expanded awardees when your ?shape= includes awardees(...).

Example:

GET /api/vehicles/{uuid}/?shape=uuid,solicitation_identifier,awardees(key,piid,recipient(display_name,uei))&search=deloitte

Ordering

Vehicles support ?ordering= with a strict allowlist (8 fields). Prefix with - for descending; combine with commas for multi-field sort.

  • vehicle_obligations — sum of obligations across child orders (computed at query time)
  • latest_award_date — most recent IDV award date in the vehicle (computed at query time)
  • total_obligated — direct column rollup
  • award_date — earliest IDV award date
  • last_date_to_order — latest "last date to order" across IDVs
  • fiscal_year — vehicle fiscal year
  • idv_count — precomputed count of IDVs in the vehicle
  • order_count — precomputed count of orders against the vehicle's IDVs

Examples:

  • Most obligations first: ?ordering=-vehicle_obligations
  • Soonest stop-orders first: ?ordering=last_date_to_order
  • Combined: ?ordering=-total_obligated,-award_date

When no ?ordering= is provided, results are returned in solicitation_identifier, agency_id, uuid order.

Pagination

Vehicle lists use page-number pagination:

  • page (default 1)
  • limit (max 100)

Vehicle awardees and vehicle orders also use page-number pagination (page, limit). Vehicle orders is optimized internally for date-ordered traversal of very large vehicles, but the response contract is the same as every other paginated endpoint: page-based with next / previous URLs and a count.

Response shaping

Vehicles use the shaping pipeline by default. Even without ?shape= you'll get a curated default response.

Default LIST shape: agency_details, award_date, awardee_count, contract_type, description, fiscal_year, idv_count, last_date_to_order, latest_award_date, naics_code, order_count, organization, program_acronym, psc_code, set_aside, solicitation_date, solicitation_identifier, solicitation_title, total_obligated, type_of_idc, uuid, vehicle_contracts_value, vehicle_obligations, vehicle_type, who_can_use

Default DETAIL shape is a superset: adds agency_details(*) (expanded), agency_id, competition_details(*), metrics(*), opportunity_id, solicitation_description.

Available expansions

Expansion Description
awardees(...) The underlying IDVs that make up the vehicle. Supports ?search= filtering on detail.
opportunity(...) Linked SAM.gov Opportunity (full Opportunity shape — office, attachments, meta, etc.).
competition_details(*) Aggregated competition information (12 sub-fields including extent_competed, set_aside, solicitation_procedures, number_of_offers_received).
agency_details(*) Aggregated awarding/funding office. Returned on detail (GET /api/vehicles/{uuid}/); list responses return a null stub for this field.
metrics(*) 12 computed vehicle metrics (HHI, competed-rate, top-recipient share, etc.).
organization(*) Canonical 7-key office payload (organization_id, office_code, office_name, agency_code, agency_name, department_code, department_name). Both bare ?shape=organization (leaf) and ?shape=organization(*) (expand) work — both converge on the same cached lookup.

Vehicles also support flat=true|false, flat_lists=true|false, and joiner=. (relevant only when flat=true). See Response Shaping.

Synthetic GWAC vehicles

Some GWAC vehicles lack a real solicitation number. Tango synthesizes a vehicle for them so the grouping still works; consumers can identify them via:

  • is_synthetic_solicitation (boolean) — true on synthetic rows
  • program_acronym — the GWAC's identifier (e.g. SEWP)
  • solicitation_identifier — the user-facing value, with the internal ACRO: storage prefix stripped

SDK examples

See also: Full SDK method reference — tango-python methods · tango-node methods.

The Python SDK exposes first-class methods for all three vehicle endpoints.

List vehicles (search + ordering + filters)

import os

from tango import TangoClient

client = TangoClient(api_key=os.environ["TANGO_API_KEY"])

resp = client.list_vehicles(
    search="SEWP",
    program_acronym="SEWP",
    ordering="-vehicle_obligations",
    page=1,
    limit=10,
)

print("count:", resp.count)
for v in resp.results:
    print(v.uuid, v.solicitation_identifier, v.vehicle_obligations)
import { TangoClient } from "@makegov/tango-node";

const client = new TangoClient({ apiKey: process.env.TANGO_API_KEY });

// Workaround until the Node SDK ships a first-class listVehicles()
const http = (client as any).http;
const data = await http.get("/api/vehicles/", {
  search: "SEWP",
  program_acronym: "SEWP",
  ordering: "-vehicle_obligations",
  page: 1,
  limit: 10,
});

console.log("count:", data.count);

Vehicle detail with metrics and organization

import os

from tango import TangoClient

client = TangoClient(api_key=os.environ["TANGO_API_KEY"])

vehicle_uuid = "00000000-0000-0000-0000-000000000000"  # replace
v = client.get_vehicle(
    vehicle_uuid,
    shape="uuid,solicitation_identifier,vehicle_obligations,metrics(*),organization(*)",
)
print(v["uuid"], v["organization"]["agency_name"])
resp = client.list_vehicle_awardees(
    "00000000-0000-0000-0000-000000000000",   # vehicle UUID is positional (kwarg name: uuid)
    search="deloitte",
    limit=25,
)
for awd in resp.results:
    print(awd.piid, awd.recipient.display_name)

Vehicle orders (task orders)

resp = client.list_vehicle_orders(
    "00000000-0000-0000-0000-000000000000",   # vehicle UUID is positional (kwarg name: uuid)
    ordering="-award_date",
    limit=50,
)
print("orders:", resp.count)