# BOP Inmate Locator Scraper (`crawlerbros/bop-inmate-locator-scraper`) Actor

Scrape the U.S. Federal Bureau of Prisons Inmate Locator. Search federal inmates by name or register number, browse the register, and get register number, age, race, sex, release dates, and facility details.

- **URL**: https://apify.com/crawlerbros/bop-inmate-locator-scraper.md
- **Developed by:** [Crawler Bros](https://apify.com/crawlerbros) (community)
- **Categories:** Automation, Lead generation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## BOP Inmate Locator Scraper

Scrape the **U.S. Federal Bureau of Prisons (BOP) Inmate Locator** — the official public directory of people in federal custody. Search by name or register number, browse the register, and get register number, age, race, sex, release dates, and facility details for every record. HTTP-only against the public bop.gov service — no auth, no proxy needed.

### What this actor does

- **Three modes:** `searchByName`, `searchByNumber`, `browseAll`
- **Name search:** first + last name (required), optional middle name/initial
- **Number search:** BOP register number, DCDC, FBI, or INS number
- **Register browse:** systematic sweep over the most common US first/last name combinations (deduplicated)
- **Filters:** race, sex, age range, keyword in name or facility
- **Release data:** projected and actual release dates, release status
- **Facility data:** current facility name, type, code, and location URL
- **Empty fields are omitted**

### Data Source

The official U.S. Federal Bureau of Prisons Inmate Locator (www.bop.gov/inmateloc) — the public web service that powers the BOP's own search. HTTP-only against the public bop.gov service; no auth, no proxy required. The actor is not affiliated with the BOP.

### Output per inmate

- `registerNumber` — BOP register number, e.g. `00123-871`
- `numberType` — type of number the lookup matched (`IRN` / `DCDC` / `FBI` / `INS`)
- `nameFirst`, `nameMiddle`, `nameLast`, `suffix`, `fullName`
- `age`, `race`, `sex`
- `releaseCode`, `releaseStatus` — Released / Deceased / Escaped / Absconded / Not in BOP Custody
- `projectedReleaseDate` — projected release date (in custody)
- `actualReleaseDate` — actual release date (released)
- `releaseDate` — whichever release date applies
- `facilityCode`, `facilityName`, `facilityType` — e.g. `CDT`, `Detroit`, `RRM`
- `facilityUrl` — BOP facility page for the location
- `sourceUrl` — canonical locator deep-link for this register number
- `recordType: "inmate"`, `scrapedAt`

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | string | `searchByName` | `searchByName` / `searchByNumber` / `browseAll` |
| `nameFirst` | string | `john` | First name (mode=searchByName) |
| `nameLast` | string | `smith` | Last name (mode=searchByName) |
| `nameMiddle` | string | – | Middle name or initial (mode=searchByName) |
| `registerNumber` | string | – | Register number, e.g. `00123-871` (mode=searchByNumber) |
| `numberType` | select | IRN | IRN / DCDC / FBI / INS (mode=searchByNumber) |
| `race` | select | Any | American Indian / Asian / Black / White |
| `sex` | select | Any | Male / Female |
| `ageMin` | int | – | Minimum age |
| `ageMax` | int | – | Maximum age |
| `containsKeyword` | string | – | Only emit inmates whose name or facility contains this keyword |
| `maxItems` | int | `100` | Hard cap (1–10000) |
| `proxyConfiguration` | proxy | off | Optional; auto-engaged only if bop.gov blocks direct requests |

#### Example: search by name with filters

```json
{
  "mode": "searchByName",
  "nameFirst": "john",
  "nameLast": "smith",
  "sex": "M",
  "ageMin": 40,
  "maxItems": 25
}
```

#### Example: lookup by register number

```json
{
  "mode": "searchByNumber",
  "registerNumber": "00123-871",
  "numberType": "IRN"
}
```

#### Example: browse a segment of the register

```json
{
  "mode": "browseAll",
  "race": "W",
  "ageMin": 30,
  "ageMax": 60,
  "maxItems": 200
}
```

#### Example: keyword-filtered search

```json
{
  "mode": "searchByName",
  "nameFirst": "james",
  "nameLast": "williams",
  "containsKeyword": "Florence",
  "maxItems": 50
}
```

### Limitations

- **100-record cap per query** — the BOP service returns at most 100 records per name lookup. The actor paginates within that cap and reports when a query is truncated.
- **`browseAll` is a name sweep, not a census** — bop.gov has no "show everyone" query, so browse mode queries the most common US first/last name combinations and deduplicates. It covers a large share of the register but is not a complete enumeration of every inmate.
- **First AND last name are required** — bop.gov itself rejects searches with only one part.
- **No sentence or case data** — the public locator exposes only the fields listed above; case files require the BOP's FOIA portal.
- **Captcha under aggressive use** — the service may demand a captcha when queried too quickly; the actor spaces requests and retries automatically.
- **Some fields are always absent for some records** — e.g. released inmates have no projected release date. Empty fields are never emitted.

### Use cases

- **Legal research** — locate federal defendants and verify register numbers and release dates
- **Reentry services** — discover projected release dates and receiving facilities for case planning
- **Journalism & policy analysis** — demographic breakdowns (race, sex, age) of the federal register
- **Family support** — confirm where a loved one is held and whether they have been released
- **Compliance checks** — verify an individual's federal custody status

### FAQ

- **What is the data source?** The official U.S. Federal Bureau of Prisons Inmate Locator (www.bop.gov/inmateloc). This actor is not affiliated with the BOP.
- **How fresh is the data?** Every record is fetched live from bop.gov at run time.
- **Why do some searches return fewer than 100 records?** The BOP service returns at most 100 records per query and asks for a captcha when queried too aggressively. This actor spaces out requests and retries automatically.
- **What happens with an inverted age range (`ageMin` > `ageMax`)?** An inverted range can never match — the actor emits 0 records with a status message instead of filtering forever.
- **Why does `browseAll` use a name sweep instead of a plain listing?** bop.gov has no "show everyone" query — searches match exact name parts and cap at 100 records. The browse mode systematically queries the most common US first/last name combinations and deduplicates results, which covers a large share of the register while respecting the service's constraints.
- **Why is a first AND last name required?** bop.gov itself requires both fields; searches with only one return no results.
- **Where is sentence / case information?** The public locator only exposes the fields listed above (it has no sentence or case detail). Use the BOP's Freedom of Information portal for case files.
- **Why are some fields missing from some records?** Fields are omitted when the source has no value for them — for example, released inmates have no projected release date. Empty fields are never emitted.
- **Do I need a proxy or account?** No. The public service works without credentials or proxy. A proxy is engaged automatically only if bop.gov blocks direct requests.

# Actor input Schema

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

What to fetch.

## `nameFirst` (type: `string`):

First name or initial. Required together with last name (mode=searchByName).

## `nameLast` (type: `string`):

Last name. Required together with first name (mode=searchByName).

## `nameMiddle` (type: `string`):

Optional middle name or initial (mode=searchByName).

## `registerNumber` (type: `string`):

BOP register number, e.g. `00123-871` or `12345678` (mode=searchByNumber).

## `numberType` (type: `string`):

Type of number to look up (mode=searchByNumber).

## `race` (type: `string`):

Restrict results by race.

## `sex` (type: `string`):

Restrict results by sex.

## `ageMin` (type: `integer`):

Drop inmates younger than this age.

## `ageMax` (type: `integer`):

Drop inmates older than this age.

## `containsKeyword` (type: `string`):

Only emit inmates whose name or facility contains this keyword (case-insensitive).

## `maxItems` (type: `integer`):

Hard cap on emitted records. The BOP API returns at most 100 records per query.

## `proxyConfiguration` (type: `object`):

Optional Apify proxy. Automatically engaged only if bop.gov blocks direct requests (403/429).

## Actor input object example

```json
{
  "mode": "searchByName",
  "nameFirst": "john",
  "nameLast": "smith",
  "numberType": "IRN",
  "race": "",
  "sex": "",
  "maxItems": 10,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `inmates` (type: `string`):

Dataset containing all scraped inmate records.

# 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 = {
    "mode": "searchByName",
    "nameFirst": "john",
    "nameLast": "smith",
    "numberType": "IRN",
    "race": "",
    "sex": "",
    "maxItems": 10,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawlerbros/bop-inmate-locator-scraper").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 = {
    "mode": "searchByName",
    "nameFirst": "john",
    "nameLast": "smith",
    "numberType": "IRN",
    "race": "",
    "sex": "",
    "maxItems": 10,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("crawlerbros/bop-inmate-locator-scraper").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 '{
  "mode": "searchByName",
  "nameFirst": "john",
  "nameLast": "smith",
  "numberType": "IRN",
  "race": "",
  "sex": "",
  "maxItems": 10,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call crawlerbros/bop-inmate-locator-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,crawlerbros/bop-inmate-locator-scraper"
        }
    }
}

```

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/lrgUNNbUeI1iOsgER/builds/E9EYYQEuPdvQRlkIA/openapi.json
