Response Notes API

Add internal notes to responses during review and approval workflows. Track decision rationale and compliance documentation.

Response Notes vs Comments

Response Notes are attached to the entire response (for audit trail and review documentation). Comments are attached to specific answers (for question-level feedback).

Notes do not change response status

The status_transition field on a note is an audit label only — it records which status was in effect when the note was created. It does not trigger a status change. To approve, reject, or request changes programmatically, use the dedicated review action endpoints on the Responses page.

Response Note Object

The response note object represents an internal note attached to a response, typically used for approval decisions and workflow documentation.

Attributes

Field Type Description
id uuid Unique identifier for the note
text string Note text content (encrypted at rest)
status_transition string | null Audit label recording the response status when this note was created. Set automatically by the system when a status-change action (approve, reject, request changes) generates a note. Does not affect questionnaire_response.status.
profile_name string Name of the user who created the note
profile_email string Email of the user who created the note
created_at datetime ISO 8601 timestamp of when the note was created

List Response Notes

Retrieve all notes for a specific response.

GET /api/v1/responses/{response_id}/notes/

Path Parameters

ParameterTypeDescription
response_id uuid ID of the response

Headers

HeaderTypeRequiredDescription
Authorization string Yes Bearer token: Bearer YOUR_API_KEY

List Response Notes

curl -X GET 'https://api.kycgenie.com/api/v1/responses/550e8400-e29b-41d4-a716-446655440000/notes/' \
  -H 'Authorization: Bearer YOUR_API_KEY'
import requests

response_id = '550e8400-e29b-41d4-a716-446655440000'

response = requests.get(
    f'https://api.kycgenie.com/api/v1/responses/{response_id}/notes/',
    headers={'Authorization': 'Bearer YOUR_API_KEY'}
)

notes_data = response.json()
print(f"Response: {notes_data['response_name']}")
print(f"Status: {notes_data['response_status']}")
print(f"Notes: {notes_data['count']}")

for note in notes_data['notes']:
    print(f"\n{note['profile_name']} ({note['created_at']}):")
    print(f"  {note['text']}")
    if note['status_transition']:
        print(f"  Status transition: {note['status_transition']}")
const responseId = '550e8400-e29b-41d4-a716-446655440000';

const response = await fetch(
  `https://api.kycgenie.com/api/v1/responses/${responseId}/notes/`,
  {
    method: 'GET',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY'
    }
  }
);

const notesData = await response.json();
console.log(`Response: ${notesData.response_name}`);
console.log(`Status: ${notesData.response_status}`);
console.log(`Notes: ${notesData.count}`);

Response Example

{
    "response_id": "550e8400-e29b-41d4-a716-446655440000",
    "response_name": "ACME Corporation - Vendor DDQ 2026",
    "response_status": "APPROVED",
    "count": 2,
    "notes": [
        {
            "id": "8d4e2f1a-3b5c-4d6e-9f0a-1b2c3d4e5f60",
            "text": "All documentation verified. Screening passed with no matches.",
            "status_transition": "APPROVED",
            "profile_name": "Jane Smith",
            "profile_email": "jane@example.com",
            "created_at": "2026-01-19T14:30:00Z"
        },
        {
            "id": "3a1b2c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
            "text": "Initial review complete. Minor clarification needed on Q15.",
            "status_transition": null,
            "profile_name": "John Doe",
            "profile_email": "john@example.com",
            "created_at": "2026-01-19T10:30:00Z"
        }
    ]
}

Create Response Note

Add an internal note to a response for audit trail and review documentation. Notes do not affect response status.

POST /api/v1/responses/{response_id}/notes/

Path Parameters

ParameterTypeDescription
response_id uuid ID of the response

Headers

HeaderTypeRequiredDescription
Authorization string Yes Bearer token: Bearer YOUR_API_KEY
Idempotency-Key string Recommended Unique key to prevent duplicate note creation. Retrying with the same key returns the original note.

Request Body

Field Type Required Description
text string Yes Note text (encrypted at rest)
status_transition string No Optional audit label to tag this note with a status context. Metadata only — does not change response status. To change status, use the dedicated review action endpoints. Values: APPROVED, REJECTED, CHANGES_REQUESTED.

Status Transition Label Values

These are audit labels only. They record context — they do not change the response status.

Value Meaning When Set
APPROVED Note was created in the context of an approval Automatically set when the system creates a note during an approve action
REJECTED Note was created in the context of a rejection Automatically set when the system creates a note during a reject action
CHANGES_REQUESTED Note was created in the context of a changes-requested action Automatically set when the system creates a note during a request-changes action
null No status context General review note not associated with a status-change action

