Create a record comment
Collaboration is feature-gated and scoped to accessible task, donor, recipient, sponsorship or space_page records in the organization. Archived subjects are read-only409; Support Sessions cannot write. Editing comments requires authorship; pinning requires management access. Revisions and request UUIDs protect concurrent edits. Downloads require a safe scan and existing stored bytes.
curl --request POST \
--url https://api.gratona.com/v1/admin/collaboration/{subjectType}/{subjectId}/comments \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"body_document": {
"version": 1,
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Please review the updated trip details."
}
]
}
]
},
"idempotency_key": "b2e01bb7-6c5a-4bc6-9ee6-20b5a4295605",
"collaboration_attachment_ids": [
2
],
"collaboration_draft_context_id": "b2e01bb7-6c5a-4bc6-9ee6-20b5a4295605"
}
'import requests
url = "https://api.gratona.com/v1/admin/collaboration/{subjectType}/{subjectId}/comments"
payload = {
"body_document": {
"version": 1,
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Please review the updated trip details."
}
]
}
]
},
"idempotency_key": "b2e01bb7-6c5a-4bc6-9ee6-20b5a4295605",
"collaboration_attachment_ids": [2],
"collaboration_draft_context_id": "b2e01bb7-6c5a-4bc6-9ee6-20b5a4295605"
}
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_document: {
version: 1,
type: 'doc',
content: [
{
type: 'paragraph',
content: [{type: 'text', text: 'Please review the updated trip details.'}]
}
]
},
idempotency_key: 'b2e01bb7-6c5a-4bc6-9ee6-20b5a4295605',
collaboration_attachment_ids: [2],
collaboration_draft_context_id: 'b2e01bb7-6c5a-4bc6-9ee6-20b5a4295605'
})
};
fetch('https://api.gratona.com/v1/admin/collaboration/{subjectType}/{subjectId}/comments', 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/collaboration/{subjectType}/{subjectId}/comments",
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_document' => [
'version' => 1,
'type' => 'doc',
'content' => [
[
'type' => 'paragraph',
'content' => [
[
'type' => 'text',
'text' => 'Please review the updated trip details.'
]
]
]
]
],
'idempotency_key' => 'b2e01bb7-6c5a-4bc6-9ee6-20b5a4295605',
'collaboration_attachment_ids' => [
2
],
'collaboration_draft_context_id' => 'b2e01bb7-6c5a-4bc6-9ee6-20b5a4295605'
]),
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/collaboration/{subjectType}/{subjectId}/comments"
payload := strings.NewReader("{\n \"body_document\": {\n \"version\": 1,\n \"type\": \"doc\",\n \"content\": [\n {\n \"type\": \"paragraph\",\n \"content\": [\n {\n \"type\": \"text\",\n \"text\": \"Please review the updated trip details.\"\n }\n ]\n }\n ]\n },\n \"idempotency_key\": \"b2e01bb7-6c5a-4bc6-9ee6-20b5a4295605\",\n \"collaboration_attachment_ids\": [\n 2\n ],\n \"collaboration_draft_context_id\": \"b2e01bb7-6c5a-4bc6-9ee6-20b5a4295605\"\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/collaboration/{subjectType}/{subjectId}/comments")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"body_document\": {\n \"version\": 1,\n \"type\": \"doc\",\n \"content\": [\n {\n \"type\": \"paragraph\",\n \"content\": [\n {\n \"type\": \"text\",\n \"text\": \"Please review the updated trip details.\"\n }\n ]\n }\n ]\n },\n \"idempotency_key\": \"b2e01bb7-6c5a-4bc6-9ee6-20b5a4295605\",\n \"collaboration_attachment_ids\": [\n 2\n ],\n \"collaboration_draft_context_id\": \"b2e01bb7-6c5a-4bc6-9ee6-20b5a4295605\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.gratona.com/v1/admin/collaboration/{subjectType}/{subjectId}/comments")
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_document\": {\n \"version\": 1,\n \"type\": \"doc\",\n \"content\": [\n {\n \"type\": \"paragraph\",\n \"content\": [\n {\n \"type\": \"text\",\n \"text\": \"Please review the updated trip details.\"\n }\n ]\n }\n ]\n },\n \"idempotency_key\": \"b2e01bb7-6c5a-4bc6-9ee6-20b5a4295605\",\n \"collaboration_attachment_ids\": [\n 2\n ],\n \"collaboration_draft_context_id\": \"b2e01bb7-6c5a-4bc6-9ee6-20b5a4295605\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": 123,
"body": "<string>",
"revision": 123,
"idempotency_key": "<string>",
"pinned": true,
"pinned_at": "2023-11-07T05:31:56Z",
"edited_at": "2023-11-07T05:31:56Z",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"body_document": {
"version": 1,
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Please review the updated trip details."
}
]
}
]
},
"author": {
"id": 123,
"name": "<string>"
},
"mentions": [
{
"user_id": 123,
"name": "<string>",
"email": "<string>"
}
],
"attachments": [
{
"id": 123,
"name": "<string>",
"mime": "<string>",
"size": 123,
"status": "<string>",
"comment_id": 123,
"created_at": "2023-11-07T05:31:56Z",
"permissions": {
"delete": true
}
}
],
"permissions": {
"edit": true,
"delete": true,
"pin": true
}
}
}{
"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"
}{
"message": "<string>",
"code": "<string>",
"data": {
"comment": {
"id": 123,
"body": "<string>",
"revision": 123,
"idempotency_key": "<string>",
"pinned": true,
"pinned_at": "2023-11-07T05:31:56Z",
"edited_at": "2023-11-07T05:31:56Z",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"body_document": {
"version": 1,
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Please review the updated trip details."
}
]
}
]
},
"author": {
"id": 123,
"name": "<string>"
},
"mentions": [
{
"user_id": 123,
"name": "<string>",
"email": "<string>"
}
],
"attachments": [
{
"id": 123,
"name": "<string>",
"mime": "<string>",
"size": 123,
"status": "<string>",
"comment_id": 123,
"created_at": "2023-11-07T05:31:56Z",
"permissions": {
"delete": true
}
}
],
"permissions": {
"edit": true,
"delete": true,
"pin": true
}
}
}
}{
"errors": {},
"status": "error",
"message": "The given data was invalid."
}Authorizations
Passport bearer token authentication for legacy admin sessions.
Path Parameters
Supported collaboration subject type.
ID of the accessible collaboration subject.
Body
Request fields accepted by this operation. Omitted optional properties retain the behavior described above.
Comment document version 1. Supports paragraphs containing text, teammate mentions and hard breaks. At most25 distinct mentioned users, all with access to the subject. A comment needs text or an attachment.
Show child attributes
Show child attributes
Validation: required|uuid.
"b2e01bb7-6c5a-4bc6-9ee6-20b5a4295605"
10x >= 1Validation: nullable|uuid.
"b2e01bb7-6c5a-4bc6-9ee6-20b5a4295605"
Response
Create a record comment response.
Show child attributes
Show child attributes
curl --request POST \
--url https://api.gratona.com/v1/admin/collaboration/{subjectType}/{subjectId}/comments \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"body_document": {
"version": 1,
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Please review the updated trip details."
}
]
}
]
},
"idempotency_key": "b2e01bb7-6c5a-4bc6-9ee6-20b5a4295605",
"collaboration_attachment_ids": [
2
],
"collaboration_draft_context_id": "b2e01bb7-6c5a-4bc6-9ee6-20b5a4295605"
}
'import requests
url = "https://api.gratona.com/v1/admin/collaboration/{subjectType}/{subjectId}/comments"
payload = {
"body_document": {
"version": 1,
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Please review the updated trip details."
}
]
}
]
},
"idempotency_key": "b2e01bb7-6c5a-4bc6-9ee6-20b5a4295605",
"collaboration_attachment_ids": [2],
"collaboration_draft_context_id": "b2e01bb7-6c5a-4bc6-9ee6-20b5a4295605"
}
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_document: {
version: 1,
type: 'doc',
content: [
{
type: 'paragraph',
content: [{type: 'text', text: 'Please review the updated trip details.'}]
}
]
},
idempotency_key: 'b2e01bb7-6c5a-4bc6-9ee6-20b5a4295605',
collaboration_attachment_ids: [2],
collaboration_draft_context_id: 'b2e01bb7-6c5a-4bc6-9ee6-20b5a4295605'
})
};
fetch('https://api.gratona.com/v1/admin/collaboration/{subjectType}/{subjectId}/comments', 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/collaboration/{subjectType}/{subjectId}/comments",
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_document' => [
'version' => 1,
'type' => 'doc',
'content' => [
[
'type' => 'paragraph',
'content' => [
[
'type' => 'text',
'text' => 'Please review the updated trip details.'
]
]
]
]
],
'idempotency_key' => 'b2e01bb7-6c5a-4bc6-9ee6-20b5a4295605',
'collaboration_attachment_ids' => [
2
],
'collaboration_draft_context_id' => 'b2e01bb7-6c5a-4bc6-9ee6-20b5a4295605'
]),
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/collaboration/{subjectType}/{subjectId}/comments"
payload := strings.NewReader("{\n \"body_document\": {\n \"version\": 1,\n \"type\": \"doc\",\n \"content\": [\n {\n \"type\": \"paragraph\",\n \"content\": [\n {\n \"type\": \"text\",\n \"text\": \"Please review the updated trip details.\"\n }\n ]\n }\n ]\n },\n \"idempotency_key\": \"b2e01bb7-6c5a-4bc6-9ee6-20b5a4295605\",\n \"collaboration_attachment_ids\": [\n 2\n ],\n \"collaboration_draft_context_id\": \"b2e01bb7-6c5a-4bc6-9ee6-20b5a4295605\"\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/collaboration/{subjectType}/{subjectId}/comments")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"body_document\": {\n \"version\": 1,\n \"type\": \"doc\",\n \"content\": [\n {\n \"type\": \"paragraph\",\n \"content\": [\n {\n \"type\": \"text\",\n \"text\": \"Please review the updated trip details.\"\n }\n ]\n }\n ]\n },\n \"idempotency_key\": \"b2e01bb7-6c5a-4bc6-9ee6-20b5a4295605\",\n \"collaboration_attachment_ids\": [\n 2\n ],\n \"collaboration_draft_context_id\": \"b2e01bb7-6c5a-4bc6-9ee6-20b5a4295605\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.gratona.com/v1/admin/collaboration/{subjectType}/{subjectId}/comments")
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_document\": {\n \"version\": 1,\n \"type\": \"doc\",\n \"content\": [\n {\n \"type\": \"paragraph\",\n \"content\": [\n {\n \"type\": \"text\",\n \"text\": \"Please review the updated trip details.\"\n }\n ]\n }\n ]\n },\n \"idempotency_key\": \"b2e01bb7-6c5a-4bc6-9ee6-20b5a4295605\",\n \"collaboration_attachment_ids\": [\n 2\n ],\n \"collaboration_draft_context_id\": \"b2e01bb7-6c5a-4bc6-9ee6-20b5a4295605\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": 123,
"body": "<string>",
"revision": 123,
"idempotency_key": "<string>",
"pinned": true,
"pinned_at": "2023-11-07T05:31:56Z",
"edited_at": "2023-11-07T05:31:56Z",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"body_document": {
"version": 1,
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Please review the updated trip details."
}
]
}
]
},
"author": {
"id": 123,
"name": "<string>"
},
"mentions": [
{
"user_id": 123,
"name": "<string>",
"email": "<string>"
}
],
"attachments": [
{
"id": 123,
"name": "<string>",
"mime": "<string>",
"size": 123,
"status": "<string>",
"comment_id": 123,
"created_at": "2023-11-07T05:31:56Z",
"permissions": {
"delete": true
}
}
],
"permissions": {
"edit": true,
"delete": true,
"pin": true
}
}
}{
"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"
}{
"message": "<string>",
"code": "<string>",
"data": {
"comment": {
"id": 123,
"body": "<string>",
"revision": 123,
"idempotency_key": "<string>",
"pinned": true,
"pinned_at": "2023-11-07T05:31:56Z",
"edited_at": "2023-11-07T05:31:56Z",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"body_document": {
"version": 1,
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Please review the updated trip details."
}
]
}
]
},
"author": {
"id": 123,
"name": "<string>"
},
"mentions": [
{
"user_id": 123,
"name": "<string>",
"email": "<string>"
}
],
"attachments": [
{
"id": 123,
"name": "<string>",
"mime": "<string>",
"size": 123,
"status": "<string>",
"comment_id": 123,
"created_at": "2023-11-07T05:31:56Z",
"permissions": {
"delete": true
}
}
],
"permissions": {
"edit": true,
"delete": true,
"pin": true
}
}
}
}{
"errors": {},
"status": "error",
"message": "The given data was invalid."
}