Create a new note
Creates a donor or recipient note and resolves its category within the organization. Requires notes_manage and access to the linked donor form or program.
curl --request POST \
--url https://api.gratona.com/v2/notes \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"note": "Called to thank the donor.",
"type": "donor",
"entity_id": 321,
"donor_id": 12345,
"program_id": 77,
"categories": "Phone call"
}
'import requests
url = "https://api.gratona.com/v2/notes"
payload = {
"note": "Called to thank the donor.",
"type": "donor",
"entity_id": 321,
"donor_id": 12345,
"program_id": 77,
"categories": "Phone call"
}
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({
note: 'Called to thank the donor.',
type: 'donor',
entity_id: 321,
donor_id: 12345,
program_id: 77,
categories: 'Phone call'
})
};
fetch('https://api.gratona.com/v2/notes', 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/v2/notes",
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([
'note' => 'Called to thank the donor.',
'type' => 'donor',
'entity_id' => 321,
'donor_id' => 12345,
'program_id' => 77,
'categories' => 'Phone call'
]),
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/v2/notes"
payload := strings.NewReader("{\n \"note\": \"Called to thank the donor.\",\n \"type\": \"donor\",\n \"entity_id\": 321,\n \"donor_id\": 12345,\n \"program_id\": 77,\n \"categories\": \"Phone call\"\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/v2/notes")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"note\": \"Called to thank the donor.\",\n \"type\": \"donor\",\n \"entity_id\": 321,\n \"donor_id\": 12345,\n \"program_id\": 77,\n \"categories\": \"Phone call\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.gratona.com/v2/notes")
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 \"note\": \"Called to thank the donor.\",\n \"type\": \"donor\",\n \"entity_id\": 321,\n \"donor_id\": 12345,\n \"program_id\": 77,\n \"categories\": \"Phone call\"\n}"
response = http.request(request)
puts response.read_body{
"status": "success",
"message": "Note created successfully",
"data": {
"id": 4422,
"record_type": "donor",
"record_id": 12345,
"note": "Called to thank the donor.",
"category": {
"id": 7,
"category": "Phone call"
},
"donor": {
"id": 12345,
"username": "alex",
"email": "alex@example.com"
},
"created_by": {
"id": 1024,
"name": "Alex Staff"
},
"created_at": "2026-10-20T09:00:00Z",
"updated_at": "2026-10-20T09:00:00Z"
}
}{
"message": "Unauthorized",
"status": "error"
}{
"message": "Something went wrong. Please try again.",
"status": "error",
"error": "invalid_request",
"code": "DONOR_NOT_FOUND"
}{
"message": "Not Found",
"status": "error"
}{
"errors": {},
"status": "error",
"message": "The given data was invalid."
}Authorizations
Passport bearer token authentication for legacy admin sessions.
Body
New note and profile context.
Note body. Validation rule: required|min:3|string.
3"Called to thank the donor."
Profile type. Validation rule: required|string|in:entity,donor.
entity, donor "donor"
Recipient ID; required when type is entity. The service resolves it within the caller's organization.
321
Donor ID; required when type is donor. The service resolves it within the caller's organization.
12345
Required when type is entity. Category ownership is resolved from the recipient's stored program.
77
Category name; omitted or blank names resolve to uncategorized. Validation rule: nullable|string|max:255.
255"Phone call"
curl --request POST \
--url https://api.gratona.com/v2/notes \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"note": "Called to thank the donor.",
"type": "donor",
"entity_id": 321,
"donor_id": 12345,
"program_id": 77,
"categories": "Phone call"
}
'import requests
url = "https://api.gratona.com/v2/notes"
payload = {
"note": "Called to thank the donor.",
"type": "donor",
"entity_id": 321,
"donor_id": 12345,
"program_id": 77,
"categories": "Phone call"
}
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({
note: 'Called to thank the donor.',
type: 'donor',
entity_id: 321,
donor_id: 12345,
program_id: 77,
categories: 'Phone call'
})
};
fetch('https://api.gratona.com/v2/notes', 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/v2/notes",
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([
'note' => 'Called to thank the donor.',
'type' => 'donor',
'entity_id' => 321,
'donor_id' => 12345,
'program_id' => 77,
'categories' => 'Phone call'
]),
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/v2/notes"
payload := strings.NewReader("{\n \"note\": \"Called to thank the donor.\",\n \"type\": \"donor\",\n \"entity_id\": 321,\n \"donor_id\": 12345,\n \"program_id\": 77,\n \"categories\": \"Phone call\"\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/v2/notes")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"note\": \"Called to thank the donor.\",\n \"type\": \"donor\",\n \"entity_id\": 321,\n \"donor_id\": 12345,\n \"program_id\": 77,\n \"categories\": \"Phone call\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.gratona.com/v2/notes")
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 \"note\": \"Called to thank the donor.\",\n \"type\": \"donor\",\n \"entity_id\": 321,\n \"donor_id\": 12345,\n \"program_id\": 77,\n \"categories\": \"Phone call\"\n}"
response = http.request(request)
puts response.read_body{
"status": "success",
"message": "Note created successfully",
"data": {
"id": 4422,
"record_type": "donor",
"record_id": 12345,
"note": "Called to thank the donor.",
"category": {
"id": 7,
"category": "Phone call"
},
"donor": {
"id": 12345,
"username": "alex",
"email": "alex@example.com"
},
"created_by": {
"id": 1024,
"name": "Alex Staff"
},
"created_at": "2026-10-20T09:00:00Z",
"updated_at": "2026-10-20T09:00:00Z"
}
}{
"message": "Unauthorized",
"status": "error"
}{
"message": "Something went wrong. Please try again.",
"status": "error",
"error": "invalid_request",
"code": "DONOR_NOT_FOUND"
}{
"message": "Not Found",
"status": "error"
}{
"errors": {},
"status": "error",
"message": "The given data was invalid."
}