Skip to content

Donor (akoya_donor)

A Donor is a person or organization that has given, or is being cultivated to give, to the foundation. It's the lifecycle record that tracks giving history, engagement temperature, and cultivation stage. Individual donors link to one or two contact rows; organizational donors map via the standard account entity.

See The constituent model for how contact, account, and akoya_donor fit together.

At a glance

Display name Donors & Prospects
Logical name akoya_donor
Primary ID attribute akoya_donorid
Primary name attribute akoya_formaldefault
Entity set name (Web API) akoya_donors
Ownership OrganizationOwned
Change tracking Enabled
Audit Enabled

Web API

GET  {org}/api/data/v9.2/akoya_donors
GET  {org}/api/data/v9.2/akoya_donors({donorid})
POST {org}/api/data/v9.2/akoya_donors
PATCH {org}/api/data/v9.2/akoya_donors({donorid})

Attributes

Data-conversion fields (akoya_dc_*) are excluded.

Identity and greeting

Display name Logical name Type Required Max length Description
Formal Default akoya_formaldefault String ApplicationRequired 160 Formal greeting / salutation name. Primary name attribute.
Donor # akoya_donor String None 10 Legacy donor number from migration or external system.
Informal Greeting akoya_informalgreeting String Recommended 100 Casual greeting name.
Sort By akoya_sortby String None 100 Custom sort field.
Donor Type akoya_donortype Boolean ApplicationRequired Individual/Household (false) vs. Organization (true).
Address to Use akoya_addresstouse Boolean Recommended Whether mailings use the donor address (false) or the primary contact's address (true).

Contact and address

Display name Logical name Type Max length
Street 1 akoya_donor_street1 String 250
Street 2 akoya_donor_street2 String 250
City akoya_donor_city String 80
State/Province akoya_donor_stateorprovince String 50
ZIP/Postal Code akoya_donor_postalcode String 20
Country akoya_country String 100
County akoya_county String 250

Engagement / cultivation

Display name Logical name Type Description
Temperature akoya_temperature Choice Engagement heat. See values.
Stage akoya_stage Choice Cultivation pipeline stage. See values.
Inclination akoya_inclination Choice Propensity-to-give rating. See values.
Anonymous akoya_anonymous Boolean Donor prefers anonymity.
Aim akoya_aim Money Planned next-ask amount.
Source akoya_sourcedescription String Acquisition channel / source.

Giving history (rolling 5-year)

All of these are currency fields with paired system-maintained _Base columns.

Display name Logical name
Total Giving This Year akoya_totalgivingthisyear
Total Giving Last Year akoya_totalgivinglastyear
Total Giving 2 Years Ago akoya_totalgiving2yearsago
Total Giving 3 Years Ago akoya_totalgiving3yearsago
Total Giving 4 Years Ago akoya_totalgiving4yearsago
Total Giving 5 Years Ago akoya_totalgiving5yearsago
Total Commitment akoya_totalcommitment
Largest Gift akoya_largestgift
Count of Gifts akoya_countofgifts (integer)
First Gift Date akoya_firstgiftdate (DateTime)
Most Recent Gift Date akoya_mostrecentgiftdate (DateTime)

Lookups — quick reference

Logical name Navigation property Target Purpose
akoya_primarycontact akoya_PrimaryContact contact Primary person associated with the donor.
akoya_secondarycontact akoya_SecondaryContact contact Second person (spouse, co-advisor).
akoya_donorconstituent akoya_DonorConstituent contact Legacy "constituent" linkage — prefer akoya_primarycontact for new integrations.
akoya_largestgiftid akoya_LargestGiftId akoya_gift Rollup: highest-value gift.
akoya_mostrecentgiftid akoya_MostRecentGiftId akoya_gift Rollup: latest gift.
akoya_staff akoya_Staff systemuser Assigned foundation staff contact.

Choice values

akoya_temperature values

Label Value
Hot 730850000
Warm 730850001
Cold 730850002
Unknown 730850003

akoya_stage values

Label Value
-Unqualified- 100000000
Identification 100000001
Qualification 100000002
Cultivation 100000003
Solicitation 100000004
Stewardship 100000005

akoya_inclination values

Label Value
A-Highly inclined to give 100000000
B-Probably will give 100000001
C-Possible giver 100000002
D-Unlikely to give 100000003
X-Will not give 100000004

Relationships

Many-to-One (outbound lookups)

Schema name Referenced entity Attribute
akoya_contact_akoya_donor_primarycontact contact akoya_primarycontact
akoya_contact_akoya_donor_secondarycontact contact akoya_secondarycontact
akoya_contact_akoya_donor_donorconstituent contact akoya_donorconstituent
akoya_gift_akoya_donor_largestgift akoya_gift akoya_largestgiftid
akoya_gift_akoya_donor_mostrecentgift akoya_gift akoya_mostrecentgiftid

One-to-Many (child records)

Related entity Role
akoya_gift Gifts made by this donor (via akoya_gift.akoya_donor).
akoya_fund Funds where this donor is the primary donor.
akoya_donoropportunities Pipeline opportunities.

Supported messages

Message Supported
Create
Retrieve
RetrieveMultiple
Update
Delete
Upsert — (no alternate keys; use GET then PATCH)

Privileges

