POST /ideabank/proposals/{proposalId}/comments

Post a comment on a proposal on behalf of a panelist. Requires the canComment capability, which is only granted by the community_forum access level (see Get Idea Bank). Comment text is stripped of HTML and length-limited.

To read existing comments, use List Comments.

Request

POST /public/ideabank/proposals/{proposalId}/comments

Path Parameters

ParameterTypeDescription
proposalIdstringThe proposal identifier from the proposal listing

Headers

HeaderRequiredDescription
AuthorizationYesCompound idea-bank token from Tenant API
Content-TypeYesapplication/json

Request Body

FieldTypeRequiredDescription
textstringYesThe comment text. HTML is stripped; the result must be non-empty.
contactInfostringNoPanelist contact value, stored when the idea bank collects it
contactInfoLabelstringNoLabel identifying the kind of contact info (matches contactInfoCollection.label)
{
	"text": "Great idea, I would use this daily."
}

contactInfo is only stored when both contactInfo and contactInfoLabel are supplied.

Response

{
	"commentId": "c-abc123",
	"text": "Great idea, I would use this daily.",
	"tsCreated": 1700000000
}

Response Fields

FieldTypeDescription
commentIdstringUnique identifier of the created comment
textstringThe stored comment text (HTML stripped)
tsCreatedintegerUnix timestamp (seconds) when the comment was posted

Examples

cURL

curl -X POST \
  "https://api.votito.com/public/ideabank/proposals/p-abc123/comments" \
  -H "Authorization: abc123:xyz789:ses456" \
  -H "Content-Type: application/json" \
  -d '{"text":"Great idea, I would use this daily."}'

JavaScript

const addComment = async (publicKey, proposalId, text) => {
	const response = await fetch(`https://api.votito.com/public/ideabank/proposals/${proposalId}/comments`, {
		method: 'POST',
		headers: {
			'Authorization': publicKey,
			'Content-Type': 'application/json'
		},
		body: JSON.stringify({ text })
	});

	if (!response.ok) {
		throw new Error(`Failed to add comment: ${response.status}`);
	}

	return response.json();
};

// Usage
const comment = await addComment(publicKey, 'p-abc123', 'Great idea!');
console.log(`Created comment ${comment.commentId}`);

Python

import requests

def add_comment(public_key, proposal_id, text, contact_info=None, contact_info_label=None):
    body = {"text": text}
    if contact_info and contact_info_label:
        body["contactInfo"] = contact_info
        body["contactInfoLabel"] = contact_info_label
    response = requests.post(
        f"https://api.votito.com/public/ideabank/proposals/{proposal_id}/comments",
        headers={
            "Authorization": public_key,
            "Content-Type": "application/json"
        },
        json=body
    )
    response.raise_for_status()
    return response.json()

# Usage
comment = add_comment(public_key, "p-abc123", "Great idea!")
print(comment["commentId"])

Error Handling

StatusErrorDescription
400field-requiredtext is missing or empty after HTML is stripped
400text-exceeds-maximum-lengthtext is longer than the allowed maximum. details.maxLength gives the limit.
401UnauthorizedMissing or invalid token
403ForbiddenToken expired, or the panelist cannot comment
404idea-bank-not-foundComments not enabled, proposal not open, or idea bank not accessible
429resource-busyServer is busy. Retry after a short delay.

Notes