# BOP Federal Inmate Locator (`automation-lab/bop-federal-inmate-locator`) Actor

Look up supplied known BOP register numbers and export raw identity, public facility, release codes and dates with provenance for bounded legal and journalistic research.

- **URL**: https://apify.com/automation-lab/bop-federal-inmate-locator.md
- **Developed by:** [Automation Lab](https://apify.com/automation-lab) (community)
- **Categories:** Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.63 / 1,000 item processeds

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

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

## BOP Federal Inmate Locator

Perform a bounded **BOP inmate search by register number** against the official Federal Bureau of Prisons locator. Supply already known register numbers and export raw source identity, public facility fields, release codes, dates and retrieval provenance for legal and journalistic public-record research.

This is not a population database, background-check service or identity-resolution tool. It does not support name-only search, generate numbers, enumerate inmates or make eligibility decisions.

### Who is it for?

Legal researchers can retrieve source records for a bounded list of known register numbers. Journalists can preserve a dated source snapshot and compare it with their own earlier research. Each run makes fresh lookups; no historical archive or alert engine is included.

### Why use this BOP inmate locator?

- Exact register-number matching instead of ambiguous name matching.
- Actual and projected release dates remain separate, as raw source text.
- Source URL and UTC retrieval time accompany every matching row.
- No demographic enrichment, risk score or inferred custody classification.
- Duplicate supplied numbers are normalized before requests and item charging.

### Getting started

1. Obtain the known BOP register number through your authorized research.
2. Open the input form and supply between 1 and 25 numbers.
3. Start the Actor and wait for its terminal status.
4. Inspect the default dataset and the `SUMMARY` key-value record.
5. Export permitted results as JSON, CSV or Excel through Apify.

The prefilled `61727-054` is the widely reported register number of deceased public figure Bernard Madoff. Use your own authorized known-number list for research. Do not construct number ranges.

### Input parameters

```json
{"registerNumbers":["61727-054"]}
```

| Parameter | Behavior |
|---|---|
| `registerNumbers` | Required string array, 1–25 entries before deduplication. Each must be eight digits or `NNNNN-NNN`. Leading/trailing whitespace is trimmed; duplicates are removed after normalization. |

Other input fields are rejected. There is no name, location, race, age, eligibility, date-range, population or wildcard filter. No automatic proxy or browser fallback is enabled.

### Extracted data

| Field | Meaning |
|---|---|
| `registerNumber` | Exact BOP register number returned by the source |
| `firstName`, `middleName`, `lastName`, `suffix` | Raw source identity text |
| `facilityCode`, `facilityName`, `facilityType` | Raw source facility metadata, not an inferred current location |
| `facilityUrl` | Absolute official facility URL, or an empty string |
| `releaseCode` | Raw BOP release code |
| `actualReleaseDate` | Raw actual date text, or an empty string |
| `projectedReleaseDate` | Raw projected date text, or an empty string |
| `sourceUrl` | Official locator page |
| `retrievedAt` | Retrieval time in UTC, not a source update timestamp |

Empty source strings are preserved. Dates are not guessed or converted into eligibility conclusions. A populated facility field can remain present after release or death: never interpret it alone as proof of current custody.

### Output example

This anonymized illustration follows the tested output shape; it is not a real person or a valid research target.

```json
{
  "registerNumber": "00000-000",
  "firstName": "EXAMPLE",
  "middleName": "",
  "lastName": "PERSON",
  "suffix": "",
  "facilityCode": "ABC",
  "facilityName": "Example",
  "facilityType": "FMC",
  "facilityUrl": "https://www.bop.gov/locations/institutions/abc/",
  "releaseCode": "D",
  "actualReleaseDate": "01/01/2020",
  "projectedReleaseDate": "",
  "sourceUrl": "https://www.bop.gov/inmateloc/",
  "retrievedAt": "2026-10-23T12:00:00.000Z"
}
```

### How much does it cost to look up BOP register numbers?

Pay-per-event pricing includes a **$0.005 start fee** per validated run and a tiered fee for each matching dataset record. No-match lookups, duplicates and failed requests have no item event fee. A run with no matches still incurs the start fee. Platform budget controls can stop a run before all numbers are processed.

BRONZE **$0.006049 per record**. At this BRONZE rate, one matching record costs approximately $0.011049 including start; five cost $0.035245; 25 cost $0.156225. These are estimates, not guaranteed invoices. Spend tiers follow your aggregate qualifying monthly Apify Store spend, not this Actor's private volume tiers.

| Tier | Matching-record event price |
|---|---:|
| FREE | $0.0069563 |
| BRONZE | $0.006049 |
| SILVER | $0.0047182 |
| GOLD | $0.0036294 |
| PLATINUM | $0.0036294 |
| DIAMOND | $0.0036294 |

The $0.005 start event is the same at every tier. Consult the Pricing tab for the applicable active rate.

### Limits and failure behavior

Each run accepts at most 25 supplied numbers and uses sequential requests. It does not paginate or discover more numbers. Repeated scheduled runs do not constitute historical source coverage.

Network failures, rate limits and temporary server errors receive at most three attempts per number with bounded backoff. A challenge, permanent HTTP failure, source error message, mismatched number or unexpected response fails the run rather than pretending it is a legitimate no-match result. If a later lookup fails, already saved rows are partial and remain in storage.

A recognized empty result produces no dataset row. `SUMMARY` records aggregate saved and no-match counts, without a second list of personal identifiers. An empty dataset does not prove a person has no federal record.

### Integrations

Export the default dataset to a restricted-access research spreadsheet or your existing case-management pipeline. Use Apify webhooks to notify your workflow that a run finished, then check its status before importing data. Compare dated snapshots in your own authorized system; this Actor does not infer changes or send custody alerts.

### API usage

Use an Apify token stored securely, not embedded in shared documents.

```bash
curl -X POST 'https://api.apify.com/v2/acts/automation-lab~bop-federal-inmate-locator/runs' \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"registerNumbers":["61727-054"]}'
```

JavaScript using `apify-client`:

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/bop-federal-inmate-locator')
  .call({ registerNumbers: ['61727-054'] });
const { items } = await client.dataset(run.defaultDatasetId).listItems({ limit: 25 });
```

Python using `apify-client`:

```python
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/bop-federal-inmate-locator').call(
    run_input={'registerNumbers': ['61727-054']})
