curl --request POST \
--url https://app.sajn.se/api/v1/documents/{id}/comments \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'authorization: <authorization>' \
--data '
{
"body": "<string>",
"excerpt": "<string>",
"mentions": [
"<string>"
]
}
'import requests
url = "https://app.sajn.se/api/v1/documents/{id}/comments"
payload = {
"body": "<string>",
"excerpt": "<string>",
"mentions": ["<string>"]
}
headers = {
"authorization": "<authorization>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
authorization: '<authorization>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({body: JSON.stringify('<string>'), excerpt: '<string>', mentions: ['<string>']})
};
fetch('https://app.sajn.se/api/v1/documents/{id}/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://app.sajn.se/api/v1/documents/{id}/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' => '<string>',
'excerpt' => '<string>',
'mentions' => [
'<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"authorization: <authorization>"
],
]);
$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://app.sajn.se/api/v1/documents/{id}/comments"
payload := strings.NewReader("{\n \"body\": \"<string>\",\n \"excerpt\": \"<string>\",\n \"mentions\": [\n \"<string>\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("authorization", "<authorization>")
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://app.sajn.se/api/v1/documents/{id}/comments")
.header("authorization", "<authorization>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"body\": \"<string>\",\n \"excerpt\": \"<string>\",\n \"mentions\": [\n \"<string>\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.sajn.se/api/v1/documents/{id}/comments")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["authorization"] = '<authorization>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"body\": \"<string>\",\n \"excerpt\": \"<string>\",\n \"mentions\": [\n \"<string>\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"documentId": "<string>",
"status": "OPEN",
"visibility": "INTERNAL",
"excerpt": "<string>",
"createdAt": "<unknown>",
"updatedAt": "<unknown>",
"resolvedAt": null,
"createdBy": {
"id": "<string>",
"name": "<string>",
"email": "<string>"
},
"resolvedBy": {
"id": "<string>",
"name": "<string>",
"email": "<string>"
},
"messages": [
{
"id": "<string>",
"threadId": "<string>",
"parentId": "<string>",
"authorType": "USER",
"body": "<string>",
"mentions": [
"<string>"
],
"createdAt": "<unknown>",
"editedAt": null,
"deletedAt": null,
"author": {
"id": "<string>",
"name": "<string>",
"email": "<string>"
}
}
]
}{
"message": "<string>",
"code": "<string>",
"errorId": "<string>",
"issues": [
{
"path": "<string>",
"message": "<string>"
}
],
"requiredScopes": [
"<string>"
],
"grantedScopes": [
"<string>"
]
}{
"message": "<string>",
"code": "<string>",
"errorId": "<string>",
"issues": [
{
"path": "<string>",
"message": "<string>"
}
],
"requiredScopes": [
"<string>"
],
"grantedScopes": [
"<string>"
]
}{
"message": "<string>",
"code": "<string>",
"errorId": "<string>",
"issues": [
{
"path": "<string>",
"message": "<string>"
}
],
"requiredScopes": [
"<string>"
],
"grantedScopes": [
"<string>"
]
}Create a comment thread on a document
Start a new comment thread on a document with an initial message. Mention users by passing their user IDs in mentions.
curl --request POST \
--url https://app.sajn.se/api/v1/documents/{id}/comments \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'authorization: <authorization>' \
--data '
{
"body": "<string>",
"excerpt": "<string>",
"mentions": [
"<string>"
]
}
'import requests
url = "https://app.sajn.se/api/v1/documents/{id}/comments"
payload = {
"body": "<string>",
"excerpt": "<string>",
"mentions": ["<string>"]
}
headers = {
"authorization": "<authorization>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
authorization: '<authorization>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({body: JSON.stringify('<string>'), excerpt: '<string>', mentions: ['<string>']})
};
fetch('https://app.sajn.se/api/v1/documents/{id}/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://app.sajn.se/api/v1/documents/{id}/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' => '<string>',
'excerpt' => '<string>',
'mentions' => [
'<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"authorization: <authorization>"
],
]);
$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://app.sajn.se/api/v1/documents/{id}/comments"
payload := strings.NewReader("{\n \"body\": \"<string>\",\n \"excerpt\": \"<string>\",\n \"mentions\": [\n \"<string>\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("authorization", "<authorization>")
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://app.sajn.se/api/v1/documents/{id}/comments")
.header("authorization", "<authorization>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"body\": \"<string>\",\n \"excerpt\": \"<string>\",\n \"mentions\": [\n \"<string>\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.sajn.se/api/v1/documents/{id}/comments")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["authorization"] = '<authorization>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"body\": \"<string>\",\n \"excerpt\": \"<string>\",\n \"mentions\": [\n \"<string>\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"documentId": "<string>",
"status": "OPEN",
"visibility": "INTERNAL",
"excerpt": "<string>",
"createdAt": "<unknown>",
"updatedAt": "<unknown>",
"resolvedAt": null,
"createdBy": {
"id": "<string>",
"name": "<string>",
"email": "<string>"
},
"resolvedBy": {
"id": "<string>",
"name": "<string>",
"email": "<string>"
},
"messages": [
{
"id": "<string>",
"threadId": "<string>",
"parentId": "<string>",
"authorType": "USER",
"body": "<string>",
"mentions": [
"<string>"
],
"createdAt": "<unknown>",
"editedAt": null,
"deletedAt": null,
"author": {
"id": "<string>",
"name": "<string>",
"email": "<string>"
}
}
]
}{
"message": "<string>",
"code": "<string>",
"errorId": "<string>",
"issues": [
{
"path": "<string>",
"message": "<string>"
}
],
"requiredScopes": [
"<string>"
],
"grantedScopes": [
"<string>"
]
}{
"message": "<string>",
"code": "<string>",
"errorId": "<string>",
"issues": [
{
"path": "<string>",
"message": "<string>"
}
],
"requiredScopes": [
"<string>"
],
"grantedScopes": [
"<string>"
]
}{
"message": "<string>",
"code": "<string>",
"errorId": "<string>",
"issues": [
{
"path": "<string>",
"message": "<string>"
}
],
"requiredScopes": [
"<string>"
],
"grantedScopes": [
"<string>"
]
}2026-09, which is deprecated and stops working on October 1, 2027. To see the current version, select 2026-10 in the menu at the top of the sidebar. To move your integration, see Upgrading to 2026-10.Authorizations
Personal API key, e.g. Authorization: Bearer sajn_sk_.... Not scope-limited — acts as the issuing user.
Headers
Bearer token for API authentication
Makes retries safe. A retry with the same key and the same request replays the stored response for 24 hours (header Idempotent-Replayed: true); the same key with a different request returns 400.
255Path Parameters
Body
Body
Initial message body for the new thread
1Optional excerpt of the document content the thread refers to
User IDs mentioned in the message
SHARED makes the thread visible to every party on the document; INTERNAL (the default) keeps it to the workspace
INTERNAL, SHARED Response
200
OPEN, RESOLVED INTERNAL, SHARED Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Was this page helpful?

