# Connect Python requests to SAM.gov data

To call SAM.gov data from Python, send requests.get("https://samgovapi.io/api/v1/registration-status/<UEI>") with headers {"Authorization": f"Bearer {os.environ['SAMGOVAPI_API_KEY']}"}. Every answer is JSON with data and meta (source, as_of, credits_charged, next_cursor); pass next_cursor back as cursor to page through searches.

Plain Python is the right tool when the job is fixed: a nightly supplier check, a CSV export for a spreadsheet, a notebook that sizes a market. It is also what coding agents write when you ask them to automate one of the recipes.

- Connects with: REST
- MCP server: https://samgovapi.io/api/mcp
- REST base: https://samgovapi.io/api/v1
- Auth: Authorization: Bearer <key>, kept in SAMGOVAPI_API_KEY

## Get a key

Free key at https://samgovapi.io/sign-up, or have the agent call start_signup and approve the link it shows you. Read the key from SAMGOVAPI_API_KEY; never commit it.

## Set up Python requests

1. Install and set the key

Shell:

```bash
pip install requests
export SAMGOVAPI_API_KEY="sg_..."
```

2. Look up one registration: X-User-Request is optional and tells the team what the call was for.

check.py:

```python
import os, requests

H = {"Authorization": f"Bearer {os.environ['SAMGOVAPI_API_KEY']}", "X-User-Request": "check partner registration"}
r = requests.get("https://samgovapi.io/api/v1/registration-status/ZXBCU6K5KL99", headers=H, timeout=30)
r.raise_for_status()
d = r.json()["data"]
print(d["status"], d["expiration_date"], d["renewal_window"], "as of", d["as_of"])
```

3. Page through a search: Searches return next_cursor until the last page.

search.py:

```python
import os, requests

H = {"Authorization": f"Bearer {os.environ['SAMGOVAPI_API_KEY']}"}
params = {"naics": "541512", "open": "true", "limit": 100}
while True:
    body = requests.get("https://samgovapi.io/api/v1/opportunities", headers=H, params=params, timeout=30).json()
    for o in body["data"]:
        print(o["notice_id"], o["response_deadline"], o["title"])
    if not body["meta"]["next_cursor"]:
        break
    params["cursor"] = body["meta"]["next_cursor"]
```

## Check that it works

Expected response (trimmed):

```json
{
  "data": {
    "uei": "ZXBCU6K5KL99",
    "status": "active",
    "expiration_date": "2027-10-20",
    "days_to_expiry": 341,
    "renewal_window": "current",
    "exclusion_flag": false,
    "as_of": "2026-11-01"
  },
  "meta": {
    "credits_charged": 1
  }
}
```

## Things to know

- Respect your plan's per-minute limit in loops; a 429 body says which limit was hit and when it resets.

## Troubleshooting

- 401 INVALID_API_KEY: The header must be Authorization: Bearer sg_... with a space after Bearer.
- 429 RATE_LIMITED: Sleep until reset_at or for the Retry-After seconds, then retry.
- 429 QUOTA_EXCEEDED: The monthly credits are used; add a top-up or upgrade, or wait for the reset.

## Questions

### Is there an official Python package?

No package is needed; the API is plain JSON over HTTPS and /openapi.json can generate a typed client.

## Official documentation

- Requests: quickstart: https://requests.readthedocs.io/en/latest/user/quickstart/

Checked 2026-11-13. All guides: https://samgovapi.io/agents.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.
