Skip to content

Protests Data Dictionary

This document describes the fields available in the Protests API endpoints (/api/protests/). For filtering, ordering, and pagination, see the Protests API Reference.

Overview

Protests are bid protest records from GAO and SBA OHA (the Small Business Administration's Office of Hearings and Appeals). The API exposes a narrow set of client-facing fields. Source ingest payload details and internal fields (e.g. external_id, data_quality) are not exposed. Filter by source_system (gao or sba_oha) to scope results to a single venue.

SBA OHA decisions are size and status appeals — a challenge to whether a firm qualifies as small, or as a service-disabled veteran-owned, women-owned, or HUBZone concern — rather than challenges to an award. They therefore populate a different set of fields: most name the challenged firm and the NAICS code at issue, and most carry no procuring agency at all.

Authentication: Protests endpoints require authentication (API key or OAuth2).

Coverage: The API covers protest decisions from 2015 onward, across every venue — the effective floor for the filed_date and decision_date filters alike. Pre-2015 records exist in the database but are not available through the API.

Note: Both list and detail endpoints return case-level objects. Each case is identified by case_id (a deterministic UUID from source_system + base_case_number). Detail lookup uses case_id in the URL path: GET /api/protests/{case_id}/. Use ?shape=...,dockets(...) to expand nested docket records. The default (unshaped) response does not include dockets.

Update Frequency

GAO and SBA OHA protest data is refreshed by loader schedule and available source files. SBA OHA decisions arrive daily.

Fields (API response)

Only the following fields are returned in list and detail responses (and are available via shape):

Field Type Description Source
case_id UUID Deterministic case UUID derived from source_system + base_case_number. Use for detail lookup: GET /api/protests/{case_id}/. Tango
source_system String Source venue identifier: gao or sba_oha. Tango
case_number String Base case for grouping sub-dockets (for example b-424214 from B-424214.1). Model field: base_case_number. Use with decision_date for decision-level counting. Derived
docket_number String Source docket identifier (for example b-424214.1, b-424214.2). Model field: case_number. Only available inside the dockets(...) expansion. Use to distinguish sub-dockets under the same case_number. Source
title String Protest title. Source
protester String Protester name. Source
agency String Protested agency. Source
solicitation_number String Solicitation number when provided. Source
case_type String Protest case type. GAO uses values like Bid Protest; SBA OHA uses SIZE, NAICS, VSBC, CVE, BDPE, SDVOSB, BDPT, WOSB, and HUBZONE. Source
outcome String Protest outcome, when available. GAO returns Denied, Dismissed, Withdrawn, or Sustained; SBA OHA additionally returns Granted, Remanded, Reversed, or Vacated. Source
filed_date Date Date the protest was filed. Source
posted_date Date Date the protest was posted. Source
decision_date Date Decision date, when available. Source
due_date Date Protest due date, when available. Source
docket_url String Source docket URL. Source
decision_url String Source decision URL, when available. Source

Opt-in via shape only: digest — when requested with ?shape=...,digest, the value from raw_data.digest (e.g. decision summary text) is returned. Not included in the default list/detail response.

Opt-in via shape only, SBA OHA: the five fields below are populated on SBA OHA decisions and are null on GAO records. Because they are null for most of the table, they are excluded from the default response — request them explicitly, for example ?shape=case_id,case_number,challenged_party,naics_code. They are available on every plan.

Field Type Description
challenged_party String The firm whose size or socioeconomic status was challenged.
naics_code String The NAICS code at issue in the appeal. Also available as a filter: ?naics_code=541512.
size_standard String The applicable size standard as written, for example $33.5 million or 1,000 employees.
outcome_reason String Why a case was dismissed: untimely, moot, withdrawn, lack of jurisdiction, lack of standing, or insufficient specificity.
judge String The authoring administrative judge.

Resolution Fields (shape expansions)

Protests support entity and organization resolution via the Bayesian resolver. These fields are available as shape expansions and return null when no confident match exists.

resolved_protester(...) — Entity Resolution

Field Type Description
uei String Unique Entity Identifier of the matched entity.
name String Display name of the matched entity.
match_confidence String "confident" (high confidence, auto-linkable) or "review" (medium confidence, needs human review).
rationale String Human-readable explanation (e.g. "Exact name match", "Similar name match; multiple entities share this name").

resolved_agency(...) — Organization Resolution

Field Type Description
key String (UUID) UUID primary key of the matched organization in Tango.
name String Display name of the matched organization.
match_confidence String "confident" or "review".
rationale String Human-readable explanation (e.g. "Exact name match; parent agency confirmed").

Confidence mapping: Internal resolution tiers map to public labels as follows: high"confident", medium"review". Low-confidence and no-match results are excluded (return null).

The following are not exposed in the API: external_id, data_quality, source_last_updated, created, modified, raw_data, field_provenance.

Data Quality (internal)

Every protest record has an internal data_quality tier (not exposed in the API response). Records with quarantined or unknown quality are always excluded from API responses. Quality is recomputed on each ingestion cycle.

Shaping

Both list and detail return case-level objects. shape lets you request a subset of fields. Use the dockets(...) expansion to include nested docket records.

Allowed shape fields (case-level):

  • case_id, source_system, case_number, title, protester, agency
  • solicitation_number, case_type, outcome
  • filed_date, posted_date, decision_date, due_date
  • docket_url, decision_url
  • digest (from raw_data.digest; opt-in only)
  • dockets (expand with docket fields, e.g. dockets(case_number,docket_number,filed_date))
  • resolved_protester (expand: uei, name, match_confidence, rationale)
  • resolved_agency (expand: key, name, match_confidence, rationale)

Inside dockets(...), these additional fields are available:

  • docket_number (specific sub-docket identifier, e.g. b-424214.1)

Examples:

# List: case-level and nested dockets
GET /api/protests/?shape=case_id,case_number,title,dockets(docket_number,filed_date,outcome)

# List: case-level only
GET /api/protests/?shape=case_id,title,outcome,decision_date

# Detail with nested dockets
GET /api/protests/{case_id}/?shape=case_id,title,dockets(docket_number,filed_date)

raw_data and field-level provenance metadata are internal-only and not exposed in API responses.

Data Sources

  • GAO – primary source for protest records.
  • SBA OHA – size and status appeal decisions from the Small Business Administration's Office of Hearings and Appeals.
  • Tangocase_id (deterministic case UUID) and normalized API behavior.