Update donor communication preferences
Updates only supplied fields. Email categories, master do_not_email and postal choices apply across donor records sharing the normalized primary address; SMS consent changes only this donor. Enabling SMS requires sms_consent_confirmed=true. account_security cannot be disabled individually. restore_email_delivery clears address-level/email-event blocks and donor master flags, preserving form-level suppression. Requires access to every matching donor form. Requires permission: one of donors_manage.
curl --request PATCH \
--url https://api.gratona.com/v1/donor/{id}/communication-preferences \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"email_categories": {
"marketing": true,
"account_security": true,
"receipts_tax": true,
"payment_issues": true,
"sponsorship_updates": true,
"events_fundraising": true,
"messages": true,
"files_photos": true,
"other_updates": true
},
"postal_mail_enabled": true,
"sms_enabled": true,
"sms_consent_confirmed": true,
"do_not_email": true,
"restore_email_delivery": true
}
'import requests
url = "https://api.gratona.com/v1/donor/{id}/communication-preferences"
payload = {
"email_categories": {
"marketing": True,
"account_security": True,
"receipts_tax": True,
"payment_issues": True,
"sponsorship_updates": True,
"events_fundraising": True,
"messages": True,
"files_photos": True,
"other_updates": True
},
"postal_mail_enabled": True,
"sms_enabled": True,
"sms_consent_confirmed": True,
"do_not_email": True,
"restore_email_delivery": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
email_categories: {
marketing: true,
account_security: true,
receipts_tax: true,
payment_issues: true,
sponsorship_updates: true,
events_fundraising: true,
messages: true,
files_photos: true,
other_updates: true
},
postal_mail_enabled: true,
sms_enabled: true,
sms_consent_confirmed: true,
do_not_email: true,
restore_email_delivery: true
})
};
fetch('https://api.gratona.com/v1/donor/{id}/communication-preferences', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.gratona.com/v1/donor/{id}/communication-preferences",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'email_categories' => [
'marketing' => true,
'account_security' => true,
'receipts_tax' => true,
'payment_issues' => true,
'sponsorship_updates' => true,
'events_fundraising' => true,
'messages' => true,
'files_photos' => true,
'other_updates' => true
],
'postal_mail_enabled' => true,
'sms_enabled' => true,
'sms_consent_confirmed' => true,
'do_not_email' => true,
'restore_email_delivery' => true
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.gratona.com/v1/donor/{id}/communication-preferences"
payload := strings.NewReader("{\n \"email_categories\": {\n \"marketing\": true,\n \"account_security\": true,\n \"receipts_tax\": true,\n \"payment_issues\": true,\n \"sponsorship_updates\": true,\n \"events_fundraising\": true,\n \"messages\": true,\n \"files_photos\": true,\n \"other_updates\": true\n },\n \"postal_mail_enabled\": true,\n \"sms_enabled\": true,\n \"sms_consent_confirmed\": true,\n \"do_not_email\": true,\n \"restore_email_delivery\": true\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.patch("https://api.gratona.com/v1/donor/{id}/communication-preferences")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"email_categories\": {\n \"marketing\": true,\n \"account_security\": true,\n \"receipts_tax\": true,\n \"payment_issues\": true,\n \"sponsorship_updates\": true,\n \"events_fundraising\": true,\n \"messages\": true,\n \"files_photos\": true,\n \"other_updates\": true\n },\n \"postal_mail_enabled\": true,\n \"sms_enabled\": true,\n \"sms_consent_confirmed\": true,\n \"do_not_email\": true,\n \"restore_email_delivery\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.gratona.com/v1/donor/{id}/communication-preferences")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"email_categories\": {\n \"marketing\": true,\n \"account_security\": true,\n \"receipts_tax\": true,\n \"payment_issues\": true,\n \"sponsorship_updates\": true,\n \"events_fundraising\": true,\n \"messages\": true,\n \"files_photos\": true,\n \"other_updates\": true\n },\n \"postal_mail_enabled\": true,\n \"sms_enabled\": true,\n \"sms_consent_confirmed\": true,\n \"do_not_email\": true,\n \"restore_email_delivery\": true\n}"
response = http.request(request)
puts response.read_body{
"email_categories": [
{
"key": "marketing",
"label": "Example",
"description": "Example",
"requires_disable_warning": true,
"enabled": true,
"events": {},
"partially_enabled": true,
"blocked_code": "category_opt_out",
"blocked_reason": "All donor email is turned off."
}
],
"saved_email_categories": [
{
"key": "marketing",
"label": "Example",
"description": "Example",
"requires_disable_warning": true,
"enabled": true,
"events": {},
"partially_enabled": true,
"blocked_code": "category_opt_out",
"blocked_reason": "All donor email is turned off."
}
],
"sms": {
"enabled": true,
"events": {},
"partially_enabled": true,
"blocked_code": "category_opt_out",
"blocked_reason": "All donor email is turned off."
},
"saved_sms": {
"enabled": true,
"events": {},
"partially_enabled": true,
"blocked_code": "category_opt_out",
"blocked_reason": "All donor email is turned off."
},
"postal_mail": {
"enabled": true,
"events": {},
"partially_enabled": true,
"blocked_code": "category_opt_out",
"blocked_reason": "All donor email is turned off."
},
"saved_postal_mail": {
"enabled": true,
"events": {},
"partially_enabled": true,
"blocked_code": "category_opt_out",
"blocked_reason": "All donor email is turned off."
},
"do_not_email": true
}{
"message": "Unauthorized",
"status": "error"
}{
"message": "Not Found",
"status": "error"
}{
"errors": {},
"status": "error",
"message": "The given data was invalid."
}Authorizations
Passport bearer token authentication for legacy admin sessions.
Path Parameters
Id in the current organization.
Body
Validated request fields for this operation.
Partial category-key to boolean map; account_security must remain true.
Show child attributes
Show child attributes
Postal mail enabled. Validation: sometimes, boolean.
true
Sms enabled. Validation: sometimes, boolean.
true
Sms consent confirmed. Validation: sometimes, boolean.
true
Do not email. Validation: sometimes, boolean.
true
Restore email delivery. Validation: sometimes, boolean.
true
Response
Operation result.
Effective values and saved choices are separate while a donor master block pauses delivery.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Effective delivery state. events and partially_enabled appear when applicable; null blocked_reason can accompany an opt-out.
Show child attributes
Show child attributes
Effective delivery state. events and partially_enabled appear when applicable; null blocked_reason can accompany an opt-out.
Show child attributes
Show child attributes
Effective delivery state. events and partially_enabled appear when applicable; null blocked_reason can accompany an opt-out.
Show child attributes
Show child attributes
Effective delivery state. events and partially_enabled appear when applicable; null blocked_reason can accompany an opt-out.
Show child attributes
Show child attributes
Enabled state.
true
curl --request PATCH \
--url https://api.gratona.com/v1/donor/{id}/communication-preferences \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"email_categories": {
"marketing": true,
"account_security": true,
"receipts_tax": true,
"payment_issues": true,
"sponsorship_updates": true,
"events_fundraising": true,
"messages": true,
"files_photos": true,
"other_updates": true
},
"postal_mail_enabled": true,
"sms_enabled": true,
"sms_consent_confirmed": true,
"do_not_email": true,
"restore_email_delivery": true
}
'import requests
url = "https://api.gratona.com/v1/donor/{id}/communication-preferences"
payload = {
"email_categories": {
"marketing": True,
"account_security": True,
"receipts_tax": True,
"payment_issues": True,
"sponsorship_updates": True,
"events_fundraising": True,
"messages": True,
"files_photos": True,
"other_updates": True
},
"postal_mail_enabled": True,
"sms_enabled": True,
"sms_consent_confirmed": True,
"do_not_email": True,
"restore_email_delivery": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
email_categories: {
marketing: true,
account_security: true,
receipts_tax: true,
payment_issues: true,
sponsorship_updates: true,
events_fundraising: true,
messages: true,
files_photos: true,
other_updates: true
},
postal_mail_enabled: true,
sms_enabled: true,
sms_consent_confirmed: true,
do_not_email: true,
restore_email_delivery: true
})
};
fetch('https://api.gratona.com/v1/donor/{id}/communication-preferences', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.gratona.com/v1/donor/{id}/communication-preferences",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'email_categories' => [
'marketing' => true,
'account_security' => true,
'receipts_tax' => true,
'payment_issues' => true,
'sponsorship_updates' => true,
'events_fundraising' => true,
'messages' => true,
'files_photos' => true,
'other_updates' => true
],
'postal_mail_enabled' => true,
'sms_enabled' => true,
'sms_consent_confirmed' => true,
'do_not_email' => true,
'restore_email_delivery' => true
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.gratona.com/v1/donor/{id}/communication-preferences"
payload := strings.NewReader("{\n \"email_categories\": {\n \"marketing\": true,\n \"account_security\": true,\n \"receipts_tax\": true,\n \"payment_issues\": true,\n \"sponsorship_updates\": true,\n \"events_fundraising\": true,\n \"messages\": true,\n \"files_photos\": true,\n \"other_updates\": true\n },\n \"postal_mail_enabled\": true,\n \"sms_enabled\": true,\n \"sms_consent_confirmed\": true,\n \"do_not_email\": true,\n \"restore_email_delivery\": true\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.patch("https://api.gratona.com/v1/donor/{id}/communication-preferences")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"email_categories\": {\n \"marketing\": true,\n \"account_security\": true,\n \"receipts_tax\": true,\n \"payment_issues\": true,\n \"sponsorship_updates\": true,\n \"events_fundraising\": true,\n \"messages\": true,\n \"files_photos\": true,\n \"other_updates\": true\n },\n \"postal_mail_enabled\": true,\n \"sms_enabled\": true,\n \"sms_consent_confirmed\": true,\n \"do_not_email\": true,\n \"restore_email_delivery\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.gratona.com/v1/donor/{id}/communication-preferences")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"email_categories\": {\n \"marketing\": true,\n \"account_security\": true,\n \"receipts_tax\": true,\n \"payment_issues\": true,\n \"sponsorship_updates\": true,\n \"events_fundraising\": true,\n \"messages\": true,\n \"files_photos\": true,\n \"other_updates\": true\n },\n \"postal_mail_enabled\": true,\n \"sms_enabled\": true,\n \"sms_consent_confirmed\": true,\n \"do_not_email\": true,\n \"restore_email_delivery\": true\n}"
response = http.request(request)
puts response.read_body{
"email_categories": [
{
"key": "marketing",
"label": "Example",
"description": "Example",
"requires_disable_warning": true,
"enabled": true,
"events": {},
"partially_enabled": true,
"blocked_code": "category_opt_out",
"blocked_reason": "All donor email is turned off."
}
],
"saved_email_categories": [
{
"key": "marketing",
"label": "Example",
"description": "Example",
"requires_disable_warning": true,
"enabled": true,
"events": {},
"partially_enabled": true,
"blocked_code": "category_opt_out",
"blocked_reason": "All donor email is turned off."
}
],
"sms": {
"enabled": true,
"events": {},
"partially_enabled": true,
"blocked_code": "category_opt_out",
"blocked_reason": "All donor email is turned off."
},
"saved_sms": {
"enabled": true,
"events": {},
"partially_enabled": true,
"blocked_code": "category_opt_out",
"blocked_reason": "All donor email is turned off."
},
"postal_mail": {
"enabled": true,
"events": {},
"partially_enabled": true,
"blocked_code": "category_opt_out",
"blocked_reason": "All donor email is turned off."
},
"saved_postal_mail": {
"enabled": true,
"events": {},
"partially_enabled": true,
"blocked_code": "category_opt_out",
"blocked_reason": "All donor email is turned off."
},
"do_not_email": true
}{
"message": "Unauthorized",
"status": "error"
}{
"message": "Not Found",
"status": "error"
}{
"errors": {},
"status": "error",
"message": "The given data was invalid."
}