# US Federal Contractor Profile (`mikee368/us-contractor-profile`) Actor

Look up a US federal contractor by company name, UEI, or CAGE code. Returns the USAspending recipient and award-history summary. SAM.gov registration and exclusion checks are coming later (no key yet).

- **URL**: https://apify.com/mikee368/us-contractor-profile.md
- **Developed by:** [Mike Berckmoes](https://apify.com/mikee368) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$4.00 / 1,000 company profiles

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## US Federal Contractor Profile

Look up a US federal contractor by **company name**, **UEI**, or **CAGE code**. Each row is the USAspending recipient plus an award-history summary.

**SAM.gov checks are coming later.** No SAM.gov API key is configured yet, so a run does not check registration or exclusions. `samStatus` is `not-checked` and `samReason` says SAM.gov was not checked because `SAM_GOV_API_KEY` is not set. The USAspending fields are still filled.

This Actor is not affiliated with or endorsed by USAspending, SAM.gov, or the General Services Administration.

### What does US Federal Contractor Profile do?

It answers one question: who is this contractor, and what does the public federal record say about them?

**USAspending** is what this Actor returns today. It needs no API key. You get the recipient UEI, legal name, parent, business types, address, lifetime obligations, and a short award history for the last few fiscal years.

**SAM.gov checks are coming later.** Registration status, expiration, CAGE, NAICS, and exclusions need a SAM.gov API key, and none is configured yet. Until that key is added, those fields stay empty, `samChecked` is false, and `samStatus` stays `not-checked`. The run still succeeds.

Watch mode will flag a registration that expires within N days, one that is already expired, or an exclusion that was not on the previous run, once SAM.gov checks are on. The same alert is not emitted again for the same expiration date, and watch alerts are not charged. Until the key is configured, a watch run still returns the USAspending profile and does not emit those alerts.

### Why use US Federal Contractor Profile?

Use it as the company step after a tender, a filing, or a carrier lookup:

- An awardee name from **us-federal-tender-monitor** goes in `names` or `companies`.
- A public company name from **sec-edgar-filings-watch** (`companyName`) goes in `names`. This Actor does not return a ticker or CIK. Pass `companyName` back into that Actor if you want filings.
- A motor carrier that also holds federal awards: pass `legalName` into `names` and `state` into **fmcsa-carrier-watch**.

The shared fields are `uei` / `ueiSAM` (the same 12-character id), `companyName` / `legalName` (the same legal name), `cageCode`, `naicsCode`, and `state`.

Runs stay small: 128 MB, no proxy, and one USAspending search plus a detail and three summary requests per company. Successful responses are cached for 24 hours. SAM.gov is not called, because no key is configured yet.

### What data can it extract?

| Field | What it is |
| --- | --- |
| `uei`, `ueiSAM` | Unique Entity ID. Same value in both fields. |
| `companyName`, `legalName` | Legal name. Same value in both fields. |
| `cageCode` | CAGE code. Empty until SAM.gov checks are added. |
| `naicsCode` | Primary NAICS. Empty until SAM.gov checks are added. |
| `lifetimeObligationAmount` | Lifetime federal obligations for that USAspending recipient level. |
| `awardCount`, `obligationByFiscalYear`, `topAwards` | Award history inside the fiscal-year window. `topAwards` lists the largest contracts. IDVs, grants, and loans stay in `awardCount`. |
| `samStatus`, `samReason` | `not-checked`, with a sentence, until SAM.gov checks are added. |
| `registrationStatus`, `registrationExpirationDate` | SAM.gov registration. Empty until those checks are added. |
| `exclusionFlag` | Null until exclusions are checked. |
| `registrationExpiring`, `daysUntilRegistrationExpiry` | Null until SAM.gov checks are added. |

A company that cannot be matched is still a row, with `notFound: true`. That row is not charged.

Points of contact, email addresses, and individual exclusion names are not requested and not stored.

### How to look up a contractor

1. Open the Actor and leave **Mode** on Lookup.
2. Paste company names, UEIs, or CAGE codes into **Company name, UEI, or CAGE**. A 12-character token is a UEI. A 5-character token is a CAGE code. Anything else is a name. Or fill **Company names**, **UEIs**, and **CAGE codes** separately when you are chaining another Actor.
3. Leave **SAM.gov API key** empty. No key is configured yet, and SAM.gov checks are coming later.
4. Run. Download the dataset as JSON, CSV, or Excel. The run summary is the `RUN_SUMMARY` record in the key-value store.
5. Watch mode is for later, when SAM.gov checks are on. Set **Mode** to Watch, set **Expiry window (days)** (default 90), and schedule the Actor with one **Watchlist ID** per list.

A CAGE code cannot be resolved until SAM.gov checks are available. The row explains that, and no USAspending call is made for it.

### How much will it cost?

Pay per event, with no start fee. **$0.004** for each `company-profile`. One event is one matched contractor profile (the USAspending recipient and award history). Not-found rows are not charged. Watch alerts are not charged.

Default memory is 128 MB and the default timeout is 180 seconds. There is no proxy.

### Input

See the input tab for every field. The lists accept up to **Max companies** lines (default 25, maximum 100). **Award history window** is a number of federal fiscal years ending today (default 3). **Top awards to include** defaults to 5. Set it to 0 to skip that request.

### Output

You can download the dataset in JSON, CSV, HTML, or Excel. A lookup without a SAM.gov key looks like this:

```json
{
  "recordType": "profile",
  "query": "EXAMPLE CORPORATION",
  "queryType": "name",
  "notFound": false,
  "uei": "E1AMP2UEI3X4",
  "ueiSAM": "E1AMP2UEI3X4",
  "companyName": "EXAMPLE CORPORATION",
  "legalName": "EXAMPLE CORPORATION",
  "cageCode": null,
  "naicsCode": null,
  "state": "TX",
  "lifetimeObligationAmount": 120000,
  "recentAwardCount": 2,
  "samChecked": false,
  "samStatus": "not-checked",
  "samReason": "SAM.gov was not checked because SAM_GOV_API_KEY is not set.",
  "registrationExpiring": null,
  "exclusionFlag": null
}
```

A watch alert is a second row with `recordType: "alert"` and `alertType` of `REGISTRATION_EXPIRING`, `REGISTRATION_EXPIRED`, or `EXCLUSION_PRESENT`. It repeats `uei`, `ueiSAM`, `companyName`, `legalName`, and `cageCode`.

### Tips

Keep **Max companies** at the default unless you need a longer list. Raise memory only if a run is killed. 128 MB is enough. The cache lasts 24 hours. When SAM.gov checks are added later, schedule watch runs no more than once a day, because a personal SAM.gov key allows 10 requests per day.

`CONTRACTOR_CACHE_HOURS` can shorten the cache. Leave it unset in production.

### FAQ

**Do I need an API key?** No. USAspending needs no key. SAM.gov checks are coming later because no SAM.gov API key is configured yet. Until then, `samStatus` is `not-checked` and the USAspending fields are still filled.

**Why is SAM.gov missing on a row that has a UEI?** SAM.gov checks are coming later. No key is configured yet, so registration, CAGE, NAICS, and exclusions are not checked. `samReason` says so. The USAspending profile is still returned.

**What does the first watch run return?** A profile for each matched company, plus an alert if a registration is already inside the expiry window or an exclusion is already on file. Later runs alert only when that fact is new.

**Are people included?** No. The exclusions request does not ask for individual records by name, and any individual classification is stored without a personal name or address.

### Data source and licence

USAspending data is public federal spending data from [api.usaspending.gov](https://api.usaspending.gov). SAM.gov registration and exclusion checks are coming later, once a key is configured. Those checks will use the public SAM.gov entity and exclusion APIs and will request `entityRegistration`, `coreData`, and `assertions` only. Points of contact are not requested.

Commercial reuse of these public records is your responsibility under the source terms.

# Actor input Schema

## `companies` (type: `array`):

One company per line. A 12-character UEI (letters and digits, no I or O) is looked up as a UEI. A 5-character token is looked up as a CAGE code. Anything else is a company name. A CAGE code can be resolved only when SAM_GOV_API_KEY is set.

## `names` (type: `array`):

Company names to look up on USAspending. Use this when chaining from us-federal-tender-monitor (awardee name), sec-edgar-filings-watch (companyName), or fmcsa-carrier-watch (legalName).

## `ueis` (type: `array`):

12-character Unique Entity IDs. Same value this Actor writes as uei and ueiSAM.

## `cageCodes` (type: `array`):

5-character CAGE codes. Resolved through SAM.gov when SAM_GOV_API_KEY is set, then enriched from USAspending.

## `mode` (type: `string`):

lookup returns one profile per company. watch does the same and also emits an alert when a registration expires within Expiry window days, is already expired, or a new exclusion appears. The same alert is not repeated on the next run with the same Watchlist ID.

## `expiryWithinDays` (type: `integer`):

Flag registrationExpiring when the SAM.gov registration expiration date is within this many days. Already-expired registrations are flagged as registrationExpired. Used in both modes; watch mode also emits an alert row.

## `watchlistId` (type: `string`):

Name of the saved watch snapshot. Use one ID per list. State is one gzipped record in the named key-value store us-contractor-profile-state.

## `awardFiscalYears` (type: `integer`):

How many federal fiscal years of USAspending award history to summarize, counting the current fiscal year. 3 on 5 Oct 2026 covers FY2025 through FY2027.

## `maxAwards` (type: `integer`):

Largest awards to list in topAwards, inside the fiscal-year window. 0 skips that request.

## `includeExclusions` (type: `boolean`):

When a SAM.gov key is set, one batched exclusions request covers every company in the run. Turn off to spend that request only on registration.

## `maxCompanies` (type: `integer`):

Maximum companies looked up in this run (1-100). Extra lines are counted and skipped.

## `samGovApiKey` (type: `string`):

Optional. Leave empty to use the SAM_GOV_API_KEY environment variable or Apify secret. When neither is set, SAM.gov registration and exclusions are not checked and USAspending data is still returned.

## Actor input object example

```json
{
  "companies": [
    "EXAMPLE CORPORATION"
  ],
  "names": [],
  "ueis": [],
  "cageCodes": [],
  "mode": "lookup",
  "expiryWithinDays": 90,
  "watchlistId": "default",
  "awardFiscalYears": 3,
  "maxAwards": 5,
  "includeExclusions": true,
  "maxCompanies": 25
}
```

# Actor output Schema

## `overview` (type: `string`):

Dataset with one profile or one watch alert per item

## `summary` (type: `string`):

Status, request counts, SAM.gov check, and charge limit

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "companies": [
        "EXAMPLE CORPORATION"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("mikee368/us-contractor-profile").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "companies": ["EXAMPLE CORPORATION"] }

# Run the Actor and wait for it to finish
run = client.actor("mikee368/us-contractor-profile").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "companies": [
    "EXAMPLE CORPORATION"
  ]
}' |
apify call mikee368/us-contractor-profile --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,mikee368/us-contractor-profile"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/MwYbm8GTUBc5USREP/builds/2KBNHKua9PKjWUesO/openapi.json
