Comments

List, add and delete comments on Goals, Objectives, Meetings, Actions and Ideas.

Comments belong to a parent record: a Goal, Objective, Meeting, Action or Idea. Each parent has the same three operations.

Method Path Scope
GET /goals/{goalId}/comments comments:read
GET /objectives/{objectiveId}/comments comments:read
GET /meetings/{meetingId}/comments comments:read
GET /actions/{actionId}/comments comments:read
GET /ideas/{ideaId}/comments comments:read
POST /goals/{goalId}/comments comments:write
POST /objectives/{objectiveId}/comments comments:write
POST /meetings/{meetingId}/comments comments:write
POST /actions/{actionId}/comments comments:write
POST /ideas/{ideaId}/comments comments:write
DELETE /goals/{goalId}/comments/{commentId} comments:write
DELETE /objectives/{objectiveId}/comments/{commentId} comments:write
DELETE /meetings/{meetingId}/comments/{commentId} comments:write
DELETE /actions/{actionId}/comments/{commentId} comments:write
DELETE /comments/{id}?type=… comments:write

Comment changes don't fire webhooks.

The parent must exist in your organization and be visible to the API (not an archived Meeting, a hidden Idea, or an Action whose Goal or Objective is archived), or every comment endpoint for it returns 404.

The JavaScript examples assume a headers object holding your key:

JavaScript
const headers = {
  'X-API-Key': process.env.GPS_API_KEY_ID,
  'X-API-Secret': process.env.GPS_API_SECRET,
};

The comment object#

Comments on every kind of parent come back in the same shape.

Field Type Notes
id string Comment ID.
content string The comment text.
authorId string or null Member ID of the author.
createdAt string ISO 8601 timestamp.
updatedAt string ISO 8601 timestamp. For comments on Actions and Ideas this equals createdAt.

List comments#

GET /goals/{goalId}/comments GET /objectives/{objectiveId}/comments GET /meetings/{meetingId}/comments GET /actions/{actionId}/comments GET /ideas/{ideaId}/comments

Returns the parent's comments. Comments on Ideas come oldest first; for other parents order isn't guaranteed, so sort by createdAt.

Scope: comments:read

Parameter In Notes
goalId, objectiveId, meetingId, actionId or ideaId path The parent's ID.
limit, offset query See Pagination.
curl https://plan.empiraa.app/api/v1/goals/a1f3c5e7-2b4d-4f6a-8c9e-0b1d3f5a7c9e/comments -H "X-API-Key: $GPS_API_KEY_ID" -H "X-API-Secret: $GPS_API_SECRET"
curl https://plan.empiraa.app/api/v1/objectives/c7e9a1b3-4d5f-4a6b-9c8d-1e2f3a4b5c6d/comments -H "X-API-Key: $GPS_API_KEY_ID" -H "X-API-Secret: $GPS_API_SECRET"
curl https://plan.empiraa.app/api/v1/meetings/7a9c1e3f-5b6d-4e8a-8b9c-4d5e6f7a8b9c/comments -H "X-API-Key: $GPS_API_KEY_ID" -H "X-API-Secret: $GPS_API_SECRET"
curl https://plan.empiraa.app/api/v1/actions/e5a7c9e1-6f8b-4c2d-8e9f-3a4b5c6d7e8f/comments -H "X-API-Key: $GPS_API_KEY_ID" -H "X-API-Secret: $GPS_API_SECRET"
curl https://plan.empiraa.app/api/v1/ideas/2c4e6a8c-0d1f-4a3b-9c5d-6e7f8a9b0c1d/comments -H "X-API-Key: $GPS_API_KEY_ID" -H "X-API-Secret: $GPS_API_SECRET"

Response 200

JSON
{
  "data": [
    {
      "id": "8e0a2c4e-6f7b-4d9c-a1b2-7c8d9e0f1a2b",
      "content": "Renewals are tracking ahead of plan this month.",
      "authorId": "5d7f9b1d-3e5a-4c7e-9f1a-2b3c4d5e6f70",
      "createdAt": "2026-11-11T21:04:13.000Z",
      "updatedAt": "2026-11-11T21:04:13.000Z"
    }
  ],
  "meta": { "total": 1, "limit": 50, "offset": 0 }
}

Errors: 404 NOT_FOUND if the parent doesn't exist, is in another organization, or isn't visible to the API; 422 VALIDATION_ERROR for a bad limit or offset.

Add a comment#

POST /goals/{goalId}/comments POST /objectives/{objectiveId}/comments POST /meetings/{meetingId}/comments POST /actions/{actionId}/comments POST /ideas/{ideaId}/comments

Scope: comments:write

Path parameter Notes
goalId, objectiveId, meetingId, actionId or ideaId The parent's ID.

Request body for Goals, Objectives, Meetings and Actions

Field Type Required Allowed values Notes
content string Yes At least 1 character The comment text.
onBehalfOf string No Active member ID The author. Default: the key's creator. See Attribution.

Request body for Ideas: the text goes in body, not content.

Field Type Required Allowed values Notes
body string Yes 1–2,000 characters The comment text. Returned as content.
onBehalfOf string No Active member ID The author.
curl -X POST https://plan.empiraa.app/api/v1/goals/a1f3c5e7-2b4d-4f6a-8c9e-0b1d3f5a7c9e/comments \
  -H "X-API-Key: $GPS_API_KEY_ID" -H "X-API-Secret: $GPS_API_SECRET" -H "Content-Type: application/json" \
  -d '{ "content": "Renewals are tracking ahead of plan this month." }'

