Comments API

Add internal notes, external clarifications, and AI-generated comments to specific answers in questionnaire responses.

Comments & Answers

Each comment must be linked to either a text answer (answer_id) or file answer (file_answer_id). Comments support audit trails with edit and deletion tracking.

Comment Object

The comment object represents a note or clarification attached to an answer in a questionnaire response.

Attributes

Field Type Description
id uuid Unique identifier
text string Comment text content (encrypted at rest)
comment_type string Type of comment: internal, external, ai_reviewer_side
profile_name string Full name of the user who created the comment
profile_email string Email address of the user who created the comment
is_edited boolean Whether the comment has been edited after creation
edited_at datetime Timestamp of last edit (null if never edited)
created_at datetime Creation timestamp
updated_at datetime Last update timestamp

List Comments

Retrieve all comments for a specific answer with optional filtering by comment type.

GET /api/v1/comments/
GET /api/v2/comments/

Query Parameters

ParameterTypeRequiredDescription
answer_id uuid One required* Text answer ID to filter comments
file_answer_id uuid One required* File answer ID to filter comments
comment_type string No Filter by type: internal, external, ai_reviewer_side

* Either answer_id or file_answer_id must be provided

Query Parameters

ParameterTypeRequiredDescription
target_id uuid Yes UUID of the answer or file attachment to list comments for
target_type string Yes answer for text answers, attachment for file answers
comment_type string No Filter by type: internal, external, ai_reviewer_side

List Comments

curl -X GET 'https://api.kycgenie.com/api/v1/comments/?answer_id=123e4567-e89b-12d3-a456-426614174000' \
  -H 'Authorization: Bearer YOUR_API_KEY'
curl -X GET 'https://api.kycgenie.com/api/v2/comments/?target_id=123e4567-e89b-12d3-a456-426614174000&target_type=answer' \
  -H 'Authorization: Bearer YOUR_API_KEY'
const params = new URLSearchParams({
    answer_id: '123e4567-e89b-12d3-a456-426614174000',
    comment_type: 'internal'
});

const response = await fetch(`https://api.kycgenie.com/api/v1/comments/?${params}`, {
    headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
});

const data = await response.json();
console.log(`Found ${data.count} comments`);

data.comments.forEach((comment) => {
    console.log(`${comment.profile_name}: ${comment.text}`);
    if (comment.is_edited) {
        console.log(`  (Edited at ${comment.edited_at})`);
    }
});
const params = new URLSearchParams({
    target_id: '123e4567-e89b-12d3-a456-426614174000',
    target_type: 'answer',
    comment_type: 'internal'
});

const response = await fetch(`https://api.kycgenie.com/api/v2/comments/?${params}`, {
    headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
});

const data = await response.json();
console.log(`Found ${data.count} comments`);

data.results.forEach((comment) => {
    console.log(`${comment.profile_name}: ${comment.text}`);
    if (comment.is_edited) {
        console.log(`  (Edited at ${comment.edited_at})`);
    }
});
import requests

response = requests.get(
    'https://api.kycgenie.com/api/v1/comments/',
    headers={'Authorization': 'Bearer YOUR_API_KEY'},
    params={
        'answer_id': '123e4567-e89b-12d3-a456-426614174000',
        'comment_type': 'internal'
    }
)

data = response.json()
print(f"Found {data['count']} comments")

for comment in data['comments']:
    print(f"{comment['profile_name']}: {comment['text']}")
    if comment.is_edited:
        print(f"  (Edited at {comment.edited_at})")
from kycgenie import KYCGenie
import os

client = KYCGenie(api_key=os.getenv("KYCGENIE_API_KEY"))

comments = client.comments.list(
    target_id="123e4567-e89b-12d3-a456-426614174000",
    target_type="answer",
    comment_type="internal",
)

print(f"Found {comments.count} comments")
for comment in comments.results:
    print(f"{comment.profile_name}: {comment.text}")

Response Example

