> ## Documentation Index
> Fetch the complete documentation index at: https://docs.virtuous.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Donors

> The Donor resource in Raise — identity fields, sub-resources for addresses and contact methods, and the special operations like merge, archive, and transfer.

The Donor is Raise's primary donor-side record. Every Gift, RecurringGift, and donor-related activity attaches to a Donor. The resource has a richer surface than most others in the API — over 30 dedicated endpoints span basic CRUD, sub-resources for addresses and contact methods, lifecycle operations (archive, merge), and specialized operations (transfer a Gift between Donors).

This page covers the resource shape, the sub-resource pattern Raise uses for addresses and contact methods, and the operations that don't map to plain CRUD.

## The Donor record

The core fields on a Donor record:

### Identity

| Field              | Type    | Description                                                                                               |
| ------------------ | ------- | --------------------------------------------------------------------------------------------------------- |
| `id`               | integer | The Raise primary key. Assigned at creation, immutable after.                                             |
| `name`             | string  | Display name. For households, typically `"FirstName LastName"`; for organizations, the organization name. |
| `title`            | string  | Optional title — Dr., Rev., etc.                                                                          |
| `firstName`        | string  | Given name.                                                                                               |
| `middleName`       | string  | Middle name.                                                                                              |
| `lastName`         | string  | Family name.                                                                                              |
| `suffix`           | string  | Suffix — Jr., III, etc.                                                                                   |
| `isOrganization`   | boolean | `true` for organizational donors, `false` for individuals.                                                |
| `organizationName` | string  | The organization name when `isOrganization` is `true`.                                                    |

### Top-level contact

| Field   | Type   | Description                                                                                              |
| ------- | ------ | -------------------------------------------------------------------------------------------------------- |
| `email` | string | The donor's primary email — convenience field that mirrors the primary entry in `donorEmailAddresses[]`. |
| `phone` | string | The donor's primary phone — convenience field that mirrors the primary entry in `donorPhoneNumbers[]`.   |

The top-level `email` and `phone` are convenience accessors. The authoritative storage for contact methods is in the sub-resource collections below — those collections support multiple entries per donor and explicit primary-marking.

### Sub-resource collections

| Collection              | Description                                                          |
| ----------------------- | -------------------------------------------------------------------- |
| `donorAddresses[]`      | All addresses on the donor. One is typically marked primary.         |
| `primaryAddress`        | Convenience accessor pointing to the address with `isPrimary: true`. |
| `donorEmailAddresses[]` | All email addresses on the donor. One is typically marked primary.   |
| `donorPhoneNumbers[]`   | All phone numbers on the donor. One is typically marked primary.     |