curl -X POST https://plan.empiraa.app/api/v1/objectives/c7e9a1b3-4d5f-4a6b-9c8d-1e2f3a4b5c6d/comments \
  -H "X-API-Key: $GPS_API_KEY_ID" -H "X-API-Secret: $GPS_API_SECRET" -H "Content-Type: application/json" \
  -d '{ "content": "October figures are in." }'

curl -X POST https://plan.empiraa.app/api/v1/meetings/7a9c1e3f-5b6d-4e8a-8b9c-4d5e6f7a8b9c/comments \
  -H "X-API-Key: $GPS_API_KEY_ID" -H "X-API-Secret: $GPS_API_SECRET" -H "Content-Type: application/json" \
  -d '{ "content": "Please add the churn report to the agenda." }'

curl -X POST https://plan.empiraa.app/api/v1/actions/e5a7c9e1-6f8b-4c2d-8e9f-3a4b5c6d7e8f/comments \
  -H "X-API-Key: $GPS_API_KEY_ID" -H "X-API-Secret: $GPS_API_SECRET" -H "Content-Type: application/json" \
  -d '{ "content": "Twelve offers sent so far.", "onBehalfOf": "6e8a0c2e-4f6b-4d8f-a0b1-3c4d5e6f7a81" }'

curl -X POST https://plan.empiraa.app/api/v1/ideas/2c4e6a8c-0d1f-4a3b-9c5d-6e7f8a9b0c1d/comments \
  -H "X-API-Key: $GPS_API_KEY_ID" -H "X-API-Secret: $GPS_API_SECRET" -H "Content-Type: application/json" \
  -d '{ "body": "We could start with the three largest clients." }'

Response 201

JSON
{
  "data": {
    "id": "8e0a2c4e-6f7b-4d9c-a1b2-7c8d9e0f1a2b",
    "content": "Renewals are tracking ahead of plan this month.",
    "authorId": "5d7f9b1d-3e5a-4c7e-9f1a-2b3c4d5e6f70",
    "createdAt": "2026-11-12T03:21:09.402Z",
    "updatedAt": "2026-11-12T03:21:09.402Z"
  }
}

Errors

Status code When
404 NOT_FOUND The parent doesn't exist, is in another organization, or isn't visible to the API.
422 VALIDATION_ERROR Missing or empty content (or body for Ideas), or an Idea comment over 2,000 characters.
422 INVALID_USERS onBehalfOf isn't an active member.
422 NO_KEY_OWNER No onBehalfOf, and the key's creator is no longer a member.

Delete a comment#

DELETE /goals/{goalId}/comments/{commentId} DELETE /objectives/{objectiveId}/comments/{commentId} DELETE /meetings/{meetingId}/comments/{commentId} DELETE /actions/{actionId}/comments/{commentId}

Permanently deletes a comment from the parent you name. A key with comments:write can delete any comment in the organization, not only ones it added. To delete a comment on an Idea, use Delete a comment by ID.

Scope: comments:write

Path parameter Notes
goalId, objectiveId, meetingId or actionId The parent's ID.
commentId The comment's ID. It must belong to that parent.
curl -X DELETE https://plan.empiraa.app/api/v1/goals/a1f3c5e7-2b4d-4f6a-8c9e-0b1d3f5a7c9e/comments/8e0a2c4e-6f7b-4d9c-a1b2-7c8d9e0f1a2b -H "X-API-Key: $GPS_API_KEY_ID" -H "X-API-Secret: $GPS_API_SECRET"
curl -X DELETE https://plan.empiraa.app/api/v1/objectives/c7e9a1b3-4d5f-4a6b-9c8d-1e2f3a4b5c6d/comments/8e0a2c4e-6f7b-4d9c-a1b2-7c8d9e0f1a2b -H "X-API-Key: $GPS_API_KEY_ID" -H "X-API-Secret: $GPS_API_SECRET"
curl -X DELETE https://plan.empiraa.app/api/v1/meetings/7a9c1e3f-5b6d-4e8a-8b9c-4d5e6f7a8b9c/comments/8e0a2c4e-6f7b-4d9c-a1b2-7c8d9e0f1a2b -H "X-API-Key: $GPS_API_KEY_ID" -H "X-API-Secret: $GPS_API_SECRET"
curl -X DELETE https://plan.empiraa.app/api/v1/actions/e5a7c9e1-6f8b-4c2d-8e9f-3a4b5c6d7e8f/comments/8e0a2c4e-6f7b-4d9c-a1b2-7c8d9e0f1a2b -H "X-API-Key: $GPS_API_KEY_ID" -H "X-API-Secret: $GPS_API_SECRET"

Response 204: no body.

Errors: 404 NOT_FOUND if the parent or the comment doesn't exist, the comment belongs to a different parent, or either is in another organization.

Delete a comment by ID#

DELETE /comments/{id}?type={type}

Deletes a comment when you know its ID and the kind of parent it's on. This is the only way to delete a comment on an Idea.

Scope: comments:write

Parameter In Required Allowed values
id path Yes The comment's ID.
type query Yes goal, objective, meeting, action, idea
curl -X DELETE "https://plan.empiraa.app/api/v1/comments/9f1b3d5f-7a8c-4e0d-b2c3-8d9e0f1a2b3c?type=idea" \
  -H "X-API-Key: $GPS_API_KEY_ID" \
  -H "X-API-Secret: $GPS_API_SECRET"

Response 204: no body.

Errors

Status code When
422 VALIDATION_ERROR type is missing or not one of the allowed values.
404 NOT_FOUND No comment of that type has this ID in your organization.