Record a stewardship Work completion
Requires readable Work/donor scope. Logs a manual interaction and acknowledges eligible selected gifts. For handwritten_card, supply an existing order or draft fields; unaccepted/practice cards return pending_submission and leave work/gifts incomplete until live acceptance. Replays preserve interaction and gift selection. Other channels record work already performed; this operation does not send email or SMS. The Handwrytten feature is required only for channel=handwritten_card or a supplied handwrytten_order_id. Requires permission: donors_view; plus one of donors_manage, donations, interactions_manage, mailings_generate, mailings_manage, manage_email.
curl --request POST \
--url https://api.gratona.com/v1/admin/handwrytten/work-items/{workItemId}/complete \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"channel": "call",
"donor_id": 1,
"handwrytten_order_id": 1,
"donation_ids": [
1
],
"subject": "Subject",
"note": "Discuss the next update with the program team.",
"body_plain": "Body Plain",
"body_visibility": "private",
"outcome": "Outcome",
"direction": "inbound",
"duration_minutes": 1,
"follow_up_at": "2026-10-20T12:00:00Z",
"counts_as_touch": true,
"shared_group_id": 1,
"occurred_at": "2026-10-20T12:00:00Z",
"idempotency_key": "Idempotency Key",
"handwrytten": {
"generated_mailing_id": 1,
"rule_id": 1,
"account_mode": "hys_managed",
"card_vendor_id": "Handwrytten.Card Vendor Id",
"card_name": "Handwrytten.Card Name",
"font_label": "Handwrytten.Font Label",
"insert_vendor_id": "Handwrytten.Insert Vendor Id",
"message_template": "Handwrytten.Message Template",
"message": "Handwrytten.Message",
"merge_data": [
"<unknown>"
],
"recipient_address": {
"first_name": "Example",
"last_name": "Example",
"name": "Example",
"address1": "Example",
"address2": "Example",
"street": "Example",
"address_line2": "Example",
"city": "Example",
"state": "Example",
"province": "Example",
"zip": "Example",
"postal_code": "Example",
"country": "Example",
"country_code": "Example",
"country_id": 1
},
"sender_address": {
"first_name": "Example",
"last_name": "Example",
"name": "Example",
"address1": "Example",
"address2": "Example",
"street": "Example",
"address_line2": "Example",
"city": "Example",
"state": "Example",
"province": "Example",
"zip": "Example",
"postal_code": "Example",
"country": "Example",
"country_code": "Example",
"country_id": 1
},
"program_id": 1,
"campaign_key": "Handwrytten.Campaign Key",
"requested_send_date": "2026-10-20T12:00:00Z"
}
}
'import requests
url = "https://api.gratona.com/v1/admin/handwrytten/work-items/{workItemId}/complete"
payload = {
"channel": "call",
"donor_id": 1,
"handwrytten_order_id": 1,
"donation_ids": [1],
"subject": "Subject",
"note": "Discuss the next update with the program team.",
"body_plain": "Body Plain",
"body_visibility": "private",
"outcome": "Outcome",
"direction": "inbound",
"duration_minutes": 1,
"follow_up_at": "2026-10-20T12:00:00Z",
"counts_as_touch": True,
"shared_group_id": 1,
"occurred_at": "2026-10-20T12:00:00Z",
"idempotency_key": "Idempotency Key",
"handwrytten": {
"generated_mailing_id": 1,
"rule_id": 1,
"account_mode": "hys_managed",
"card_vendor_id": "Handwrytten.Card Vendor Id",
"card_name": "Handwrytten.Card Name",
"font_label": "Handwrytten.Font Label",
"insert_vendor_id": "Handwrytten.Insert Vendor Id",
"message_template": "Handwrytten.Message Template",
"message": "Handwrytten.Message",
"merge_data": ["<unknown>"],
"recipient_address": {
"first_name": "Example",
"last_name": "Example",
"name": "Example",
"address1": "Example",
"address2": "Example",
"street": "Example",
"address_line2": "Example",
"city": "Example",
"state": "Example",
"province": "Example",
"zip": "Example",
"postal_code": "Example",
"country": "Example",
"country_code": "Example",
"country_id": 1
},
"sender_address": {
"first_name": "Example",
"last_name": "Example",
"name": "Example",
"address1": "Example",
"address2": "Example",
"street": "Example",
"address_line2": "Example",
"city": "Example",
"state": "Example",
"province": "Example",
"zip": "Example",
"postal_code": "Example",
"country": "Example",
"country_code": "Example",
"country_id": 1
},
"program_id": 1,
"campaign_key": "Handwrytten.Campaign Key",
"requested_send_date": "2026-10-20T12:00:00Z"
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
channel: 'call',
donor_id: 1,
handwrytten_order_id: 1,
donation_ids: [1],
subject: 'Subject',
note: 'Discuss the next update with the program team.',
body_plain: 'Body Plain',
body_visibility: 'private',
outcome: 'Outcome',
direction: 'inbound',
duration_minutes: 1,
follow_up_at: '2026-10-20T12:00:00Z',
counts_as_touch: true,
shared_group_id: 1,
occurred_at: '2026-10-20T12:00:00Z',
idempotency_key: 'Idempotency Key',
handwrytten: {
generated_mailing_id: 1,
rule_id: 1,
account_mode: 'hys_managed',
card_vendor_id: 'Handwrytten.Card Vendor Id',
card_name: 'Handwrytten.Card Name',
font_label: 'Handwrytten.Font Label',
insert_vendor_id: 'Handwrytten.Insert Vendor Id',
message_template: 'Handwrytten.Message Template',
message: 'Handwrytten.Message',
merge_data: ['<unknown>'],
recipient_address: {
first_name: 'Example',
last_name: 'Example',
name: 'Example',
address1: 'Example',
address2: 'Example',
street: 'Example',
address_line2: 'Example',
city: 'Example',
state: 'Example',
province: 'Example',
zip: 'Example',
postal_code: 'Example',
country: 'Example',
country_code: 'Example',
country_id: 1
},
sender_address: {
first_name: 'Example',
last_name: 'Example',
name: 'Example',
address1: 'Example',
address2: 'Example',
street: 'Example',
address_line2: 'Example',
city: 'Example',
state: 'Example',
province: 'Example',
zip: 'Example',
postal_code: 'Example',
country: 'Example',
country_code: 'Example',
country_id: 1
},
program_id: 1,
campaign_key: 'Handwrytten.Campaign Key',
requested_send_date: '2026-10-20T12:00:00Z'
}
})
};
fetch('https://api.gratona.com/v1/admin/handwrytten/work-items/{workItemId}/complete', 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/handwrytten/work-items/{workItemId}/complete",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'channel' => 'call',
'donor_id' => 1,
'handwrytten_order_id' => 1,
'donation_ids' => [
1
],
'subject' => 'Subject',
'note' => 'Discuss the next update with the program team.',
'body_plain' => 'Body Plain',
'body_visibility' => 'private',
'outcome' => 'Outcome',
'direction' => 'inbound',
'duration_minutes' => 1,
'follow_up_at' => '2026-10-20T12:00:00Z',
'counts_as_touch' => true,
'shared_group_id' => 1,
'occurred_at' => '2026-10-20T12:00:00Z',
'idempotency_key' => 'Idempotency Key',
'handwrytten' => [
'generated_mailing_id' => 1,
'rule_id' => 1,
'account_mode' => 'hys_managed',
'card_vendor_id' => 'Handwrytten.Card Vendor Id',
'card_name' => 'Handwrytten.Card Name',
'font_label' => 'Handwrytten.Font Label',
'insert_vendor_id' => 'Handwrytten.Insert Vendor Id',
'message_template' => 'Handwrytten.Message Template',
'message' => 'Handwrytten.Message',
'merge_data' => [
'<unknown>'
],
'recipient_address' => [
'first_name' => 'Example',
'last_name' => 'Example',
'name' => 'Example',
'address1' => 'Example',
'address2' => 'Example',
'street' => 'Example',
'address_line2' => 'Example',
'city' => 'Example',
'state' => 'Example',
'province' => 'Example',
'zip' => 'Example',
'postal_code' => 'Example',
'country' => 'Example',
'country_code' => 'Example',
'country_id' => 1
],
'sender_address' => [
'first_name' => 'Example',
'last_name' => 'Example',
'name' => 'Example',
'address1' => 'Example',
'address2' => 'Example',
'street' => 'Example',
'address_line2' => 'Example',
'city' => 'Example',
'state' => 'Example',
'province' => 'Example',
'zip' => 'Example',
'postal_code' => 'Example',
'country' => 'Example',
'country_code' => 'Example',
'country_id' => 1
],
'program_id' => 1,
'campaign_key' => 'Handwrytten.Campaign Key',
'requested_send_date' => '2026-10-20T12:00:00Z'
]
]),
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/handwrytten/work-items/{workItemId}/complete"
payload := strings.NewReader("{\n \"channel\": \"call\",\n \"donor_id\": 1,\n \"handwrytten_order_id\": 1,\n \"donation_ids\": [\n 1\n ],\n \"subject\": \"Subject\",\n \"note\": \"Discuss the next update with the program team.\",\n \"body_plain\": \"Body Plain\",\n \"body_visibility\": \"private\",\n \"outcome\": \"Outcome\",\n \"direction\": \"inbound\",\n \"duration_minutes\": 1,\n \"follow_up_at\": \"2026-10-20T12:00:00Z\",\n \"counts_as_touch\": true,\n \"shared_group_id\": 1,\n \"occurred_at\": \"2026-10-20T12:00:00Z\",\n \"idempotency_key\": \"Idempotency Key\",\n \"handwrytten\": {\n \"generated_mailing_id\": 1,\n \"rule_id\": 1,\n \"account_mode\": \"hys_managed\",\n \"card_vendor_id\": \"Handwrytten.Card Vendor Id\",\n \"card_name\": \"Handwrytten.Card Name\",\n \"font_label\": \"Handwrytten.Font Label\",\n \"insert_vendor_id\": \"Handwrytten.Insert Vendor Id\",\n \"message_template\": \"Handwrytten.Message Template\",\n \"message\": \"Handwrytten.Message\",\n \"merge_data\": [\n \"<unknown>\"\n ],\n \"recipient_address\": {\n \"first_name\": \"Example\",\n \"last_name\": \"Example\",\n \"name\": \"Example\",\n \"address1\": \"Example\",\n \"address2\": \"Example\",\n \"street\": \"Example\",\n \"address_line2\": \"Example\",\n \"city\": \"Example\",\n \"state\": \"Example\",\n \"province\": \"Example\",\n \"zip\": \"Example\",\n \"postal_code\": \"Example\",\n \"country\": \"Example\",\n \"country_code\": \"Example\",\n \"country_id\": 1\n },\n \"sender_address\": {\n \"first_name\": \"Example\",\n \"last_name\": \"Example\",\n \"name\": \"Example\",\n \"address1\": \"Example\",\n \"address2\": \"Example\",\n \"street\": \"Example\",\n \"address_line2\": \"Example\",\n \"city\": \"Example\",\n \"state\": \"Example\",\n \"province\": \"Example\",\n \"zip\": \"Example\",\n \"postal_code\": \"Example\",\n \"country\": \"Example\",\n \"country_code\": \"Example\",\n \"country_id\": 1\n },\n \"program_id\": 1,\n \"campaign_key\": \"Handwrytten.Campaign Key\",\n \"requested_send_date\": \"2026-10-20T12:00:00Z\"\n }\n}")
req, _ := http.NewRequest("POST", 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.post("https://api.gratona.com/v1/admin/handwrytten/work-items/{workItemId}/complete")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"channel\": \"call\",\n \"donor_id\": 1,\n \"handwrytten_order_id\": 1,\n \"donation_ids\": [\n 1\n ],\n \"subject\": \"Subject\",\n \"note\": \"Discuss the next update with the program team.\",\n \"body_plain\": \"Body Plain\",\n \"body_visibility\": \"private\",\n \"outcome\": \"Outcome\",\n \"direction\": \"inbound\",\n \"duration_minutes\": 1,\n \"follow_up_at\": \"2026-10-20T12:00:00Z\",\n \"counts_as_touch\": true,\n \"shared_group_id\": 1,\n \"occurred_at\": \"2026-10-20T12:00:00Z\",\n \"idempotency_key\": \"Idempotency Key\",\n \"handwrytten\": {\n \"generated_mailing_id\": 1,\n \"rule_id\": 1,\n \"account_mode\": \"hys_managed\",\n \"card_vendor_id\": \"Handwrytten.Card Vendor Id\",\n \"card_name\": \"Handwrytten.Card Name\",\n \"font_label\": \"Handwrytten.Font Label\",\n \"insert_vendor_id\": \"Handwrytten.Insert Vendor Id\",\n \"message_template\": \"Handwrytten.Message Template\",\n \"message\": \"Handwrytten.Message\",\n \"merge_data\": [\n \"<unknown>\"\n ],\n \"recipient_address\": {\n \"first_name\": \"Example\",\n \"last_name\": \"Example\",\n \"name\": \"Example\",\n \"address1\": \"Example\",\n \"address2\": \"Example\",\n \"street\": \"Example\",\n \"address_line2\": \"Example\",\n \"city\": \"Example\",\n \"state\": \"Example\",\n \"province\": \"Example\",\n \"zip\": \"Example\",\n \"postal_code\": \"Example\",\n \"country\": \"Example\",\n \"country_code\": \"Example\",\n \"country_id\": 1\n },\n \"sender_address\": {\n \"first_name\": \"Example\",\n \"last_name\": \"Example\",\n \"name\": \"Example\",\n \"address1\": \"Example\",\n \"address2\": \"Example\",\n \"street\": \"Example\",\n \"address_line2\": \"Example\",\n \"city\": \"Example\",\n \"state\": \"Example\",\n \"province\": \"Example\",\n \"zip\": \"Example\",\n \"postal_code\": \"Example\",\n \"country\": \"Example\",\n \"country_code\": \"Example\",\n \"country_id\": 1\n },\n \"program_id\": 1,\n \"campaign_key\": \"Handwrytten.Campaign Key\",\n \"requested_send_date\": \"2026-10-20T12:00:00Z\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.gratona.com/v1/admin/handwrytten/work-items/{workItemId}/complete")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"channel\": \"call\",\n \"donor_id\": 1,\n \"handwrytten_order_id\": 1,\n \"donation_ids\": [\n 1\n ],\n \"subject\": \"Subject\",\n \"note\": \"Discuss the next update with the program team.\",\n \"body_plain\": \"Body Plain\",\n \"body_visibility\": \"private\",\n \"outcome\": \"Outcome\",\n \"direction\": \"inbound\",\n \"duration_minutes\": 1,\n \"follow_up_at\": \"2026-10-20T12:00:00Z\",\n \"counts_as_touch\": true,\n \"shared_group_id\": 1,\n \"occurred_at\": \"2026-10-20T12:00:00Z\",\n \"idempotency_key\": \"Idempotency Key\",\n \"handwrytten\": {\n \"generated_mailing_id\": 1,\n \"rule_id\": 1,\n \"account_mode\": \"hys_managed\",\n \"card_vendor_id\": \"Handwrytten.Card Vendor Id\",\n \"card_name\": \"Handwrytten.Card Name\",\n \"font_label\": \"Handwrytten.Font Label\",\n \"insert_vendor_id\": \"Handwrytten.Insert Vendor Id\",\n \"message_template\": \"Handwrytten.Message Template\",\n \"message\": \"Handwrytten.Message\",\n \"merge_data\": [\n \"<unknown>\"\n ],\n \"recipient_address\": {\n \"first_name\": \"Example\",\n \"last_name\": \"Example\",\n \"name\": \"Example\",\n \"address1\": \"Example\",\n \"address2\": \"Example\",\n \"street\": \"Example\",\n \"address_line2\": \"Example\",\n \"city\": \"Example\",\n \"state\": \"Example\",\n \"province\": \"Example\",\n \"zip\": \"Example\",\n \"postal_code\": \"Example\",\n \"country\": \"Example\",\n \"country_code\": \"Example\",\n \"country_id\": 1\n },\n \"sender_address\": {\n \"first_name\": \"Example\",\n \"last_name\": \"Example\",\n \"name\": \"Example\",\n \"address1\": \"Example\",\n \"address2\": \"Example\",\n \"street\": \"Example\",\n \"address_line2\": \"Example\",\n \"city\": \"Example\",\n \"state\": \"Example\",\n \"province\": \"Example\",\n \"zip\": \"Example\",\n \"postal_code\": \"Example\",\n \"country\": \"Example\",\n \"country_code\": \"Example\",\n \"country_id\": 1\n },\n \"program_id\": 1,\n \"campaign_key\": \"Handwrytten.Campaign Key\",\n \"requested_send_date\": \"2026-10-20T12:00:00Z\"\n }\n}"
response = http.request(request)
puts response.read_body{
"data": {
"completion_status": "pending_submission",
"work_item": {
"id": 42,
"donor_id": 42,
"subject_type": "Example",
"subject_id": 42,
"action_contact_donor_id": 42,
"work_item_type": "Example",
"status": "Example",
"acted_at": "2026-10-20T12:00:00Z",
"acted_by_user_id": 42,
"context": {},
"lifecycle": [
{}
]
},
"interaction": {
"id": 42,
"client_id": 42,
"donor_id": 42,
"owner_user_id": 42,
"type": "Example",
"subject": "Example",
"body_plain": "Example",
"body_visibility": "Example",
"source": "manual",
"occurred_at": "2026-10-20T12:00:00Z",
"provider_metadata": {}
},
"acknowledgement": {
"updated_count": 100,
"items": [
{
"id": 42,
"donor_id": 42,
"acknowledged_at": "2026-10-20T12:00:00Z",
"acknowledged_by_user_id": 42,
"acknowledgement_source": "Example"
}
]
},
"handwrytten_order": {
"id": 42,
"donor_id": 42,
"generated_mailing_id": 42,
"mailing_run_id": 42,
"fundraising_work_item_id": 42,
"status": "Example",
"approval_status": "Example",
"vendor_order_id": "Example",
"vendor_status": "Example",
"card_name": "Example",
"card_vendor_id": "Example",
"font_label": "Example",
"insert_vendor_id": "Example",
"message_resolved": "Example",
"submitted_at": "2026-10-20T12:00:00Z",
"requested_send_date": "2026-10-20",
"recipient_address_snapshot_json": {
"first_name": "Example",
"last_name": "Example",
"name": "Example",
"address1": "Example",
"address2": "Example",
"street": "Example",
"address_line2": "Example",
"city": "Example",
"state": "Example",
"province": "Example",
"zip": "Example",
"postal_code": "Example",
"country": "Example",
"country_code": "Example",
"country_id": 1
},
"governance_flags_json": {},
"account_mode": "hys_managed",
"provider_test_mode": true,
"sender_address_snapshot_json": {
"first_name": "Example",
"last_name": "Example",
"name": "Example",
"address1": "Example",
"address2": "Example",
"street": "Example",
"address_line2": "Example",
"city": "Example",
"state": "Example",
"province": "Example",
"zip": "Example",
"postal_code": "Example",
"country": "Example",
"country_code": "Example",
"country_id": 1
},
"proof_snapshot_json": {},
"customer_price_cents": 100,
"wallet_reserved_cents": 100,
"wallet_spent_cents": 100,
"wallet_refunded_cents": 100,
"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
Workitem id in the current organization.
Body
Validated request fields for this operation.
Channel. Validation: required, string; allowed values: call, text, sms, email, note, meeting, handwritten_card, letter, mailing.
call, text, sms, email, note, meeting, handwritten_card, letter, mailing "call"
Donor id. Validation: nullable, integer.
1
Existing order belonging to the work action contact, or omit and supply a handwrytten draft for handwritten_card.
1
Eligible gifts for this stewardship relationship. Direct gifts are acknowledged; relationship soft-credit gifts may be retained as completion evidence only. Replays must preserve the selection.
Donation ids item. Validation: integer.
Subject. Validation: nullable, string, max:255.
255"Subject"
Note. Validation: nullable, string, max:10000.
10000"Discuss the next update with the program team."
Body plain. Validation: nullable, string, max:10000.
10000"Body Plain"
Body visibility. Validation: nullable, string; allowed values: private, metadata, shared, team.
private, metadata, shared, team, null "private"
Outcome. Validation: nullable, string, max:64.
64"Outcome"
Direction. Validation: nullable, string; allowed values: inbound, outbound, internal, none.
inbound, outbound, internal, none, null "inbound"
Duration minutes. Validation: nullable, integer, min:1, max:1440.
1 <= x <= 14401
Follow up at. Validation: nullable, date.
"2026-10-20T12:00:00Z"
Counts as touch. Validation: nullable, boolean.
true
Shared group id. Validation: required_if:body_visibility,shared, nullable, integer.
1
Occurred at. Validation: nullable, date.
"2026-10-20T12:00:00Z"
Idempotency key. Validation: nullable, string, max:191.
191"Idempotency Key"
Handwrytten. Validation: nullable, array.
Show child attributes
Show child attributes
Response
Operation result.
A handwritten draft does not complete the work or acknowledge gifts until a live provider acceptance. Replays return the existing interaction and no new acknowledgement.
Show child attributes
Show child attributes
curl --request POST \
--url https://api.gratona.com/v1/admin/handwrytten/work-items/{workItemId}/complete \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"channel": "call",
"donor_id": 1,
"handwrytten_order_id": 1,
"donation_ids": [
1
],
"subject": "Subject",
"note": "Discuss the next update with the program team.",
"body_plain": "Body Plain",
"body_visibility": "private",
"outcome": "Outcome",
"direction": "inbound",
"duration_minutes": 1,
"follow_up_at": "2026-10-20T12:00:00Z",
"counts_as_touch": true,
"shared_group_id": 1,
"occurred_at": "2026-10-20T12:00:00Z",
"idempotency_key": "Idempotency Key",
"handwrytten": {
"generated_mailing_id": 1,
"rule_id": 1,
"account_mode": "hys_managed",
"card_vendor_id": "Handwrytten.Card Vendor Id",
"card_name": "Handwrytten.Card Name",
"font_label": "Handwrytten.Font Label",
"insert_vendor_id": "Handwrytten.Insert Vendor Id",
"message_template": "Handwrytten.Message Template",
"message": "Handwrytten.Message",
"merge_data": [
"<unknown>"
],
"recipient_address": {
"first_name": "Example",
"last_name": "Example",
"name": "Example",
"address1": "Example",
"address2": "Example",
"street": "Example",
"address_line2": "Example",
"city": "Example",
"state": "Example",
"province": "Example",
"zip": "Example",
"postal_code": "Example",
"country": "Example",
"country_code": "Example",
"country_id": 1
},
"sender_address": {
"first_name": "Example",
"last_name": "Example",
"name": "Example",
"address1": "Example",
"address2": "Example",
"street": "Example",
"address_line2": "Example",
"city": "Example",
"state": "Example",
"province": "Example",
"zip": "Example",
"postal_code": "Example",
"country": "Example",
"country_code": "Example",
"country_id": 1
},
"program_id": 1,
"campaign_key": "Handwrytten.Campaign Key",
"requested_send_date": "2026-10-20T12:00:00Z"
}
}
'import requests
url = "https://api.gratona.com/v1/admin/handwrytten/work-items/{workItemId}/complete"
payload = {
"channel": "call",
"donor_id": 1,
"handwrytten_order_id": 1,
"donation_ids": [1],
"subject": "Subject",
"note": "Discuss the next update with the program team.",
"body_plain": "Body Plain",
"body_visibility": "private",
"outcome": "Outcome",
"direction": "inbound",
"duration_minutes": 1,
"follow_up_at": "2026-10-20T12:00:00Z",
"counts_as_touch": True,
"shared_group_id": 1,
"occurred_at": "2026-10-20T12:00:00Z",
"idempotency_key": "Idempotency Key",
"handwrytten": {
"generated_mailing_id": 1,
"rule_id": 1,
"account_mode": "hys_managed",
"card_vendor_id": "Handwrytten.Card Vendor Id",
"card_name": "Handwrytten.Card Name",
"font_label": "Handwrytten.Font Label",
"insert_vendor_id": "Handwrytten.Insert Vendor Id",
"message_template": "Handwrytten.Message Template",
"message": "Handwrytten.Message",
"merge_data": ["<unknown>"],
"recipient_address": {
"first_name": "Example",
"last_name": "Example",
"name": "Example",
"address1": "Example",
"address2": "Example",
"street": "Example",
"address_line2": "Example",
"city": "Example",
"state": "Example",
"province": "Example",
"zip": "Example",
"postal_code": "Example",
"country": "Example",
"country_code": "Example",
"country_id": 1
},
"sender_address": {
"first_name": "Example",
"last_name": "Example",
"name": "Example",
"address1": "Example",
"address2": "Example",
"street": "Example",
"address_line2": "Example",
"city": "Example",
"state": "Example",
"province": "Example",
"zip": "Example",
"postal_code": "Example",
"country": "Example",
"country_code": "Example",
"country_id": 1
},
"program_id": 1,
"campaign_key": "Handwrytten.Campaign Key",
"requested_send_date": "2026-10-20T12:00:00Z"
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
channel: 'call',
donor_id: 1,
handwrytten_order_id: 1,
donation_ids: [1],
subject: 'Subject',
note: 'Discuss the next update with the program team.',
body_plain: 'Body Plain',
body_visibility: 'private',
outcome: 'Outcome',
direction: 'inbound',
duration_minutes: 1,
follow_up_at: '2026-10-20T12:00:00Z',
counts_as_touch: true,
shared_group_id: 1,
occurred_at: '2026-10-20T12:00:00Z',
idempotency_key: 'Idempotency Key',
handwrytten: {
generated_mailing_id: 1,
rule_id: 1,
account_mode: 'hys_managed',
card_vendor_id: 'Handwrytten.Card Vendor Id',
card_name: 'Handwrytten.Card Name',
font_label: 'Handwrytten.Font Label',
insert_vendor_id: 'Handwrytten.Insert Vendor Id',
message_template: 'Handwrytten.Message Template',
message: 'Handwrytten.Message',
merge_data: ['<unknown>'],
recipient_address: {
first_name: 'Example',
last_name: 'Example',
name: 'Example',
address1: 'Example',
address2: 'Example',
street: 'Example',
address_line2: 'Example',
city: 'Example',
state: 'Example',
province: 'Example',
zip: 'Example',
postal_code: 'Example',
country: 'Example',
country_code: 'Example',
country_id: 1
},
sender_address: {
first_name: 'Example',
last_name: 'Example',
name: 'Example',
address1: 'Example',
address2: 'Example',
street: 'Example',
address_line2: 'Example',
city: 'Example',
state: 'Example',
province: 'Example',
zip: 'Example',
postal_code: 'Example',
country: 'Example',
country_code: 'Example',
country_id: 1
},
program_id: 1,
campaign_key: 'Handwrytten.Campaign Key',
requested_send_date: '2026-10-20T12:00:00Z'
}
})
};
fetch('https://api.gratona.com/v1/admin/handwrytten/work-items/{workItemId}/complete', 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/handwrytten/work-items/{workItemId}/complete",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'channel' => 'call',
'donor_id' => 1,
'handwrytten_order_id' => 1,
'donation_ids' => [
1
],
'subject' => 'Subject',
'note' => 'Discuss the next update with the program team.',
'body_plain' => 'Body Plain',
'body_visibility' => 'private',
'outcome' => 'Outcome',
'direction' => 'inbound',
'duration_minutes' => 1,
'follow_up_at' => '2026-10-20T12:00:00Z',
'counts_as_touch' => true,
'shared_group_id' => 1,
'occurred_at' => '2026-10-20T12:00:00Z',
'idempotency_key' => 'Idempotency Key',
'handwrytten' => [
'generated_mailing_id' => 1,
'rule_id' => 1,
'account_mode' => 'hys_managed',
'card_vendor_id' => 'Handwrytten.Card Vendor Id',
'card_name' => 'Handwrytten.Card Name',
'font_label' => 'Handwrytten.Font Label',
'insert_vendor_id' => 'Handwrytten.Insert Vendor Id',
'message_template' => 'Handwrytten.Message Template',
'message' => 'Handwrytten.Message',
'merge_data' => [
'<unknown>'
],
'recipient_address' => [
'first_name' => 'Example',
'last_name' => 'Example',
'name' => 'Example',
'address1' => 'Example',
'address2' => 'Example',
'street' => 'Example',
'address_line2' => 'Example',
'city' => 'Example',
'state' => 'Example',
'province' => 'Example',
'zip' => 'Example',
'postal_code' => 'Example',
'country' => 'Example',
'country_code' => 'Example',
'country_id' => 1
],
'sender_address' => [
'first_name' => 'Example',
'last_name' => 'Example',
'name' => 'Example',
'address1' => 'Example',
'address2' => 'Example',
'street' => 'Example',
'address_line2' => 'Example',
'city' => 'Example',
'state' => 'Example',
'province' => 'Example',
'zip' => 'Example',
'postal_code' => 'Example',
'country' => 'Example',
'country_code' => 'Example',
'country_id' => 1
],
'program_id' => 1,
'campaign_key' => 'Handwrytten.Campaign Key',
'requested_send_date' => '2026-10-20T12:00:00Z'
]
]),
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/handwrytten/work-items/{workItemId}/complete"
payload := strings.NewReader("{\n \"channel\": \"call\",\n \"donor_id\": 1,\n \"handwrytten_order_id\": 1,\n \"donation_ids\": [\n 1\n ],\n \"subject\": \"Subject\",\n \"note\": \"Discuss the next update with the program team.\",\n \"body_plain\": \"Body Plain\",\n \"body_visibility\": \"private\",\n \"outcome\": \"Outcome\",\n \"direction\": \"inbound\",\n \"duration_minutes\": 1,\n \"follow_up_at\": \"2026-10-20T12:00:00Z\",\n \"counts_as_touch\": true,\n \"shared_group_id\": 1,\n \"occurred_at\": \"2026-10-20T12:00:00Z\",\n \"idempotency_key\": \"Idempotency Key\",\n \"handwrytten\": {\n \"generated_mailing_id\": 1,\n \"rule_id\": 1,\n \"account_mode\": \"hys_managed\",\n \"card_vendor_id\": \"Handwrytten.Card Vendor Id\",\n \"card_name\": \"Handwrytten.Card Name\",\n \"font_label\": \"Handwrytten.Font Label\",\n \"insert_vendor_id\": \"Handwrytten.Insert Vendor Id\",\n \"message_template\": \"Handwrytten.Message Template\",\n \"message\": \"Handwrytten.Message\",\n \"merge_data\": [\n \"<unknown>\"\n ],\n \"recipient_address\": {\n \"first_name\": \"Example\",\n \"last_name\": \"Example\",\n \"name\": \"Example\",\n \"address1\": \"Example\",\n \"address2\": \"Example\",\n \"street\": \"Example\",\n \"address_line2\": \"Example\",\n \"city\": \"Example\",\n \"state\": \"Example\",\n \"province\": \"Example\",\n \"zip\": \"Example\",\n \"postal_code\": \"Example\",\n \"country\": \"Example\",\n \"country_code\": \"Example\",\n \"country_id\": 1\n },\n \"sender_address\": {\n \"first_name\": \"Example\",\n \"last_name\": \"Example\",\n \"name\": \"Example\",\n \"address1\": \"Example\",\n \"address2\": \"Example\",\n \"street\": \"Example\",\n \"address_line2\": \"Example\",\n \"city\": \"Example\",\n \"state\": \"Example\",\n \"province\": \"Example\",\n \"zip\": \"Example\",\n \"postal_code\": \"Example\",\n \"country\": \"Example\",\n \"country_code\": \"Example\",\n \"country_id\": 1\n },\n \"program_id\": 1,\n \"campaign_key\": \"Handwrytten.Campaign Key\",\n \"requested_send_date\": \"2026-10-20T12:00:00Z\"\n }\n}")
req, _ := http.NewRequest("POST", 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.post("https://api.gratona.com/v1/admin/handwrytten/work-items/{workItemId}/complete")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"channel\": \"call\",\n \"donor_id\": 1,\n \"handwrytten_order_id\": 1,\n \"donation_ids\": [\n 1\n ],\n \"subject\": \"Subject\",\n \"note\": \"Discuss the next update with the program team.\",\n \"body_plain\": \"Body Plain\",\n \"body_visibility\": \"private\",\n \"outcome\": \"Outcome\",\n \"direction\": \"inbound\",\n \"duration_minutes\": 1,\n \"follow_up_at\": \"2026-10-20T12:00:00Z\",\n \"counts_as_touch\": true,\n \"shared_group_id\": 1,\n \"occurred_at\": \"2026-10-20T12:00:00Z\",\n \"idempotency_key\": \"Idempotency Key\",\n \"handwrytten\": {\n \"generated_mailing_id\": 1,\n \"rule_id\": 1,\n \"account_mode\": \"hys_managed\",\n \"card_vendor_id\": \"Handwrytten.Card Vendor Id\",\n \"card_name\": \"Handwrytten.Card Name\",\n \"font_label\": \"Handwrytten.Font Label\",\n \"insert_vendor_id\": \"Handwrytten.Insert Vendor Id\",\n \"message_template\": \"Handwrytten.Message Template\",\n \"message\": \"Handwrytten.Message\",\n \"merge_data\": [\n \"<unknown>\"\n ],\n \"recipient_address\": {\n \"first_name\": \"Example\",\n \"last_name\": \"Example\",\n \"name\": \"Example\",\n \"address1\": \"Example\",\n \"address2\": \"Example\",\n \"street\": \"Example\",\n \"address_line2\": \"Example\",\n \"city\": \"Example\",\n \"state\": \"Example\",\n \"province\": \"Example\",\n \"zip\": \"Example\",\n \"postal_code\": \"Example\",\n \"country\": \"Example\",\n \"country_code\": \"Example\",\n \"country_id\": 1\n },\n \"sender_address\": {\n \"first_name\": \"Example\",\n \"last_name\": \"Example\",\n \"name\": \"Example\",\n \"address1\": \"Example\",\n \"address2\": \"Example\",\n \"street\": \"Example\",\n \"address_line2\": \"Example\",\n \"city\": \"Example\",\n \"state\": \"Example\",\n \"province\": \"Example\",\n \"zip\": \"Example\",\n \"postal_code\": \"Example\",\n \"country\": \"Example\",\n \"country_code\": \"Example\",\n \"country_id\": 1\n },\n \"program_id\": 1,\n \"campaign_key\": \"Handwrytten.Campaign Key\",\n \"requested_send_date\": \"2026-10-20T12:00:00Z\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.gratona.com/v1/admin/handwrytten/work-items/{workItemId}/complete")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"channel\": \"call\",\n \"donor_id\": 1,\n \"handwrytten_order_id\": 1,\n \"donation_ids\": [\n 1\n ],\n \"subject\": \"Subject\",\n \"note\": \"Discuss the next update with the program team.\",\n \"body_plain\": \"Body Plain\",\n \"body_visibility\": \"private\",\n \"outcome\": \"Outcome\",\n \"direction\": \"inbound\",\n \"duration_minutes\": 1,\n \"follow_up_at\": \"2026-10-20T12:00:00Z\",\n \"counts_as_touch\": true,\n \"shared_group_id\": 1,\n \"occurred_at\": \"2026-10-20T12:00:00Z\",\n \"idempotency_key\": \"Idempotency Key\",\n \"handwrytten\": {\n \"generated_mailing_id\": 1,\n \"rule_id\": 1,\n \"account_mode\": \"hys_managed\",\n \"card_vendor_id\": \"Handwrytten.Card Vendor Id\",\n \"card_name\": \"Handwrytten.Card Name\",\n \"font_label\": \"Handwrytten.Font Label\",\n \"insert_vendor_id\": \"Handwrytten.Insert Vendor Id\",\n \"message_template\": \"Handwrytten.Message Template\",\n \"message\": \"Handwrytten.Message\",\n \"merge_data\": [\n \"<unknown>\"\n ],\n \"recipient_address\": {\n \"first_name\": \"Example\",\n \"last_name\": \"Example\",\n \"name\": \"Example\",\n \"address1\": \"Example\",\n \"address2\": \"Example\",\n \"street\": \"Example\",\n \"address_line2\": \"Example\",\n \"city\": \"Example\",\n \"state\": \"Example\",\n \"province\": \"Example\",\n \"zip\": \"Example\",\n \"postal_code\": \"Example\",\n \"country\": \"Example\",\n \"country_code\": \"Example\",\n \"country_id\": 1\n },\n \"sender_address\": {\n \"first_name\": \"Example\",\n \"last_name\": \"Example\",\n \"name\": \"Example\",\n \"address1\": \"Example\",\n \"address2\": \"Example\",\n \"street\": \"Example\",\n \"address_line2\": \"Example\",\n \"city\": \"Example\",\n \"state\": \"Example\",\n \"province\": \"Example\",\n \"zip\": \"Example\",\n \"postal_code\": \"Example\",\n \"country\": \"Example\",\n \"country_code\": \"Example\",\n \"country_id\": 1\n },\n \"program_id\": 1,\n \"campaign_key\": \"Handwrytten.Campaign Key\",\n \"requested_send_date\": \"2026-10-20T12:00:00Z\"\n }\n}"
response = http.request(request)
puts response.read_body{
"data": {
"completion_status": "pending_submission",
"work_item": {
"id": 42,
"donor_id": 42,
"subject_type": "Example",
"subject_id": 42,
"action_contact_donor_id": 42,
"work_item_type": "Example",
"status": "Example",
"acted_at": "2026-10-20T12:00:00Z",
"acted_by_user_id": 42,
"context": {},
"lifecycle": [
{}
]
},
"interaction": {
"id": 42,
"client_id": 42,
"donor_id": 42,
"owner_user_id": 42,
"type": "Example",
"subject": "Example",
"body_plain": "Example",
"body_visibility": "Example",
"source": "manual",
"occurred_at": "2026-10-20T12:00:00Z",
"provider_metadata": {}
},
"acknowledgement": {
"updated_count": 100,
"items": [
{
"id": 42,
"donor_id": 42,
"acknowledged_at": "2026-10-20T12:00:00Z",
"acknowledged_by_user_id": 42,
"acknowledgement_source": "Example"
}
]
},
"handwrytten_order": {
"id": 42,
"donor_id": 42,
"generated_mailing_id": 42,
"mailing_run_id": 42,
"fundraising_work_item_id": 42,
"status": "Example",
"approval_status": "Example",
"vendor_order_id": "Example",
"vendor_status": "Example",
"card_name": "Example",
"card_vendor_id": "Example",
"font_label": "Example",
"insert_vendor_id": "Example",
"message_resolved": "Example",
"submitted_at": "2026-10-20T12:00:00Z",
"requested_send_date": "2026-10-20",
"recipient_address_snapshot_json": {
"first_name": "Example",
"last_name": "Example",
"name": "Example",
"address1": "Example",
"address2": "Example",
"street": "Example",
"address_line2": "Example",
"city": "Example",
"state": "Example",
"province": "Example",
"zip": "Example",
"postal_code": "Example",
"country": "Example",
"country_code": "Example",
"country_id": 1
},
"governance_flags_json": {},
"account_mode": "hys_managed",
"provider_test_mode": true,
"sender_address_snapshot_json": {
"first_name": "Example",
"last_name": "Example",
"name": "Example",
"address1": "Example",
"address2": "Example",
"street": "Example",
"address_line2": "Example",
"city": "Example",
"state": "Example",
"province": "Example",
"zip": "Example",
"postal_code": "Example",
"country": "Example",
"country_code": "Example",
"country_id": 1
},
"proof_snapshot_json": {},
"customer_price_cents": 100,
"wallet_reserved_cents": 100,
"wallet_spent_cents": 100,
"wallet_refunded_cents": 100,
"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."
}