Each entry in these collections is itself a typed sub-resource with its own ID and its own dedicated endpoints — see [Sub-resource endpoints](#sub-resource-endpoints) below.

### Lifecycle and audit

| Field           | Type    | Description                                                                                                                                     |
| --------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `createdDate`   | string  | When the donor record was created.                                                                                                              |
| `modifiedDate`  | string  | When any field on the record was last changed. Read-only.                                                                                       |
| `isArchived`    | boolean | `true` if the donor has been archived. Archived donors are hidden from normal views but the record still exists.                                |
| `isGDPRDeleted` | boolean | `true` if the donor has been deleted under a GDPR right-to-erasure request. The record is retained as a tombstone but personal data is removed. |
| `isTestMode`    | boolean | `true` if the donor was created in test mode.                                                                                                   |
| `notes`         | string  | Free-text notes — see [Updating notes](#updating-notes) for the dedicated update endpoint.                                                      |

### External system linkage

| Field          | Type   | Description                                                                                                           |
| -------------- | ------ | --------------------------------------------------------------------------------------------------------------------- |
| `crmKey`       | string | The donor's primary key in an external CRM — typically CRM+.                                                          |
| `crmSecondKey` | string | A secondary CRM identifier.                                                                                           |
| `crmKeyUrls`   | object | A map of integration types to URL info, letting the customer's UI link directly to the donor in each external system. |

The `crmKey` fields are the linkage Raise uses to keep records aligned with CRM+ when a customer runs both products. Partner integrations don't typically write these directly — they're populated by the platform-level sync. See [How Raise Data Flows to CRM+](/raise/concepts/data-flow-to-crm).

***

## Reading Donors

Raise exposes three patterns for reading Donor records, each suited to a different use:

| Pattern                    | Endpoint                   | Use                                                                                                                                     |
| -------------------------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| List all                   | `GET /api/Donor/list`      | Paginated list of all donors. Supports `Filter`, `Skip`, `Take`, `SortBy`, `Descending`, `IncludeDetails`.                              |
| Query by structured filter | `POST /api/Donor/query`    | Advanced filtering with `groups[]` of `conditions[]` — see [Pagination and Filtering](/raise/pagination#pagination-on-query-endpoints). |
| Search by free text        | `GET /api/Donor/search`    | Free-text search. Matches on donor ID, name, email, and phone.                                                                          |
| Get by ID                  | `GET /api/Donor/{donorId}` | A single donor with all sub-resources included.                                                                                         |

For list-and-export workflows, `Donor/list` with `IncludeDetails=false` is the cheapest. For complex segmentation, `Donor/query` with structured filters. For interactive type-ahead in a UI, `Donor/search`.

### Reading related records for a donor

Several donor sub-resources have dedicated paginated endpoints:

| Endpoint                                         | Returns                                         |
| ------------------------------------------------ | ----------------------------------------------- |
| `GET /api/Donor/{donorId}/gifts`                 | All Gifts by this donor                         |
| `GET /api/Donor/{donorId}/recurringgifts`        | All RecurringGifts by this donor                |
| `GET /api/Donor/{donorId}/projects`              | Projects this donor has supported               |
| `GET /api/Donor/{donorId}/donor-fields`          | Custom field values on the donor                |
| `GET /api/Donor/{donorId}/responses`             | Donor responses (associated with custom fields) |
| `GET /api/Donor/{donorId}/campaign-statistics`   | Per-campaign giving summary                     |
| `GET /api/Donor/{donorId}/segment-statistics`    | Per-segment giving summary                      |
| `GET /api/Donor/{donorId}/motivation-statistics` | Per-motivation-code giving summary              |

The statistics endpoints aggregate the donor's giving over time — useful for donor analytics workflows without needing to query the full Gift history.

***

## Creating and updating Donors

Donor records can be created directly via the API. Most partner integrations don't create Donors directly — they let the `POST /api/Raise/give` donation submission path create donors as part of the donation flow. But for integrations syncing donors from another system without a corresponding gift, the direct create endpoint is available.

<Note>
  The Raise spec does not show a dedicated top-level `POST /api/Donor` endpoint. Donor creation in practice happens either through the donation submission path (`POST /api/Raise/give`) or through dedicated bulk-import tools in the admin UI. For partner integrations that need to create donors independently of a gift, confirm the current approach with the platform team — the spec's donor-creation surface may evolve as part of the v2 overhaul.
</Note>

### Updating a Donor

`PUT /api/Donor/{id}` and `PATCH /api/Donor/{id}` update a donor:

| Method                  | Behavior                                                                                                    |
| ----------------------- | ----------------------------------------------------------------------------------------------------------- |
| `PUT /api/Donor/{id}`   | Documented in the spec summary as "Update an existing donor (full update)." Send the complete donor record. |
| `PATCH /api/Donor/{id}` | Same endpoint, PATCH semantics. Send only the fields to change.                                             |

The dual `PUT`/`PATCH` support on the same endpoint is unusual — most Raise endpoints expose just one. For partner integrations, **prefer `PATCH` for partial updates** to minimize the risk of inadvertently clearing fields with a full-replace `PUT`.

```bash cURL theme={null}
# Update just the donor's email via PATCH
curl -X PATCH https://prod-api.raisedonors.com/api/Donor/12345 \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "bruce.wayne@updated.example"
  }'
```

### Updating notes

Donor notes have a dedicated update endpoint separate from the main donor PUT:

```bash cURL theme={null}
curl -X PUT https://prod-api.raisedonors.com/api/Donor/12345/notes \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "notes": "Donor prefers email contact; no phone calls" }'
```

Using the dedicated endpoint is preferred over including `notes` in a general PUT — it scopes the change cleanly to the notes field and produces a clearer audit trail.

***

## Sub-resource endpoints

Raise treats addresses and contact methods as first-class sub-resources of a donor. Each has its own ID, its own dedicated endpoints, and operates independently of the parent donor PUT.

### Addresses

| Endpoint                                              | Method | Use                                      |
| ----------------------------------------------------- | ------ | ---------------------------------------- |
| `POST /api/Donor/{id}/address`                        | POST   | Create a new address on a donor          |
| `GET /api/Donor/{id}/address/list`                    | GET    | List all addresses on a donor            |
| `GET /api/Donor/{id}/address/{addressId}`             | GET    | Get a specific address                   |
| `PATCH /api/Donor/{id}/address/{addressId}`           | PATCH  | Partial update of an address             |
| `PUT /api/Donor/{id}/address/{addressId}/update`      | PUT    | Full update of an address                |
| `DELETE /api/Donor/{id}/address/{addressId}/delete`   | DELETE | Remove an address from a donor           |
| `PUT /api/Donor/{id}/address/{addressId}/set-primary` | PUT    | Mark this address as the donor's primary |

Setting an address as primary automatically unmarks any previously-primary address — exactly one address can be primary at a time.

### Contact methods

Contact methods cover both emails and phone numbers under a unified resource. Each method has a type indicating which:

| Endpoint                                                           | Method    | Use                                        |
| ------------------------------------------------------------------ | --------- | ------------------------------------------ |
| `POST /api/Donor/{id}/contact-method`                              | POST      | Create a new email or phone contact method |
| `GET /api/Donor/{id}/contact-method/list`                          | GET       | List all contact methods                   |
| `GET /api/Donor/{id}/contact-method/email-addresses`               | GET       | List only email-type contact methods       |
| `GET /api/Donor/{id}/contact-method/phone-numbers`                 | GET       | List only phone-type contact methods       |
| `GET /api/Donor/{id}/contact-method/{contactMethodId}`             | GET       | Get a specific contact method              |
| `PUT` or `PATCH/api/Donor/{id}/contact-method/{contactMethodId}`   | PUT/PATCH | Update a contact method                    |
| `DELETE /api/Donor/{id}/contact-method/{contactMethodId}`          | DELETE    | Remove a contact method                    |
| `PUT /api/Donor/{id}/contact-method/{contactMethodId}/set-primary` | PUT       | Mark as primary                            |

There are also typed convenience endpoints (`POST /api/Donor/{id}/email`, `POST /api/Donor/{id}/phone`, etc.) that operate on the same underlying contact-method records but with explicit email-only or phone-only paths. Use whichever pattern is more natural for your integration.

***

## Special operations

A few Donor operations don't map to plain CRUD and have dedicated endpoints.

### Archive

```bash cURL theme={null}
curl -X POST https://prod-api.raisedonors.com/api/Donor/12345/archive \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

Archiving sets `isArchived: true` on the donor record. The donor is hidden from most lists and reports but the record persists with all history intact. Use archive to clean up inactive donors without losing data.

Archiving is reversible by toggling `isArchived` back to `false` via a Donor update — though the spec doesn't expose a dedicated unarchive endpoint.

### Merge

```bash cURL theme={null}
curl -X PUT https://prod-api.raisedonors.com/api/Donor/merge \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "sourceDonorId": 12345,
    "targetDonorId": 67890
  }'
```

Merging two donor records combines them — typically the source record's data is folded into the target and the source is marked archived (or otherwise made inactive). The Raise API exposes this directly, which is different from CRM+'s model where merges happen in the UI.

<Note>
  Confirm the exact request body shape for `PUT /api/Donor/merge` against the live API before relying on it in production. The endpoint description says "Merge two donors" but the OpenAPI spec doesn't detail the merge behavior — particularly around what happens to the source donor's Gifts, RecurringGifts, and sub-resources after merge.
</Note>

### Transfer a gift to another donor

If a Gift was attributed to the wrong donor, transfer it without deleting and recreating:

```bash cURL theme={null}
curl -X PUT https://prod-api.raisedonors.com/api/Donor/transfer-gift \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "giftId": 9876,
    "newDonorId": 67890
  }'
```

The Gift's `donorId` is updated to the new donor and the Gift remains otherwise intact — same amount, date, designations, payment record.

`PUT /api/Donor/transfer-recurring-gift` performs the equivalent operation for a RecurringGift schedule.

### Activities

Donor activities are log entries — interaction notes, status updates, follow-up records:

| Endpoint                          | Method | Use                                                                                           |
| --------------------------------- | ------ | --------------------------------------------------------------------------------------------- |
| `POST /api/Donor/{id}/activity`   | POST   | Create a new activity entry                                                                   |
| `POST /api/Donor/{id}/activities` | POST   | Get a paginated list of activities (uses POST despite being a read because of the query body) |

Use activities to track integration-managed interactions — when your integration sent the donor a thank-you email, when an automated follow-up sequence was triggered, etc. These show up in the donor's history alongside manual entries from the customer's staff.

### Generate a personalized donation page

```bash cURL theme={null}
curl -X POST https://prod-api.raisedonors.com/api/Donor/12345/generate-page \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "campaignId": 5678
  }'