{
  "count": 2,
  "comments": [
    {
      "id": "123e4567-e89b-12d3-a456-426614174000",
      "text": "Verified against incorporation certificate",
      "comment_type": "internal",
      "profile_name": "John Reviewer",
      "profile_email": "john@example.com",
      "is_edited": false,
      "edited_at": null,
      "created_at": "2026-01-19T10:30:00Z",
      "updated_at": "2026-01-19T10:30:00Z"
    },
    {
      "id": "456e7890-e89b-12d3-a456-426614174001",
      "text": "Please provide more details about ownership",
      "comment_type": "external",
      "profile_name": "Sarah Smith",
      "profile_email": "sarah@example.com",
      "is_edited": true,
      "edited_at": "2026-01-19T14:00:00Z",
      "created_at": "2026-01-19T13:45:00Z",
      "updated_at": "2026-01-19T14:00:00Z"
    }
  ]
}
{
  "count": 2,
  "results": [
    {
      "id": "123e4567-e89b-12d3-a456-426614174000",
      "text": "Verified against incorporation certificate",
      "comment_type": "internal",
      "profile_name": "John Reviewer",
      "profile_email": "john@example.com",
      "is_edited": false,
      "edited_at": null,
      "created_at": "2026-01-19T10:30:00Z",
      "updated_at": "2026-01-19T10:30:00Z"
    },
    {
      "id": "456e7890-e89b-12d3-a456-426614174001",
      "text": "Please provide more details about ownership",
      "comment_type": "external",
      "profile_name": "Sarah Smith",
      "profile_email": "sarah@example.com",
      "is_edited": true,
      "edited_at": "2026-01-19T14:00:00Z",
      "created_at": "2026-01-19T13:45:00Z",
      "updated_at": "2026-01-19T14:00:00Z"
    }
  ]
}

Create Comment

Add a new comment to a text or file answer.

POST /api/v1/comments/
POST /api/v2/comments/

Request Body

FieldTypeRequiredDescription
answer_id uuid One required* Text answer ID
file_answer_id uuid One required* File answer ID
text string Yes Comment text content
comment_type string No Default: internal. Options: internal, external.

* Either answer_id or file_answer_id must be provided

Request Body

FieldTypeRequiredDescription
target_type string Yes answer for text answers, attachment for file answers
target_id uuid Yes UUID of the target answer or attachment
text string Yes Comment text content
comment_type string No Default: internal. Options: internal, external.

Create Comment

curl -X POST 'https://api.kycgenie.com/api/v1/comments/' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: comment-create-12345' \
  -d '{
    "answer_id": "123e4567-e89b-12d3-a456-426614174000",
    "text": "Requires additional verification of ownership",
    "comment_type": "internal"
  }'
curl -X POST 'https://api.kycgenie.com/api/v2/comments/' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: comment-create-12345' \
  -d '{
    "target_type": "answer",
    "target_id": "123e4567-e89b-12d3-a456-426614174000",
    "text": "Requires additional verification of ownership",
    "comment_type": "internal"
  }'
const response = await fetch('https://api.kycgenie.com/api/v1/comments/', {
    method: 'POST',
    headers: {
        'Authorization': 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json',
        'Idempotency-Key': 'comment-create-12345'
    },
    body: JSON.stringify({
        answer_id: '123e4567-e89b-12d3-a456-426614174000',
        text: 'Requires additional verification of ownership',
        comment_type: 'internal'
    })
});

const comment = await response.json();
console.log(`Created comment: ${comment.id}`);
const response = await fetch('https://api.kycgenie.com/api/v2/comments/', {
    method: 'POST',
    headers: {
        'Authorization': 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json',
        'Idempotency-Key': 'comment-create-12345'
    },
    body: JSON.stringify({
        target_type: 'answer',
        target_id: '123e4567-e89b-12d3-a456-426614174000',
        text: 'Requires additional verification of ownership',
        comment_type: 'internal'
    })
});

const comment = await response.json();
console.log(`Created comment: ${comment.id}`);
import requests

response = requests.post(
    'https://api.kycgenie.com/api/v1/comments/',
    headers={
        'Authorization': 'Bearer YOUR_API_KEY',
        'Idempotency-Key': 'comment-create-12345'
    },
    json={
        'answer_id': '123e4567-e89b-12d3-a456-426614174000',
        'text': 'Requires additional verification of ownership',
        'comment_type': 'internal'
    }
)

comment = response.json()
print(f"Created comment: {comment['id']}")
from kycgenie import KYCGenie
import os

client = KYCGenie(api_key=os.getenv("KYCGENIE_API_KEY"))

comment = client.comments.create(
    target_type="answer",
    target_id="123e4567-e89b-12d3-a456-426614174000",
    text="Requires additional verification of ownership",
    comment_type="internal",
)

print(f"Created comment: {comment.id}")

Response Example

{
  "id": "789e0123-e89b-12d3-a456-426614174002",
  "text": "Requires additional verification of ownership",
  "comment_type": "internal",
  "created_at": "2026-01-22T16:45:00Z"
}

Update Comment

Modify an existing comment. Updates automatically track edit history with is_edited and edited_at fields.

PATCH /api/v1/comments/{comment_id}/
PATCH /api/v2/comments/{comment_id}/

Path Parameters

ParameterTypeDescription
comment_id uuid ID of the comment to update

Request Body

FieldTypeRequiredDescription
text string Yes Updated comment text

Update Comment

curl -X PATCH 'https://api.kycgenie.com/api/v1/comments/789e0123-e89b-12d3-a456-426614174002/' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: comment-update-67890' \
  -d '{"text": "Updated: Ownership verified, documents match"}'