Privilege Purpose
prvReadakoya_donor Read donor records
prvCreateakoya_donor Create donor records
prvWriteakoya_donor Update donor records
prvAppendToakoya_donor Associate child records to a donor

Examples

Conventions

Examples assume ORG (env URL), access_token (valid bearer), headers (standard Dataverse headers dict), and service (a ServiceClient instance). See Authentication.

Read active donors with contacts

GET {org}/api/data/v9.2/akoya_donors?
  $select=akoya_formaldefault,akoya_donor,akoya_temperature,akoya_stage,akoya_totalgivingthisyear&
  $filter=statecode eq 0 and akoya_temperature eq 730850000&
  $expand=akoya_PrimaryContact($select=fullname,emailaddress1),akoya_SecondaryContact($select=fullname,emailaddress1)&
  $orderby=akoya_formaldefault asc
Accept: application/json
OData-Version: 4.0
OData-MaxVersion: 4.0
curl "https://{org}.crm.dynamics.com/api/data/v9.2/akoya_donors?\$select=akoya_formaldefault,akoya_donor,akoya_temperature,akoya_stage,akoya_totalgivingthisyear&\$filter=statecode%20eq%200%20and%20akoya_temperature%20eq%20730850000&\$expand=akoya_PrimaryContact(\$select=fullname,emailaddress1),akoya_SecondaryContact(\$select=fullname,emailaddress1)&\$orderby=akoya_formaldefault%20asc" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Accept: application/json" \
  -H "OData-Version: 4.0" \
  -H "OData-MaxVersion: 4.0"
r = requests.get(
    f"{ORG}/api/data/v9.2/akoya_donors",
    params={
        "$select": "akoya_formaldefault,akoya_donor,akoya_temperature,akoya_stage,akoya_totalgivingthisyear",
        "$filter": "statecode eq 0 and akoya_temperature eq 730850000",
        "$expand": "akoya_PrimaryContact($select=fullname,emailaddress1),akoya_SecondaryContact($select=fullname,emailaddress1)",
        "$orderby": "akoya_formaldefault asc",
    },
    headers=headers,
)
donors = r.json()["value"]
var query = new QueryExpression("akoya_donor") {
    ColumnSet = new ColumnSet("akoya_formaldefault", "akoya_donor", "akoya_temperature", "akoya_stage", "akoya_totalgivingthisyear"),
    Criteria = {
        Conditions = {
            new ConditionExpression("statecode", ConditionOperator.Equal, 0),
            new ConditionExpression("akoya_temperature", ConditionOperator.Equal, 730850000)
        }
    },
    Orders = { new OrderExpression("akoya_formaldefault", OrderType.Ascending) }
};
var donors = service.RetrieveMultiple(query);

Find donor by legacy number

No alternate keys exist — look up first, then PATCH by GUID.

GET {org}/api/data/v9.2/akoya_donors?
  $select=akoya_donorid&
  $filter=akoya_donor eq 'D-00123'&
  $top=1
Accept: application/json
OData-Version: 4.0
OData-MaxVersion: 4.0

Then:

PATCH {org}/api/data/v9.2/akoya_donors({donorid})
Content-Type: application/json
If-Match: *

{
  "akoya_temperature": 730850000,
  "akoya_stage": 100000003
}
DONOR_ID=$(curl -s "https://{org}.crm.dynamics.com/api/data/v9.2/akoya_donors?\$select=akoya_donorid&\$filter=akoya_donor%20eq%20'D-00123'&\$top=1" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Accept: application/json" \
  | jq -r '.value[0].akoya_donorid')

curl -X PATCH "https://{org}.crm.dynamics.com/api/data/v9.2/akoya_donors($DONOR_ID)" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "If-Match: *" \
  -d '{"akoya_temperature": 730850000, "akoya_stage": 100000003}'
r = requests.get(
    f"{ORG}/api/data/v9.2/akoya_donors",
    params={"$select": "akoya_donorid", "$filter": "akoya_donor eq 'D-00123'", "$top": 1},
    headers=headers,
)
hits = r.json()["value"]
if not hits:
    raise LookupError("Donor not found")
donor_id = hits[0]["akoya_donorid"]

requests.patch(
    f"{ORG}/api/data/v9.2/akoya_donors({donor_id})",
    json={"akoya_temperature": 730850000, "akoya_stage": 100000003},
    headers={**headers, "Content-Type": "application/json", "If-Match": "*"},
)
var lookup = new QueryExpression("akoya_donor") {
    ColumnSet = new ColumnSet("akoya_donorid"),
    Criteria = {
        Conditions = {
            new ConditionExpression("akoya_donor", ConditionOperator.Equal, "D-00123")
        }
    },
    TopCount = 1
};
var result = service.RetrieveMultiple(lookup);
if (result.Entities.Count == 0) throw new InvalidOperationException("Donor not found");

var donor = new Entity("akoya_donor", result.Entities[0].Id);
donor["akoya_temperature"] = new OptionSetValue(730850000);
donor["akoya_stage"] = new OptionSetValue(100000003);
service.Update(donor);

Change history

Schema extracted from the Akoyanet solution XML on 2026-04-24. Some lookup targets are inferred from attribute naming and will be finalized by the Phase 2 metadata generator.