```

Generates a hosted donation page personalized to the donor — typically a URL that can be sent in an email or text message, pre-filling the donor's identity so they need only enter the donation amount and payment method. Useful for renewal campaigns and major-donor cultivation.

***

## Donor data privacy

Two donor-data privacy concerns are worth flagging:

### GDPR right-to-erasure

The `isGDPRDeleted` flag on a Donor record indicates the donor has been deleted under a GDPR right-to-erasure request. The record is retained as a tombstone (the `id` continues to exist so historical Gift references don't break) but personal data is removed.

Partner integrations that store Donor data locally should respect this flag — when a donor sync detects `isGDPRDeleted: true`, the local record should be reduced to the tombstone state, with personal data deleted on the partner side.

### Test mode separation

Donors created with `isTestMode: true` are flagged as test data. Production reports should filter to `isTestMode: false`. See [Base URLs and Environments — Working against production with care](/raise/base-urls#working-against-production-with-care).

***

## Where to go next

<CardGroup cols={2}>
  <Card title="Gifts" icon="hand-holding-dollar" href="/raise/concepts/gifts">
    The Gift resource and the donation submission path that creates Donors as a side effect.
  </Card>

  <Card title="Create or Find a Donor" icon="user-plus" href="/raise/workflows/create-or-find-a-donor">
    The workflow for ensuring a donor exists before submitting a donation.
  </Card>

  <Card title="Query Donors by Filters" icon="filter" href="/raise/workflows/query-donors-by-filters">
    Use the structured query pattern to find specific donor segments.
  </Card>

  <Card title="How Raise Data Flows to CRM+" icon="arrow-right-arrow-left" href="/raise/concepts/data-flow-to-crm">
    The platform-level sync that keeps Raise Donors aligned with CRM+ Contacts.
  </Card>
</CardGroup>
