5-character DoD identifier in, full federal contractor profile out. JSON, one HTTP call.
A Commercial and Government Entity (CAGE) code is the 5-character alphanumeric identifier the Defense Logistics Agency assigns to every federal contractor location. DoD contracting officers, NATO partners, and many legacy procurement systems still key transactions on CAGE rather than UEI. This endpoint takes a CAGE and returns the entity it identifies: legal name, UEI, address, NAICS, certifications, registration status.
CAGE is nearly universal in the registry, which is why it stays a practical join key even after the 2022 move to UEI. As of the July 5, 2026 SAM extract, 788,881 of the 885,266 registered entities (89%) carry a CAGE code, across 793,402 distinct codes. A UEI usually maps to exactly one CAGE; a multi-facility organization can carry several, but that is rare, only 3,481 entities (0.4%) have more than one, and the most on any single UEI is 81.
Who this page is for: developers integrating DoD/DLA workflows where CAGE is the primary key. Contract administrators, defense subcontract teams, NSCM-aware ERP integrators, anyone who has CAGE codes in their data and needs to resolve them to a current federal contractor record.
What this page is NOT: a CAGE issuance or modification tool. CAGE codes are issued by DLA. This endpoint reads the public registration data; it doesn't write to it.
You pass a CAGE code. You get the same response shape as our UEI-keyed endpoint, plus a queried_cage field echoing your input so you can confirm the match. The response resolves a registration block (status, dates, freshness) and the full entity block: legal name, address, primary_naics plus the complete naics_codes[] and psc_codes[] arrays, business-type certifications, and every cage_codes[] registered to that UEI.
Real response for CAGE 53YC5, fetched 2026-07-08, trimmed to fit:
{
"queried_cage": "53YC5",
"uei": "C111ATT311C8",
"registration": {
"status": "A",
"active": true,
"registration_date": "2013-11-12",
"activation_date": "2026-04-29",
"expiration_date": "2027-04-27",
"expiring_soon": false,
"source_extract_date": "2026-07-05"
},
"entity": {
"legal_business_name": "K & K CONSTRUCTION SUPPLY INC",
"dba_name": null,
"entity_structure_code": "2L",
"entity_url": "www.kkconstructionsupply.com",
"physical_address": {
"street1": "11400 WHITE ROCK RD",
"city": "RANCHO CORDOVA", "state": "CA", "zip": "95742", "country": "USA"
},
"primary_naics": "444110",
"naics_codes": ["332312Y", "423310Y", "444110Y", "484220Y", "..."],
"psc_codes": ["3940", "5510", "5975", "..."],
"business_types": ["2X", "8W", "A2", "HQ", "XS"],
"business_types_labels": [
"For Profit Organization",
"Women-Owned Small Business (WOSB)",
"Woman-Owned Business", "DOT Certified DBE", "Subchapter S Corporation"
],
"cage_codes": ["53YC5"]
}
}
On the Pro tier the same call also carries an inline FPDS prime-contract and FFATA sub-vendor activity block (fpds_obligated_total, fpds_distinct_contracts, sub_revenue_total, top_paying_primes), so one CAGE-keyed lookup returns the resolved entity's registration and its full federal activity together.
A CAGE code is exactly 5 uppercase alphanumeric characters. We checked every CAGE in the current SAM registry: all 793,403 are 5 characters and all uppercase alphanumeric (100%).
The letters I and O never appear in positions 2 through 4, 0 of 793,403 codes, a DLA design choice so they are not confused with the digits 1 and 0.
The pattern usually quoted, "a digit, three alphanumerics, a digit", holds for about 96% of codes (95.88% have a numeric first and fifth position). It is not a strict rule: roughly 1 in 25 codes (4%) carries a letter in the first or last position. A validator that requires the first and last characters to be numeric will wrongly reject those valid codes.
# accepts 100% of real CAGE codes
^[0-9A-Z]{5}$
# stricter: encodes the DLA I/O rule (still matches 100%)
^[0-9A-Z][0-9A-HJ-NP-Z]{3}[0-9A-Z]$
# DO NOT use this: rejects ~4% of valid codes
^[0-9][0-9A-Z]{3}[0-9]$
Sample real codes from the dataset: 141S8, 59NT1, 83QT3, 9BXU3, 5UE58.
/api/v1/exclusions/search to check debarment status by UEI.
uei field in the response gives you the bridge.
business_types array tells you what self-certifications the supplier has on file with SAM at the moment you check.
A single authenticated GET. Auth via Authorization: Bearer <api_key>.
curl -H "Authorization: Bearer $API_KEY" \
https://govconapi.com/api/v1/entities/by-cage/53YC5
Python (requests):
import requests
r = requests.get(
"https://govconapi.com/api/v1/entities/by-cage/53YC5",
headers={"Authorization": f"Bearer {API_KEY}"},
timeout=15,
)
r.raise_for_status()
data = r.json()
print(data["entity"]["legal_business_name"], data["uei"])
# K & K CONSTRUCTION SUPPLY INC C111ATT311C8
JavaScript (fetch):
const res = await fetch(
"https://govconapi.com/api/v1/entities/by-cage/53YC5",
{ headers: { Authorization: `Bearer ${API_KEY}` } }
);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const { entity, uei } = await res.json();
console.log(entity.legal_business_name, uei);
Resolving a batch of CAGE codes (the legacy-ERP enrichment case). One lookup per code; skip 404s and back off on 429:
import requests, time
def resolve(cage):
r = requests.get(f"https://govconapi.com/api/v1/entities/by-cage/{cage}",
headers={"Authorization": f"Bearer {API_KEY}"}, timeout=15)
if r.status_code == 404: # superseded / NCAGE / not in current SAM data
return None
if r.status_code == 429: # rate limited: honor Retry-After, then retry
time.sleep(int(r.headers.get("Retry-After", 2)))
return resolve(cage)
r.raise_for_status()
return r.json()
# Developer tier allows 1,000 requests/hour across the API
resolved = {cage: resolve(cage) for cage in my_cage_codes}
The CAGE in the path is normalized: lowercase and surrounding whitespace are accepted and converted to canonical uppercase.
Error shapes:
401: missing or invalid Authorization header404: CAGE not found in current SAM data429: rate limit (60/min per IP burst, 1000/hr per API key)Both identify the same underlying entity. Pick by what you have on hand:
/api/v1/entities/{uei}.One entity can have multiple CAGE codes (one per registered facility), though as noted above that is uncommon: 3,481 entities carry more than one, and the largest carries 81. Most have exactly one. The cage_codes[] array in any entity response lists all CAGE codes registered to that UEI.
/api/v1/entities/{uei} (Developer): same data keyed by UEI instead of CAGE./api/v1/companies/{uei} (Pro): adds award-history aggregations to the entity profile./api/v1/entities/search (Developer for q; Pro for filters): find entities by name or by NAICS / state / certification combinations./api/v1/entities/expiring (Pro): active registrations expiring within N days. Useful when you've resolved a CAGE and want to know if the entity needs to renew soon./api/v1/exclusions/search?uei={uei} (Developer): debarment check on the resolved UEI./api/v1/vendor-risk/{uei} (Pro): seven-signal risk screening including address-cluster and name-variant matches.source_extract_date field tells you the freshness of any given record. For time-sensitive compliance decisions, verify directly with sam.gov as the system of record.
This endpoint reads the public entity-registration data that federal contractors file; it does not issue or modify CAGE codes. The authoritative sources for the CAGE system itself:
cage.dla.mil), the Defense Logistics Agency office that assigns and maintains US CAGE codes.The figures on this page, 793,403 CAGE codes, 788,881 entities carrying a CAGE (89% of 885,266), and the positional-format checks, were computed 2026-07-08 from the July 5, 2026 SAM entity extract this API serves. Every response carries a source_extract_date so you can see the freshness of the underlying record.
This endpoint is on the Developer tier ($19/mo): 1,000 requests/hour across the whole API surface, single CAGE lookup, single UEI lookup, name search, exclusions search, FPDS prime contract + SAM Award Notice endpoints, opportunities. Pro ($39/mo) adds award-history merge, multi-filter entity search, expiration radar, seven-signal vendor-risk screening, and the Federal Subawards (FFATA) API. Pro responses on this endpoint also include inline fpds_obligated_total + fpds_distinct_contracts (FPDS prime contract activity) and sub_revenue_total + top_paying_primes (FFATA sub-vendor income) so a single CAGE-keyed lookup surfaces the resolved entity's full federal activity alongside its registration data.
No annual contracts, no setup fees, monthly billing via Stripe. Cancel anytime.
Can one CAGE belong to multiple entities?
No. DLA assigns each CAGE to one entity (one specific facility of one company). The reverse, multiple CAGEs per entity, is common for organizations with multiple registered locations.
What if I have a 6-character or 7-character "CAGE"?
It is not an NCAGE: those are also five characters, alphanumeric, uppercase, no spaces, exactly like a US CAGE. A longer string is usually a DODAAC, a DUNS fragment, or a 12-character UEI. Anything other than five characters is out of spec for this endpoint and will 404.
What's the difference between CAGE and DUNS?
CAGE is DoD-issued (DLA, since the 1950s). DUNS was D&B-issued and used in non-DoD federal procurement until 2022, when it was replaced by UEI. CAGE survived the transition; DUNS didn't. CAGE is still in active use across DoD and FAR-regulated procurement.
How fresh is the data?
We refresh as upstream data publishes. In rare cases there can be up to ~30 days of latency between a CAGE record updating on sam.gov and the change appearing here. The source_extract_date field tells you which snapshot the record came from.
Can I look up entities by other identifiers (DUNS, EIN, FEIN)?
No. UEI and CAGE are the only public-key lookups we support. EIN/FEIN are not in the public SAM dataset (taxpayer identification is restricted). DUNS is retired.
Is the response shape identical to the UEI-lookup endpoint?
Almost. We add a queried_cage field to the top of the response so callers can confirm which CAGE was used to resolve the entity. Everything else (registration block, entity block) is identical.