Response

{
  "id": "7f8e9d0c-1b2a-3c4d-5e6f-7a8b9c0d1e2f",
  "text": "Verified incorporation certificate matches company registry",
  "status_transition": null,
  "created_at": "2026-01-19T16:45:00Z"
}

Create Response Note

curl -X POST 'https://api.kycgenie.com/api/v1/responses/550e8400-e29b-41d4-a716-446655440000/notes/' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: note-create-12345' \
  -d '{
    "text": "Verified incorporation certificate matches company registry"
  }'
import requests

response_id = '550e8400-e29b-41d4-a716-446655440000'

response = requests.post(
    f'https://api.kycgenie.com/api/v1/responses/{response_id}/notes/',
    headers={
        'Authorization': 'Bearer YOUR_API_KEY',
        'Idempotency-Key': 'note-create-12345'
    },
    json={
        'text': 'Verified incorporation certificate matches company registry'
    }
)

note = response.json()
print(f"Created note: {note['id']}")
const responseId = '550e8400-e29b-41d4-a716-446655440000';

const response = await fetch(
  `https://api.kycgenie.com/api/v1/responses/${responseId}/notes/`,
  {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json',
      'Idempotency-Key': 'note-create-12345'
    },
    body: JSON.stringify({
      text: 'Verified incorporation certificate matches company registry'
    })
  }
);

const note = await response.json();
console.log(`Created note: ${note.id}`);
curl -X POST 'https://api.kycgenie.com/api/v1/responses/550e8400-e29b-41d4-a716-446655440000/notes/' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: note-approval-67890' \
  -d '{
    "text": "All checks passed. Approved for onboarding.",
    "status_transition": "APPROVED"
  }'
import requests

response_id = '550e8400-e29b-41d4-a716-446655440000'

response = requests.post(
    f'https://api.kycgenie.com/api/v1/responses/{response_id}/notes/',
    headers={
        'Authorization': 'Bearer YOUR_API_KEY',
        'Idempotency-Key': 'note-approval-67890'
    },
    json={
        'text': 'All checks passed. Approved for onboarding.',
        'status_transition': 'APPROVED'
    }
)

note = response.json()
print(f"Created note (status label: APPROVED): {note['id']}")
# Note: this does NOT change questionnaire_response.status.
# To approve the response use: POST /responses/{response_id}/approve/
const responseId = '550e8400-e29b-41d4-a716-446655440000';

const response = await fetch(
  `https://api.kycgenie.com/api/v1/responses/${responseId}/notes/`,
  {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json',
      'Idempotency-Key': 'note-approval-67890'
    },
    body: JSON.stringify({
      text: 'All checks passed. Approved for onboarding.',
      status_transition: 'APPROVED'
    })
  }
);

const note = await response.json();
console.log(`Created note (status label: APPROVED): ${note.id}`);
// Note: this does NOT change questionnaire_response.status.
// To approve the response use: POST /responses/{response_id}/approve/

Delete Response Note

Delete a response note. This action is logged in the audit trail for compliance.

DELETE /api/v1/responses/{response_id}/notes/{note_id}/

Path Parameters

ParameterTypeDescription
response_id uuid ID of the response
note_id uuid ID of the note to delete

Headers

HeaderTypeRequiredDescription
Authorization string Yes Bearer token: Bearer YOUR_API_KEY

Response

Returns 204 No Content on success.

Audit Trail

Note deletions are logged in the audit trail for compliance. Consider marking notes as outdated rather than deleting them if you need a complete history.

Delete Response Note

curl -X DELETE 'https://api.kycgenie.com/api/v1/responses/550e8400-e29b-41d4-a716-446655440000/notes/8d4e2f1a-3b5c-4d6e-9f0a-1b2c3d4e5f60/' \
  -H 'Authorization: Bearer YOUR_API_KEY'
import requests

response_id = '550e8400-e29b-41d4-a716-446655440000'
note_id = '8d4e2f1a-3b5c-4d6e-9f0a-1b2c3d4e5f60'

response = requests.delete(
    f'https://api.kycgenie.com/api/v1/responses/{response_id}/notes/{note_id}/',
    headers={'Authorization': 'Bearer YOUR_API_KEY'}
)

# Returns 204 No Content on success
print(f"Status: {response.status_code}")
const responseId = '550e8400-e29b-41d4-a716-446655440000';
const noteId = '8d4e2f1a-3b5c-4d6e-9f0a-1b2c3d4e5f60';

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

// Returns 204 No Content on success
console.log(`Status: ${response.status}`);