Guides
Conversations
Conversations allow you to exchange messages within the context of a specific payment. Each payment can have one conversation thread where parties can discuss details, share documents, and resolve queries.
Before you start
You will need:
- A valid API key to authenticate your requests.
- A payment
id— use the Payments API to create or retrieve one.
Getting a conversation
Retrieve the conversation for a payment. Returns an empty messages array if no conversation exists yet:
try {
const response = await fetch('https://api.nexpay.com/v2/payments/123/conversation', {
method: 'GET',
headers: {
'Authorization': 'ApiKey your-api-key-here',
},
});
if (response.ok) {
const data = await response.json();
console.log(data);
} else {
throw new Error(`Request failed with status: ${response.status}`);
}
} catch (error) {
console.error(error);
}
{
"id": 42,
"paymentId": 123,
"isClosed": false,
"isRead": true,
"messages": [
{
"userId": 300,
"isAdminResponse": false,
"subject": "Payment query",
"text": "Can you confirm the enrollment letter was received?",
"createdOn": "2026-03-15T09:00:00.000Z",
"userFullName": "Jane Doe",
"attachments": []
},
{
"userId": 1,
"isAdminResponse": true,
"text": "Yes, we have received all documents. Payment is being processed.",
"createdOn": "2026-03-15T10:30:00.000Z",
"userFullName": "Support Team",
"attachments": []
}
]
}
Sending a message
Send a message in the payment conversation. If no conversation exists, one is created automatically:
try {
const response = await fetch('https://api.nexpay.com/v2/payments/123/conversation/messages', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'ApiKey your-api-key-here',
},
body: JSON.stringify({
"subject": "Payment query",
"text": "Can you confirm the enrollment letter was received?",
"attachments": [
"f47ac10b-58cc-4372-a567-0e02b2c3d479"
]
}),
});
if (response.ok) {
const data = await response.json();
console.log(data);
} else {
throw new Error(`Request failed with status: ${response.status}`);
}
} catch (error) {
console.error(error);
}
Message fields
| Field | Type | Required | Description |
|---|---|---|---|
text | string | Yes | The message content. |
subject | string | No | Optional subject line for the message. |
attachments | string[] | No | Array of document UUIDs uploaded via the Documents API. |
Attachments
Attachments must be uploaded via POST /documents before being referenced in a message. See Uploading documents.
Checking for unread messages
Check if a payment's conversation has unread messages without fetching the full thread:
try {
const response = await fetch('https://api.nexpay.com/v2/payments/123/conversation/unread', {
method: 'GET',
headers: {
'Authorization': 'ApiKey your-api-key-here',
},
});
if (response.ok) {
const data = await response.json();
console.log(data); // { "hasUnread": true }
} else {
throw new Error(`Request failed with status: ${response.status}`);
}
} catch (error) {
console.error(error);
}
Downloading an attachment
Download a file attached to a conversation message:
try {
const response = await fetch('https://api.nexpay.com/v2/payments/123/conversation/attachments/f47ac10b-58cc-4372-a567-0e02b2c3d479', {
method: 'GET',
headers: {
'Authorization': 'ApiKey your-api-key-here',
},
});
if (response.ok) {
const blob = await response.blob();
console.log('Downloaded attachment:', blob.size, 'bytes');
} else {
throw new Error(`Request failed with status: ${response.status}`);
}
} catch (error) {
console.error(error);
}
Closing a conversation
Close a conversation when it's no longer needed:
try {
const response = await fetch('https://api.nexpay.com/v2/payments/123/conversation/close', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'ApiKey your-api-key-here',
},
body: JSON.stringify({}),
});
if (response.ok) {
console.log('Conversation closed');
} else {
throw new Error(`Request failed with status: ${response.status}`);
}
} catch (error) {
console.error(error);
}
Closed conversations
Once a conversation is closed, no new messages can be sent. Attempting to send a message to a closed conversation will return a [CNV0002] error.
Things to know
- Each payment can have at most one conversation.
- Conversations are created automatically when the first message is sent.
- The
isAdminResponsefield indicates whether a message was sent by the Nexpay admin team. - Attachment IDs are UUID v4 references to documents uploaded via the Documents API.
- Conversations are scoped to your tenant — they cannot be accessed across organizations.