# Cemetery & Death Records Database - Find A Grave Scraper (`jungle_synthesizer/findagrave-memorial-death-record-scraper`) Actor

Scrape memorial and death records from Find A Grave, the largest cemetery directory on the web. Returns birth/death dates and places, cemetery location, plot info, and linked family memorials across 250M+ memorials worldwide.

- **URL**: https://apify.com/jungle\_synthesizer/findagrave-memorial-death-record-scraper.md
- **Developed by:** [BowTiedRaccoon](https://apify.com/jungle_synthesizer) (community)
- **Categories:** Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.40 / 1,000 record scrapeds

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

## Cemetery & Death Records Database — Find A Grave Scraper

Scrape memorial and death records from [Find A Grave](https://www.findagrave.com), the largest cemetery directory on the web. Returns birth and death dates, birth and death places, cemetery location, plot info, grave photo status, and linked family memorials for a corpus that spans roughly 250 million memorials across some 600,000 cemeteries worldwide.

***

### Find A Grave Scraper Features

- Searches by first and/or last name and returns matching memorials directly.
- Walks the full worldwide cemetery directory — continent, country, state, county, cemetery — when you want the whole corpus instead of one name.
- Extracts birth and death dates and places, not just years. When the source has a full date, so do you.
- Captures plot location, grave photo status, and any inscription text left on the memorial page.
- Returns linked family members — parents, spouse, children, siblings — as structured records with their own memorial IDs, so one search opens onto a family tree instead of a single row.
- Resumes a stopped crawl from where it left off, at no extra charge for what it already delivered.

***

### Who Uses Find A Grave Data?

- **Skip tracers and collections agencies** — confirm someone is deceased before spending further effort on a locate. A death date closes a file.
- **Genealogy researchers** — build out a family tree using the linked parent, spouse, and child records instead of chasing each name by hand.
- **Insurance SIU teams** — cross-check a claimed death against a public burial record during claims validation.
- **Probate and heir-location firms** — use the family links to map who else might have a claim, starting from a single memorial.
- **Funeral homes and memorial services** — check whether a family member already has a memorial on record before creating a duplicate.

***

### How Find A Grave Scraper Works

1. Pick a mode: search by name, or browse the full cemetery directory for everything the source publishes.
2. The scraper finds matching memorials — either from your name query or by walking down through cemeteries — and opens each one.
3. Each memorial page is parsed into a full record: dates, places, cemetery, plot, photo status, family links, and any inscription.
4. Records land in your dataset as they're found. Set `maxItems` to cap the run, or leave it high and let it run.

***

### Input

```json
{
  "searchMode": "name",
  "firstName": "John",
  "lastName": "Smith",
  "maxItems": 100
}
```

| Field          | Type    | Default  | Description |
|----------------|---------|----------|-------------|
| `searchMode`   | string  | `browse` | `browse` walks the full cemetery directory worldwide (no filter — the entire corpus). `name` searches by first and/or last name instead. |
| `firstName`    | string  | —        | First name to search for. Used only when `searchMode` is `name`. |
| `lastName`     | string  | —        | Last name to search for. Used only when `searchMode` is `name`. |
| `maxItems`     | integer | `10`     | Maximum number of memorial records to return. Required. |
| `resumeCursor` | string  | —        | Cursor from a previous run's Output. Continues a stopped crawl instead of starting over. |

To browse the whole directory instead of searching a name:

```json
{
  "searchMode": "browse",
  "maxItems": 5000
}
```

***

### Find A Grave Scraper Output Fields

```json
{
  "memorial_id": 20491559,
  "full_name": "John Smith",
  "maiden_name": null,
  "birth_date": "4 Aug 1823",
  "birth_place": "Germany",
  "death_date": "6 Oct 1867",
  "death_place": "Rome, Jefferson County, Wisconsin, USA",
  "age_at_death": 44,
  "cemetery_id": 88831,
  "cemetery_name": "Riverview Cemetery",
  "cemetery_city": "Rome",
  "cemetery_county": "Jefferson County",
  "cemetery_state": "Wisconsin",
  "cemetery_country": "USA",
  "plot_info": "W-293",
  "has_grave_photo": true,
  "family_links": [
    { "relation": "Spouse", "memorial_id": 20491560, "name": "Margaret Landgraf Smith" }
  ],
  "inscription": null,
  "memorial_url": "https://www.findagrave.com/memorial/20491559/john-smith",
  "scraped_at": "2026-09-28T19:42:41.151Z"
}
```

| Field              | Type    | Description                                                                                           |
|--------------------|---------|-------------------------------------------------------------------------------------------------------|
| `memorial_id`      | integer | Find A Grave memorial ID                                                                              |
| `full_name`        | string  | Name on the memorial                                                                                  |
| `maiden_name`      | string  | Birth surname, when shown separately from the married/display name                                    |
| `birth_date`       | string  | Birth date as recorded — a full date or a bare year, whichever the memorial has                       |
| `birth_place`      | string  | Birth place as recorded                                                                               |
| `death_date`       | string  | Death date as recorded                                                                                |
| `death_place`      | string  | Death place as recorded                                                                               |
| `age_at_death`     | integer | Age at death in years                                                                                 |
| `cemetery_id`      | integer | Find A Grave cemetery ID                                                                              |
| `cemetery_name`    | string  | Cemetery name                                                                                         |
| `cemetery_city`    | string  | Cemetery city                                                                                         |
| `cemetery_county`  | string  | Cemetery county                                                                                       |
| `cemetery_state`   | string  | Cemetery state or province                                                                            |
| `cemetery_country` | string  | Cemetery country                                                                                      |
| `plot_info`        | string  | Plot or section location within the cemetery                                                          |
| `has_grave_photo`  | boolean | Whether the memorial has a grave photo                                                                |
| `family_links`     | array   | Linked parent, spouse, child, and sibling memorials — each with `relation`, `memorial_id`, and `name` |
| `inscription`      | string  | Biography or inscription text on the memorial                                                         |
| `memorial_url`     | string  | Canonical memorial URL                                                                                |
| `scraped_at`       | string  | Timestamp the record was scraped                                                                      |

Most memorials don't carry every field — a plot location or an inscription depends entirely on what the original contributor entered. The fields that exist, exist because the source has them.

***

### Resuming a large crawl

Every run emits a `resumeCursor` in its Output. If a large crawl stops before it finishes — because it hit `maxItems`, your spend cap (`maxTotalChargeUsd`), or was aborted — start a new run with **the same input** plus that `resumeCursor` to continue from where it left off. The crawl resumes from the queued work the previous run didn't reach.

- You are **not re-charged** for records the earlier run already delivered.
- Resume within your account's run-retention window — on the free tier, roughly your 10 most recent runs. Once the source run is pruned, its `resumeCursor` is no longer valid.
- `resumeCursor` is opaque — supply it unmodified.

***

### FAQ

#### How do I scrape Find A Grave?

Set `searchMode` to `name` with a first and/or last name, or set it to `browse` to walk the full directory without any filter. Either way, set `maxItems` and run it.

#### How much does Find A Grave Scraper cost to run?

Find A Grave Scraper uses pay-per-event pricing — you pay per record returned. Everything needed to reach the site is included in the price. A name search that returns a handful of matches costs a few cents; a full directory walk scales with however many records you ask for.

#### What data can I get from Find A Grave?

Birth and death dates and places, cemetery location down to city and plot, grave photo status, any inscription text, and linked family members with their own memorial IDs. It's a death record and a family tree in one row.

#### Can I search by name instead of browsing cemeteries?

Yes. Set `searchMode` to `name` and provide a first name, a last name, or both. Find A Grave Scraper returns every matching memorial it finds.

#### Do I need an account or API key for Find A Grave?

No. Find A Grave Scraper needs nothing from you beyond your search terms or a `maxItems` value.

***

### Need More Features?

Need custom fields, filters, or a different target site? [File an issue](https://console.apify.com/actors/issues) or get in touch.

### Why Use Find A Grave Scraper?

- **The largest cemetery corpus available** — roughly 250 million memorials, about two orders of magnitude more than the next-largest genealogy scraper in the category.
- **Family links, not just a name** — parents, spouse, children, and siblings come back as structured records with their own memorial IDs, turning a flat death record into a relationship graph.
- **Two ways in** — search a name directly, or point it at the full worldwide directory and let it run.

# Actor input Schema

## `sp_intended_usage` (type: `string`):

What will this data feed? E.g. lead lists, KYB checks, price tracking.

## `sp_improvement_suggestions` (type: `string`):

Provide any feedback or suggestions for improvements.

## `sp_contact` (type: `string`):

We'll personally help with your use case. No spam.

## `resumeCursor` (type: `string`):

Leave empty for a fresh crawl. To CONTINUE a previous run where it stopped — without paying again for records you already received — paste the `resumeCursor` value from that run's Output (the run's OUTPUT key). Resume promptly: the previous run's data expires with your account's retention window (free tier: your ~10 most recent runs).

## `searchMode` (type: `string`):

'browse' walks Find A Grave's full cemetery directory worldwide (default — no filter, the entire corpus). 'name' searches by first and/or last name instead.

## `firstName` (type: `string`):

First name to search for. Only used when Search Mode is 'Search by name'.

## `lastName` (type: `string`):

Last name to search for. Only used when Search Mode is 'Search by name'.

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

Maximum number of memorial records to scrape

## Actor input object example

```json
{
  "sp_intended_usage": "Describe your intended use...",
  "sp_improvement_suggestions": "Share your suggestions here...",
  "sp_contact": "Share your email here...",
  "searchMode": "browse",
  "maxItems": 10
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# 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 = {
    "sp_intended_usage": "Describe your intended use...",
    "sp_improvement_suggestions": "Share your suggestions here...",
    "sp_contact": "Share your email here...",
    "searchMode": "browse",
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("jungle_synthesizer/findagrave-memorial-death-record-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 = {
    "sp_intended_usage": "Describe your intended use...",
    "sp_improvement_suggestions": "Share your suggestions here...",
    "sp_contact": "Share your email here...",
    "searchMode": "browse",
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("jungle_synthesizer/findagrave-memorial-death-record-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 '{
  "sp_intended_usage": "Describe your intended use...",
  "sp_improvement_suggestions": "Share your suggestions here...",
  "sp_contact": "Share your email here...",
  "searchMode": "browse",
  "maxItems": 10
}' |
apify call jungle_synthesizer/findagrave-memorial-death-record-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jungle_synthesizer/findagrave-memorial-death-record-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/mzmSgIocd4KcsbELy/builds/rduDdZ8o43Jz64NQf/openapi.json
