Save a trip communication draft or log
Requires access to trip messages under the authenticated organization and excludes sample trips. Saving a draft does not send it; phone and note channels create manual logs. Sending resolves active matching participants with email addresses and queues email or SMS delivery; SMS also requires at least one valid phone.
curl --request POST \
--url https://api.gratona.com/v1/admin/trips/{tripId}/messages \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"body": "Please review the updated trip details.",
"subject": "<string>",
"channel": "email",
"recipient_filter": {
"custom": [
123
],
"role": "leader",
"task_incomplete": 123,
"fundraising_below": 40
},
"participant_ids": [
123
]
}
'import requests
url = "https://api.gratona.com/v1/admin/trips/{tripId}/messages"
payload = {
"body": "Please review the updated trip details.",
"subject": "<string>",
"channel": "email",
"recipient_filter": {
"custom": [123],
"role": "leader",
"task_incomplete": 123,
"fundraising_below": 40
},
"participant_ids": [123]
}
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({
body: JSON.stringify('Please review the updated trip details.'),
subject: '<string>',
channel: 'email',
recipient_filter: {custom: [123], role: 'leader', task_incomplete: 123, fundraising_below: 40},
participant_ids: [123]
})
};
fetch('https://api.gratona.com/v1/admin/trips/{tripId}/messages', 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/trips/{tripId}/messages",
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([
'body' => 'Please review the updated trip details.',
'subject' => '<string>',
'channel' => 'email',
'recipient_filter' => [
'custom' => [
123
],
'role' => 'leader',
'task_incomplete' => 123,
'fundraising_below' => 40
],
'participant_ids' => [
123
]
]),
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/trips/{tripId}/messages"
payload := strings.NewReader("{\n \"body\": \"Please review the updated trip details.\",\n \"subject\": \"<string>\",\n \"channel\": \"email\",\n \"recipient_filter\": {\n \"custom\": [\n 123\n ],\n \"role\": \"leader\",\n \"task_incomplete\": 123,\n \"fundraising_below\": 40\n },\n \"participant_ids\": [\n 123\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/trips/{tripId}/messages")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"body\": \"Please review the updated trip details.\",\n \"subject\": \"<string>\",\n \"channel\": \"email\",\n \"recipient_filter\": {\n \"custom\": [\n 123\n ],\n \"role\": \"leader\",\n \"task_incomplete\": 123,\n \"fundraising_below\": 40\n },\n \"participant_ids\": [\n 123\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.gratona.com/v1/admin/trips/{tripId}/messages")
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 \"body\": \"Please review the updated trip details.\",\n \"subject\": \"<string>\",\n \"channel\": \"email\",\n \"recipient_filter\": {\n \"custom\": [\n 123\n ],\n \"role\": \"leader\",\n \"task_incomplete\": 123,\n \"fundraising_below\": 40\n },\n \"participant_ids\": [\n 123\n ]\n}"
response = http.request(request)
puts response.read_body{
"message": "Saved successfully.",
"data": {
"id": 123,
"subject": "<string>",
"body": "<string>",
"channel": "<string>",
"entry_type": "<string>",
"status": "<string>",
"recipient_count": 123,
"sent_at": "2023-11-07T05:31:56Z",
"activity_at": "2023-11-07T05:31:56Z",
"replies_count": 123,
"created_at": "2023-11-07T05:31:56Z",
"recipient_filter": {
"custom": [
123
],
"role": "leader",
"task_incomplete": 123,
"fundraising_below": 123
},
"sender": {
"id": 123,
"name": "<string>",
"email": "<string>"
},
"participants": [
{
"id": 123,
"name": "<string>",
"email": "<string>",
"role": "<string>",
"status": "<string>"
}
]
}
}{
"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.
Path Parameters
Trip ID belonging to the authenticated organization.
Body
Request fields accepted by this operation. Omitted optional properties retain the behavior described above.
Validation: required|string|max:50000.
50000"Please review the updated trip details."
Validation: nullable|string|max:255.
255Validation: nullable|in:email,sms,phone,note.
email, sms, phone, note, null "email"
Show child attributes
Show child attributes
Trip participant IDs; at least one is required for phone or note entries. Subject is required for email or SMS drafts.
curl --request POST \
--url https://api.gratona.com/v1/admin/trips/{tripId}/messages \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"body": "Please review the updated trip details.",
"subject": "<string>",
"channel": "email",
"recipient_filter": {
"custom": [
123
],
"role": "leader",
"task_incomplete": 123,
"fundraising_below": 40
},
"participant_ids": [
123
]
}
'import requests
url = "https://api.gratona.com/v1/admin/trips/{tripId}/messages"
payload = {
"body": "Please review the updated trip details.",
"subject": "<string>",
"channel": "email",
"recipient_filter": {
"custom": [123],
"role": "leader",
"task_incomplete": 123,
"fundraising_below": 40
},
"participant_ids": [123]
}
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({
body: JSON.stringify('Please review the updated trip details.'),
subject: '<string>',
channel: 'email',
recipient_filter: {custom: [123], role: 'leader', task_incomplete: 123, fundraising_below: 40},
participant_ids: [123]
})
};
fetch('https://api.gratona.com/v1/admin/trips/{tripId}/messages', 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/trips/{tripId}/messages",
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([
'body' => 'Please review the updated trip details.',
'subject' => '<string>',
'channel' => 'email',
'recipient_filter' => [
'custom' => [
123
],
'role' => 'leader',
'task_incomplete' => 123,
'fundraising_below' => 40
],
'participant_ids' => [
123
]
]),
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/trips/{tripId}/messages"
payload := strings.NewReader("{\n \"body\": \"Please review the updated trip details.\",\n \"subject\": \"<string>\",\n \"channel\": \"email\",\n \"recipient_filter\": {\n \"custom\": [\n 123\n ],\n \"role\": \"leader\",\n \"task_incomplete\": 123,\n \"fundraising_below\": 40\n },\n \"participant_ids\": [\n 123\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/trips/{tripId}/messages")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"body\": \"Please review the updated trip details.\",\n \"subject\": \"<string>\",\n \"channel\": \"email\",\n \"recipient_filter\": {\n \"custom\": [\n 123\n ],\n \"role\": \"leader\",\n \"task_incomplete\": 123,\n \"fundraising_below\": 40\n },\n \"participant_ids\": [\n 123\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.gratona.com/v1/admin/trips/{tripId}/messages")
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 \"body\": \"Please review the updated trip details.\",\n \"subject\": \"<string>\",\n \"channel\": \"email\",\n \"recipient_filter\": {\n \"custom\": [\n 123\n ],\n \"role\": \"leader\",\n \"task_incomplete\": 123,\n \"fundraising_below\": 40\n },\n \"participant_ids\": [\n 123\n ]\n}"
response = http.request(request)
puts response.read_body{
"message": "Saved successfully.",
"data": {
"id": 123,
"subject": "<string>",
"body": "<string>",
"channel": "<string>",
"entry_type": "<string>",
"status": "<string>",
"recipient_count": 123,
"sent_at": "2023-11-07T05:31:56Z",
"activity_at": "2023-11-07T05:31:56Z",
"replies_count": 123,
"created_at": "2023-11-07T05:31:56Z",
"recipient_filter": {
"custom": [
123
],
"role": "leader",
"task_incomplete": 123,
"fundraising_below": 123
},
"sender": {
"id": 123,
"name": "<string>",
"email": "<string>"
},
"participants": [
{
"id": 123,
"name": "<string>",
"email": "<string>",
"role": "<string>",
"status": "<string>"
}
]
}
}{
"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."
}