Update a custom mailing template
Rejects system templates. Updates supplied scalar fields; omitted/null nullable scalar values retain the prior value. Supplied program_ids replaces all bindings. Supplied documents replaces the set of kinds and removes omitted kinds; at least one is required when present. Document/visual-designer and current Impact Story rules also apply. Requires permission: one of mailings_manage, manage_email.
curl --request PUT \
--url https://api.gratona.com/v1/admin/mailing_templates/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Education impact letter",
"scope_type": "donor",
"preset_key": "<string>",
"render_strategy": "unlayer_pdf",
"description": "<string>",
"is_active": true,
"program_ids": [
42
],
"documents": [
{
"document_kind": "letter",
"page_preset": "us_letter_portrait",
"editor_mode": "unlayer",
"html": "<p>Dear [donor_name], thank you.</p>",
"design": "<unknown>",
"settings_json": {}
}
]
}
'import requests
url = "https://api.gratona.com/v1/admin/mailing_templates/{id}"
payload = {
"name": "Education impact letter",
"scope_type": "donor",
"preset_key": "<string>",
"render_strategy": "unlayer_pdf",
"description": "<string>",
"is_active": True,
"program_ids": [42],
"documents": [
{
"document_kind": "letter",
"page_preset": "us_letter_portrait",
"editor_mode": "unlayer",
"html": "<p>Dear [donor_name], thank you.</p>",
"design": "<unknown>",
"settings_json": {}
}
]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Education impact letter',
scope_type: 'donor',
preset_key: '<string>',
render_strategy: 'unlayer_pdf',
description: '<string>',
is_active: true,
program_ids: [42],
documents: [
{
document_kind: 'letter',
page_preset: 'us_letter_portrait',
editor_mode: 'unlayer',
html: '<p>Dear [donor_name], thank you.</p>',
design: '<unknown>',
settings_json: {}
}
]
})
};
fetch('https://api.gratona.com/v1/admin/mailing_templates/{id}', 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/admin/mailing_templates/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Education impact letter',
'scope_type' => 'donor',
'preset_key' => '<string>',
'render_strategy' => 'unlayer_pdf',
'description' => '<string>',
'is_active' => true,
'program_ids' => [
42
],
'documents' => [
[
'document_kind' => 'letter',
'page_preset' => 'us_letter_portrait',
'editor_mode' => 'unlayer',
'html' => '<p>Dear [donor_name], thank you.</p>',
'design' => '<unknown>',
'settings_json' => [
]
]
]
]),
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/admin/mailing_templates/{id}"
payload := strings.NewReader("{\n \"name\": \"Education impact letter\",\n \"scope_type\": \"donor\",\n \"preset_key\": \"<string>\",\n \"render_strategy\": \"unlayer_pdf\",\n \"description\": \"<string>\",\n \"is_active\": true,\n \"program_ids\": [\n 42\n ],\n \"documents\": [\n {\n \"document_kind\": \"letter\",\n \"page_preset\": \"us_letter_portrait\",\n \"editor_mode\": \"unlayer\",\n \"html\": \"<p>Dear [donor_name], thank you.</p>\",\n \"design\": \"<unknown>\",\n \"settings_json\": {}\n }\n ]\n}")
req, _ := http.NewRequest("PUT", 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.put("https://api.gratona.com/v1/admin/mailing_templates/{id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Education impact letter\",\n \"scope_type\": \"donor\",\n \"preset_key\": \"<string>\",\n \"render_strategy\": \"unlayer_pdf\",\n \"description\": \"<string>\",\n \"is_active\": true,\n \"program_ids\": [\n 42\n ],\n \"documents\": [\n {\n \"document_kind\": \"letter\",\n \"page_preset\": \"us_letter_portrait\",\n \"editor_mode\": \"unlayer\",\n \"html\": \"<p>Dear [donor_name], thank you.</p>\",\n \"design\": \"<unknown>\",\n \"settings_json\": {}\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.gratona.com/v1/admin/mailing_templates/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"Education impact letter\",\n \"scope_type\": \"donor\",\n \"preset_key\": \"<string>\",\n \"render_strategy\": \"unlayer_pdf\",\n \"description\": \"<string>\",\n \"is_active\": true,\n \"program_ids\": [\n 42\n ],\n \"documents\": [\n {\n \"document_kind\": \"letter\",\n \"page_preset\": \"us_letter_portrait\",\n \"editor_mode\": \"unlayer\",\n \"html\": \"<p>Dear [donor_name], thank you.</p>\",\n \"design\": \"<unknown>\",\n \"settings_json\": {}\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": 42,
"name": "Education impact letter",
"scope_type": "donor",
"template_kind": "custom",
"preset_key": "Example",
"render_strategy": "unlayer_pdf",
"description": "Example",
"is_active": true,
"program_ids": [
42
],
"program_bindings": [
{
"id": 42,
"program_id": 42,
"name": "Example"
}
],
"applicability_label": "Client-wide",
"documents": [
{
"id": 42,
"document_kind": "letter",
"page_preset": "us_letter_portrait",
"editor_mode": "unlayer",
"html": "<p>Dear [donor_name], thank you for your support.</p>",
"design": "{`body`:{}}",
"settings_json": {}
}
],
"has_labels": true,
"created_at": "2026-10-20T12:00:00Z",
"updated_at": "2026-10-20T12:00:00Z"
}
}{
"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.
191"Education impact letter"
Custom templates support donor or sponsorship; household is system-managed.
donor, sponsorship "donor"
Custom preset; tax_summary is reserved.
64Defaults unlayer_pdf; tax_summary is reserved.
32"unlayer_pdf"
true
Organization-owned record identifier.
1Show child attributes
Show child attributes
Response
Operation result.
Show child attributes
Show child attributes
curl --request PUT \
--url https://api.gratona.com/v1/admin/mailing_templates/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Education impact letter",
"scope_type": "donor",
"preset_key": "<string>",
"render_strategy": "unlayer_pdf",
"description": "<string>",
"is_active": true,
"program_ids": [
42
],
"documents": [
{
"document_kind": "letter",
"page_preset": "us_letter_portrait",
"editor_mode": "unlayer",
"html": "<p>Dear [donor_name], thank you.</p>",
"design": "<unknown>",
"settings_json": {}
}
]
}
'import requests
url = "https://api.gratona.com/v1/admin/mailing_templates/{id}"
payload = {
"name": "Education impact letter",
"scope_type": "donor",
"preset_key": "<string>",
"render_strategy": "unlayer_pdf",
"description": "<string>",
"is_active": True,
"program_ids": [42],
"documents": [
{
"document_kind": "letter",
"page_preset": "us_letter_portrait",
"editor_mode": "unlayer",
"html": "<p>Dear [donor_name], thank you.</p>",
"design": "<unknown>",
"settings_json": {}
}
]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Education impact letter',
scope_type: 'donor',
preset_key: '<string>',
render_strategy: 'unlayer_pdf',
description: '<string>',
is_active: true,
program_ids: [42],
documents: [
{
document_kind: 'letter',
page_preset: 'us_letter_portrait',
editor_mode: 'unlayer',
html: '<p>Dear [donor_name], thank you.</p>',
design: '<unknown>',
settings_json: {}
}
]
})
};
fetch('https://api.gratona.com/v1/admin/mailing_templates/{id}', 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/admin/mailing_templates/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Education impact letter',
'scope_type' => 'donor',
'preset_key' => '<string>',
'render_strategy' => 'unlayer_pdf',
'description' => '<string>',
'is_active' => true,
'program_ids' => [
42
],
'documents' => [
[
'document_kind' => 'letter',
'page_preset' => 'us_letter_portrait',
'editor_mode' => 'unlayer',
'html' => '<p>Dear [donor_name], thank you.</p>',
'design' => '<unknown>',
'settings_json' => [
]
]
]
]),
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/admin/mailing_templates/{id}"
payload := strings.NewReader("{\n \"name\": \"Education impact letter\",\n \"scope_type\": \"donor\",\n \"preset_key\": \"<string>\",\n \"render_strategy\": \"unlayer_pdf\",\n \"description\": \"<string>\",\n \"is_active\": true,\n \"program_ids\": [\n 42\n ],\n \"documents\": [\n {\n \"document_kind\": \"letter\",\n \"page_preset\": \"us_letter_portrait\",\n \"editor_mode\": \"unlayer\",\n \"html\": \"<p>Dear [donor_name], thank you.</p>\",\n \"design\": \"<unknown>\",\n \"settings_json\": {}\n }\n ]\n}")
req, _ := http.NewRequest("PUT", 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.put("https://api.gratona.com/v1/admin/mailing_templates/{id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Education impact letter\",\n \"scope_type\": \"donor\",\n \"preset_key\": \"<string>\",\n \"render_strategy\": \"unlayer_pdf\",\n \"description\": \"<string>\",\n \"is_active\": true,\n \"program_ids\": [\n 42\n ],\n \"documents\": [\n {\n \"document_kind\": \"letter\",\n \"page_preset\": \"us_letter_portrait\",\n \"editor_mode\": \"unlayer\",\n \"html\": \"<p>Dear [donor_name], thank you.</p>\",\n \"design\": \"<unknown>\",\n \"settings_json\": {}\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.gratona.com/v1/admin/mailing_templates/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"Education impact letter\",\n \"scope_type\": \"donor\",\n \"preset_key\": \"<string>\",\n \"render_strategy\": \"unlayer_pdf\",\n \"description\": \"<string>\",\n \"is_active\": true,\n \"program_ids\": [\n 42\n ],\n \"documents\": [\n {\n \"document_kind\": \"letter\",\n \"page_preset\": \"us_letter_portrait\",\n \"editor_mode\": \"unlayer\",\n \"html\": \"<p>Dear [donor_name], thank you.</p>\",\n \"design\": \"<unknown>\",\n \"settings_json\": {}\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": 42,
"name": "Education impact letter",
"scope_type": "donor",
"template_kind": "custom",
"preset_key": "Example",
"render_strategy": "unlayer_pdf",
"description": "Example",
"is_active": true,
"program_ids": [
42
],
"program_bindings": [
{
"id": 42,
"program_id": 42,
"name": "Example"
}
],
"applicability_label": "Client-wide",
"documents": [
{
"id": 42,
"document_kind": "letter",
"page_preset": "us_letter_portrait",
"editor_mode": "unlayer",
"html": "<p>Dear [donor_name], thank you for your support.</p>",
"design": "{`body`:{}}",
"settings_json": {}
}
],
"has_labels": true,
"created_at": "2026-10-20T12:00:00Z",
"updated_at": "2026-10-20T12:00:00Z"
}
}{
"message": "Unauthorized",
"status": "error"
}{
"message": "Not Found",
"status": "error"
}{
"errors": {},
"status": "error",
"message": "The given data was invalid."
}