Comments are the messages in a discussion: the customer's first message, every reply after it, and the internal notes your team leaves for each other. You read them with their discussion, and add one by replying.
Listing a discussion's comments
GET /yoursite/discussions/{id}/comments
The comments come inside their discussion, the same answer as getting the discussion:
curl -H "Accept: application/vnd.tender-v1+json" \
-H "Authorization: Bearer $TENDER_TOKEN" \
https://api.tenderapp.com/yoursite/discussions/17/comments
{
"title": "Board view is slow with 500+ cards",
"state": "open",
"comments": [
{
"body": "Our \"Fleet maintenance\" board has about 600 cards and takes 15 seconds to load. Other boards are fine.",
"formatted_body": "<div><p>Our \"Fleet maintenance\" board has about 600 cards and takes 15 seconds to load. Other boards are fine.</p></div>",
"created_at": "2026-10-08T10:47:13Z",
"number": 1,
"user_is_supporter": false,
"user_ip": null,
"user_agent": null,
"referrer": null,
"resolution": null,
"via": "web",
"internal": false,
"system_message": false,
"author_name": "Fatima Haddad",
"author_email": "fatima@harborpine.example.com",
"user_href": "https://api.tenderapp.com/yoursite/users/17",
"assets": [],
"html_href": "https://yoursite.tenderapp.com/discussions/problems/8"
},
{
"body": "Thanks Fatima. Could you tell us which browser you're using, and whether filtering the board to one column makes it faster?",
"formatted_body": "<div><p>Thanks Fatima. Could you tell us which browser you're using, and whether filtering the board to one column makes it faster?</p></div>",
"created_at": "2026-10-08T11:47:13Z",
"number": 3,
"user_is_supporter": true,
"user_ip": null,
"user_agent": null,
"referrer": null,
"resolution": null,
"via": "web",
"internal": false,
"system_message": false,
"author_name": "Daniel Reyes",
"author_email": "daniel@juniper.example.com",
"user_href": "https://api.tenderapp.com/yoursite/users/11",
"assets": [],
"html_href": "https://yoursite.tenderapp.com/discussions/problems/8"
}
],
"href": "https://api.tenderapp.com/yoursite/discussions/17",
"comments_href": "https://api.tenderapp.com/yoursite/discussions/17/comments{?page}"
}
The comments are in order, oldest first, 30 to a page, with internal notes and Tender's own notes ("Discussion was added to Bugs queue") among them. Ask for the next 30 with ?page=2; a page past the last has no comments field. Deleted comments aren't listed.
Comment fields
| Field | |
|---|---|
number |
The comment's place in the discussion: the first message is 1. |
body |
The text as it was written. |
formatted_body |
The text as HTML, as Tender shows it. |
author_name, author_email |
Who wrote it, with or without an account. |
user_href |
The author, when they have an account. |
user_is_supporter |
true if the author was on your support staff when they wrote it. |
internal |
true for an internal note, which customers never see. |
system_message |
true for a note Tender wrote itself when someone resolved, moved or queued the discussion. |
resolution |
true if this comment resolved the discussion. |
via |
How it came in: web (the website and the API), email and so on. |
user_ip, user_agent, referrer |
The author's IP address, browser and the page they came from, when Tender knows them. |
created_at |
When it was posted. |
assets |
Its attachments. |
html_href |
The discussion in Tender. |
Replying
POST /yoursite/discussions/{id}/comments
Send the reply as a JSON object. It's posted as you, and emailed to the customer and the discussion's other watchers:
curl -X POST \
-H "Accept: application/vnd.tender-v1+json" \
-H "Authorization: Bearer $TENDER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"body": "Thanks Priya. This is fixed in version 4.2: update the app and export again, and the custom field columns will be filled in.",
"resolution": true}' \
https://api.tenderapp.com/yoursite/discussions/21/comments
The answer is 201 Created with the discussion and its comments, the new one last:
{
"title": "Export to CSV leaves out custom fields",
"state": "resolved",
"comments": [
{
"body": "When I export a project to CSV, the custom field columns are empty.",
"number": 1,
"user_is_supporter": false,
"internal": false,
"author_name": "Priya Nair"
},
{
"body": "Thanks Priya. This is fixed in version 4.2: update the app and export again, and the custom field columns will be filled in.",
"formatted_body": "<div><p>Thanks Priya. This is fixed in version 4.2: update the app and export again, and the custom field columns will be filled in.</p></div>",
"created_at": "2026-10-09T07:17:25Z",
"number": 3,
"user_is_supporter": true,
"resolution": true,
"via": "web",
"internal": false,
"system_message": false,
"author_name": "Maya Okafor",
"author_email": "maya@juniper.example.com",
"user_href": "https://api.tenderapp.com/yoursite/users/10",
"assets": [],
"html_href": "https://yoursite.tenderapp.com/discussions/problems/10"
}
],
"href": "https://api.tenderapp.com/yoursite/discussions/21"
}
| Field | |
|---|---|
body |
Required. The reply. |
internal |
true: an internal note, which only your staff see and which nobody outside your team is emailed about. |
resolution |
true: resolve the discussion with this reply. |
skip_notifications |
true: post it without emailing anyone. |
skip_spam |
true: don't run the spam check on it. |
author_email, author_name |
Post it as someone else, such as the customer, when you're passing on a reply that reached you another way. Someone with an account on your site gets it under their account. |
user_ip, user_agent, referrer |
The author's IP address, browser and the page they came from, when you post from your own web form. The spam check uses them. |
Any reply that isn't an internal note opens a resolved discussion again, unless it has "resolution": true. An internal note leaves the discussion as it is.
Internal notes
An internal note is for your team: a customer's account details, what you found, who's looking at it.
curl -X POST \
-H "Accept: application/vnd.tender-v1+json" \
-H "Authorization: Bearer $TENDER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"body": "Priya is on the Business plan; custom fields export shipped in 4.2.",
"internal": true}' \
https://api.tenderapp.com/yoursite/discussions/21/comments
Only your support staff can write internal notes. A comment posted with author_email set to a customer's address is never internal, even with "internal": true, and skip_notifications only works for comments posted by your staff.
Errors
A reply that isn't valid gets 422 with the problems:
{"body": ["can't be blank"]}
An unknown discussion gets 404 with no body.
Attachments
Each comment lists its attached files in assets:
"assets": [
{
"filename": "export-log.txt",
"content_type": "text/plain",
"size": 18,
"width": null,
"height": null,
"via": "comment",
"parent_id": null,
"created_at": "2026-10-09T07:20:04Z",
"download_path": "https://..."
}
]
| Field | |
|---|---|
filename |
The file's name. |
content_type |
Its type, such as image/png or application/pdf. |
size |
Its size in bytes. |
width, height |
An image's size in pixels; null for other files. |
via |
Where it came from: comment for a file attached to a comment. |
download_path |
A link to download the file. It's signed and stops working after a day, so download the file when you need it rather than storing the link. |
created_at |
When it was uploaded. |
Right after a file is uploaded, while Tender is still processing it, download_path is /images/mime/attachment.png (a placeholder icon) instead of a link. Ask again a few seconds later.
Attaching files
To attach files to a reply, send it as a multipart/form-data form instead of JSON, with each file as uploaded_assets[] and 1 or 0 for true and false. With curl's -F:
curl -X POST \
-H "Accept: application/vnd.tender-v1+json" \
-H "Authorization: Bearer $TENDER_TOKEN" \
-F "body=Here is the export log." \
-F "internal=1" \
-F "uploaded_assets[]=@export-log.txt;type=text/plain" \
https://api.tenderapp.com/yoursite/discussions/22/comments
Creating a discussion takes files the same way.
