# Look up CAGE codes in bulk

To look up CAGE codes in bulk, give an AI agent the list and ask it to call registration_status for each code, or run a short script that calls GET /api/v1/registration-status/{cage} per row. Each lookup returns the legal name, UEI, status, expiration date and exclusion flag, at one credit per code.

Supply chain, security and contracts teams holding spreadsheets of CAGE codes from purchase orders, DD Form 254s or supplier portals. The CAGE program search at cage.dla.mil handles one code at a time; an agent or a script works through a few hundred in minutes and returns a table you can sort by expiry.

## The prompt

```
Here are 40 CAGE codes from our supplier list. For each one, give me the legal name, UEI, SAM.gov status, expiration date and exclusion flag in a table, and put anything expired or expiring within 90 days at the top.
```

## What the agent calls

1. registration_status: Accepts a CAGE code as well as a UEI. The agent repeats it per code.

```json
{"name":"registration_status","arguments":{"id":"5S389","user_request":"bulk CAGE check for supplier list"}}
```

## Sample output

Trimmed; field names and structure match the live response, values are shortened or illustrative.

```json
{
  "data": {
    "uei": "ZXBCU6K5KL99",
    "cage": "5S389",
    "legal_name": "LEIDOS, INC.",
    "status": "active",
    "expiration_date": "2027-10-20",
    "days_to_expiry": 341,
    "exclusion_flag": false,
    "renewal_window": "current"
  }
}
```

## How to read the answer

- A CAGE code that returns NOT_FOUND may belong to a firm that is not registered in SAM.gov (CAGE codes also exist for unregistered and foreign entities) or may be mistyped.
- One CAGE code maps to one registration, but a company can hold several CAGE codes for different locations; group by UEI to see the company view.

## Make it yours

- For thousands of codes, the Scale plan's bulk CSV export of entities filtered by state or NAICS is cheaper than one lookup per code.
- Ask Claude Code or Codex to write the script below into your repo and run it against a CSV.

## Pitfalls

- Agents may stop early on long lists. Ask for a count at the end and compare it with your input.
- Mind the per-minute limit of your plan in a script: add a short sleep between calls, and back off on HTTP 429.

## Python: CSV of CAGE codes in, table out

```python
import csv, os, sys, time, requests

KEY = os.environ["SAMGOVAPI_API_KEY"]
out = csv.writer(sys.stdout)
out.writerow(["cage", "uei", "legal_name", "status", "expiration_date", "exclusion_flag"])
for row in csv.reader(open("cage_codes.csv")):
    cage = row[0].strip().upper()
    r = requests.get(f"https://samgovapi.io/api/v1/registration-status/{cage}",
                     headers={"Authorization": f"Bearer {KEY}", "X-User-Request": "bulk CAGE check"}, timeout=30)
    if r.status_code == 429:
        time.sleep(int(r.headers.get("Retry-After", "10"))); continue
    d = r.json().get("data") or {}
    out.writerow([cage, d.get("uei"), d.get("legal_name"), d.get("status", "not found"), d.get("expiration_date"), d.get("exclusion_flag")])
    time.sleep(0.5)
```

## The same job over REST

```bash
curl "https://samgovapi.io/api/v1/registration-status/5S389" -H "Authorization: Bearer $SAMGOVAPI_API_KEY"
```

Plan: every plan. Credits: 1 credit per lookup; one per CAGE code.

## Questions

### Is there a batch endpoint?

Not for lookups by id. Loop single lookups at one credit each, or use the Scale plan's bulk export for large sets.

### Can I look up foreign CAGE codes (NCAGE)?

Only entities registered in SAM.gov are in the data. NATO CAGE codes for unregistered foreign firms are not.

All recipes: https://samgovapi.io/agents/recipes.md

Independent. Not affiliated with, endorsed by or sponsored by GSA, SAM.gov or any U.S. government agency. Registering in SAM.gov is free at sam.gov.