items = client.dataset(run['defaultDatasetId']).list_items(limit=25).items
```

### MCP setup and bounded results

For an authorized MCP client, select this stable Actor-specific endpoint:

```bash
claude mcp add --transport http apify \
  'https://mcp.apify.com?tools=automation-lab/bop-federal-inmate-locator'
```

Equivalent HTTP configuration for Claude Desktop, Cursor and VS Code (use the configuration location and authentication flow supported by your client):

```json
{"mcpServers":{"apify":{"url":"https://mcp.apify.com?tools=automation-lab/bop-federal-inmate-locator"}}}
```

Authenticate through the client's supported Apify flow. Discover actual tool names and input schemas using scoped `tools/list`; Actor selection also adds run/data helper tools, not exactly one tool. Discovery does not authorize running an Actor.

Example prompts for authorized use: “Retrieve raw release fields for my supplied known numbers, without inference.” Another example authorized instruction: “Look up my supplied known BOP register number, preserve raw dates and provenance, and do not infer custody or eligibility.”

Start once, retain the run ID and storage IDs, and follow the same run. `call-actor` may return before completion (waitSecs 0–45, default 30). Poll that same ID with bounded backoff (2, 4, 8 seconds, capped at 10) and a 120-second total deadline; report pending at the deadline. Set client timeout above the chosen server wait plus transport margin. Recover a known run after client timeout; never restart just to poll. If its ID is unknown, report uncertainty. Failed-run rows are partial, not a completed answer.

After success, read the returned dataset ID with `get-dataset-items`, explicit `limit`, `offset` and needed `fields`. A suggested consumer budget is pages of 20, at most 25 source rows or 64 KiB of serialized UTF-8 content, whichever comes first. Enforce the byte limit host-side before model injection, including oversized rows. If the client cannot intercept oversized responses, do not claim a hard byte guarantee. Track source offsets, disclose truncation and continuation offset, and keep full exports outside model context. These are consumer limits, not reductions to the Actor's collection contract. No numeric token-savings claim is made.

### Legality and responsible use

Use only for lawful, bounded legal and journalistic research with already known identifiers. This tool is not a consumer-reporting agency or an employment, housing, credit, insurance, parole or other eligibility decision service. Do not use it for harassment, discriminatory screening, population enumeration, identity inference or combining unrelated personal profiles.

Public availability does not remove privacy or accuracy obligations. Verify material facts with the official source and appropriate professionals. BOP coverage and release information can change or be incomplete; absence is not proof, and source dates may be revised. Restrict dataset access, retain only necessary records and delete research snapshots when no longer needed.

Failed operations send sanitized diagnostic input, exceptions and Actor/build/run IDs to our private GlitchTip service for repair. Secret fields and URL queries are removed; registerNumbers is explicitly redacted. Reports are retained for 30 days. Do not submit personal free text in unsupported fields.

### Troubleshooting and FAQ

**Can I search by name?** No. Only supplied known BOP register numbers are supported.

**Why did I receive no row?** A recognized no-match response emits no row. Check `SUMMARY` and verify the number manually. Do not conclude that no criminal record exists.

**Why did the run fail?** An upstream error or challenge is not a no-match. Inspect the safe run message, check the official locator and retry later rather than expanding the number list.

**Does a facility name mean current custody?** No. Raw fields may be retained for released or deceased people. No current-custody inference is provided.

**Are sentence details or demographics included?** No. The output is limited to the documented source identity, facility and release fields.

### Data handling and support

No AI model processes inputs or output. BOP receives the supplied number as a normal locator request; Apify stores run input and output under your account's storage and retention settings until expiry or deletion. There is no cross-run cache. Delete datasets, INPUT and run storage through Apify when research ends; no automatic Actor-side deletion is promised. Logs contain aggregate counts and generic failure messages, not response bodies. Contact the Actor's Issues tab for support without posting personal research records publicly. This independently developed Actor is not affiliated with, endorsed by or certified by BOP or the US government. The icon is an original generated illustration, not an official seal.

### Related tools

This is a standalone public-record research workflow. We intentionally do not cross-link marketing or people-enrichment Actors, or imply automated screening compatibility.

# Changelog

This Actor's version history is a separate document: https://apify.com/automation-lab/bop-federal-inmate-locator/changelog.md

# Actor input Schema

## `registerNumbers` (type: `array`):

Supply 1–25 already known BOP register numbers as strings (NNNNN-NNN or eight digits). Whitespace is trimmed, hyphens normalized and duplicates removed before exact-number lookups. At most one matching record per unique number is emitted; no-match lookups produce no row or item fee. No names, ranges, wildcard generation or inferred identities.

## Actor input object example

```json
{
  "registerNumbers": [
    "61727-054"
  ]
}
```

# Actor output Schema

## `dataset` (type: `string`):

Matching BOP records with raw release fields and retrieval provenance.

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

Aggregate supplied, saved and no-match counts without personal identifiers.

# 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 = {
    "registerNumbers": [
        "61727-054"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/bop-federal-inmate-locator").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 = { "registerNumbers": ["61727-054"] }

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/bop-federal-inmate-locator").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 '{
  "registerNumbers": [
    "61727-054"
  ]
}' |
apify call automation-lab/bop-federal-inmate-locator --silent --output-dataset

```

## MCP server setup

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

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/2sVihdccfkrggwB1e/builds/Wqnmx21wtDXd4xFl1/openapi.json