curl -X PATCH 'https://api.kycgenie.com/api/v2/comments/789e0123-e89b-12d3-a456-426614174002/' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: comment-update-67890' \
  -d '{"text": "Updated: Ownership verified, documents match"}'
const commentId = '789e0123-e89b-12d3-a456-426614174002';

const response = await fetch(`https://api.kycgenie.com/api/v1/comments/${commentId}/`, {
  method: 'PATCH',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
    'Idempotency-Key': 'comment-update-67890'
  },
  body: JSON.stringify({ text: 'Updated: Ownership verified, documents match' })
});

const comment = await response.json();
console.log(`Comment edited: ${comment.is_edited}`);
console.log(`Edited at: ${comment.edited_at}`);
const commentId = '789e0123-e89b-12d3-a456-426614174002';

const response = await fetch(`https://api.kycgenie.com/api/v2/comments/${commentId}/`, {
  method: 'PATCH',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
    'Idempotency-Key': 'comment-update-67890'
  },
  body: JSON.stringify({ text: 'Updated: Ownership verified, documents match' })
});

const comment = await response.json();
console.log(`Comment edited: ${comment.is_edited}`);
console.log(`Edited at: ${comment.edited_at}`);
import requests

comment_id = '789e0123-e89b-12d3-a456-426614174002'

response = requests.patch(
    f'https://api.kycgenie.com/api/v1/comments/{comment_id}/',
    headers={
        'Authorization': 'Bearer YOUR_API_KEY',
        'Idempotency-Key': 'comment-update-67890'
    },
    json={'text': 'Updated: Ownership verified, documents match'}
)

comment = response.json()
print(f"Comment edited: {comment.is_edited}")
print(f"Edited at: {comment.edited_at}")
from kycgenie import KYCGenie
import os

client = KYCGenie(api_key=os.getenv("KYCGENIE_API_KEY"))

comment = client.comments.update(
    comment_id="789e0123-e89b-12d3-a456-426614174002",
    text="Updated: Ownership verified, documents match",
)

print(f"Comment edited: {comment.is_edited}")
print(f"Edited at: {comment.edited_at}")

Response Example

{
  "id": "789e0123-e89b-12d3-a456-426614174002",
  "text": "Updated: Ownership verified, documents match",
  "is_edited": true,
  "edited_at": "2026-01-22T17:00:00Z",
  "updated_at": "2026-01-22T17:00:00Z"
}

Delete Comment

Delete a comment. The comment is permanently removed from the system.

DELETE /api/v1/comments/{comment_id}/
DELETE /api/v2/comments/{comment_id}/

Path Parameters

ParameterTypeDescription
comment_id uuid ID of the comment to delete

Response (204 No Content)

No response body is returned on successful deletion.

Delete Comment

curl -X DELETE 'https://api.kycgenie.com/api/v1/comments/789e0123-e89b-12d3-a456-426614174002/' \
  -H 'Authorization: Bearer YOUR_API_KEY'
curl -X DELETE 'https://api.kycgenie.com/api/v2/comments/789e0123-e89b-12d3-a456-426614174002/' \
  -H 'Authorization: Bearer YOUR_API_KEY'
const commentId = '789e0123-e89b-12d3-a456-426614174002';

const response = await fetch(`https://api.kycgenie.com/api/v1/comments/${commentId}/`, {
  method: 'DELETE',
  headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
});

if (response.status === 204) {
  console.log('Comment deleted successfully');
}
const commentId = '789e0123-e89b-12d3-a456-426614174002';

const response = await fetch(`https://api.kycgenie.com/api/v2/comments/${commentId}/`, {
  method: 'DELETE',
  headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
});

if (response.status === 204) {
  console.log('Comment deleted successfully');
}
import requests

comment_id = '789e0123-e89b-12d3-a456-426614174002'

response = requests.delete(
    f'https://api.kycgenie.com/api/v1/comments/{comment_id}/',
    headers={'Authorization': 'Bearer YOUR_API_KEY'}
)

if response.status_code == 204:
    print("Comment deleted successfully")
from kycgenie import KYCGenie
import os

client = KYCGenie(api_key=os.getenv("KYCGENIE_API_KEY"))

client.comments.delete(
    comment_id="789e0123-e89b-12d3-a456-426614174002",
)

print("Comment deleted successfully")

Comment Types

Different comment types control visibility and use cases within the platform.

TypeDescriptionVisibilityUse Case
internal Internal review notes Your team only Reviewer notes, internal discussion, flagged issues
external Clarification requests Entity and your team Questions for the responding entity, requests for additional information
ai_reviewer_side AI-generated reviewer notes Your team only AI-suggested concerns, auto-flagged discrepancies