Webhook Event Types
Complete reference for all NotaryCam webhook events.
Event Summary
| Event | Description |
|---|---|
transaction-status-update | Transaction status changed |
documents-processed | Documents uploaded via API finished processing |
tagging-started | Document tagging began in the session |
recording-available | Session recording finished processing |
auto-assigned-notary | A notary was auto-assigned to the transaction |
transaction-status-update
Fired when a transaction's status changes.
Possible status Values:
| Status | Description |
|---|---|
in-progress | The notarization session is underway |
complete | The notarization session completed successfully |
cancelled | The transaction was cancelled |
Payload Fields:
| Field | Type | Description |
|---|---|---|
transactionId | string | ID of the transaction |
status | string | New transaction status (see values above) |
type | string | Type of status change (optional) |
reason | string | Reason for status change (optional, typically for cancellations) |
comment | string | Additional context or notes (optional) |
Payload Example (Complete):
{
"event": "transaction-status-update",
"departmentId": "dept_abc123",
"data": {
"transactionId": "txn_abc123def456",
"status": "complete"
}
}
Payload Example (Cancelled with Details):
{
"event": "transaction-status-update",
"departmentId": "dept_abc123",
"data": {
"transactionId": "txn_abc123def456",
"status": "cancelled",
"type": "user-cancelled",
"reason": "Customer requested cancellation",
"comment": "Cancelled by admin user on behalf of customer"
}
}
When to Use:
- Update transaction status in your database
- Trigger business logic based on status changes
- Notify relevant users of status transitions
- Update your UI in real-time
Handler Example:
async function handleStatusUpdate(event) {
const { transactionId, status, type, reason, comment } = event.data;
switch (status) {
case 'in-progress':
await db.transactions.update(
{ notaryCamId: transactionId },
{ status: 'In Progress', startedAt: new Date() }
);
break;
case 'complete':
await db.transactions.update(
{ notaryCamId: transactionId },
{ status: 'Completed', completedAt: new Date() }
);
// Trigger post-completion workflows
await sendCompletionEmail(transactionId);
break;
case 'cancelled':
await db.transactions.update(
{ notaryCamId: transactionId },
{
status: 'Cancelled',
cancelledAt: new Date(),
cancellationType: type,
cancellationReason: reason,
cancellationComment: comment
}
);
// Log cancellation details if provided
if (reason) {
await logCancellation(transactionId, reason, comment);
}
break;
}
}
documents-processed
Fired when documents uploaded via the API finish processing (success or failure).
Payload Example (Success):
{
"event": "documents-processed",
"departmentId": "dept_abc123",
"data": {
"success": true,
"transactionId": "txn_abc123def456",
"processedCount": 2,
"processedDocuments": [
{
"documentId": "doc_123",
"originalName": "contract.pdf"
},
{
"documentId": "doc_456",
"originalName": "addendum.pdf"
}
],
"erroredCount": 0,
"erroredDocuments": []
}
}
Payload Example (Failure):
{
"event": "documents-processed",
"departmentId": "dept_abc123",
"data": {
"success": false,
"transactionId": "txn_abc123def456",
"erroredCount": 1,
"erroredDocuments": [
{
"type": "notarize",
"originalName": "corrupted-file.pdf"
}
]
}
}
When to Use:
- Verify documents were processed successfully after upload
- Handle processing failures and retry or alert users
- Update document status in your system
Handler Example:
async function handleDocumentsProcessed(event) {
const { success, transactionId, processedDocuments, erroredDocuments } = event.data;
if (success) {
for (const doc of processedDocuments) {
await db.documents.update(
{ documentId: doc.documentId },
{ status: 'ready', originalName: doc.originalName }
);
}
}
if (erroredDocuments?.length > 0) {
for (const doc of erroredDocuments) {
console.error(`Document failed: ${doc.originalName}`);
await notifyDocumentFailure(transactionId, doc);
}
}
}
tagging-started
Fired when document tagging (placing signature fields, stamps, etc.) begins during the notarization session.
Payload Example:
{
"event": "tagging-started",
"departmentId": "dept_abc123",
"data": {
"transactionId": "txn_abc123def456"
}
}
When to Use:
- Track session progress
- Update your UI to show the session has entered the tagging phase
- Log session milestones for analytics
Handler Example:
async function handleTaggingStarted(event) {
const { transactionId } = event.data;
await db.transactions.update(
{ notaryCamId: transactionId },
{ taggingStartedAt: new Date(), sessionPhase: 'tagging' }
);
}
recording-available
Fired when a session recording has finished processing and is available.
Payload Example:
{
"event": "recording-available",
"departmentId": "dept_abc123",
"data": {
"transactionId": "txn_abc123def456",
"recordingId": "rec_xyz789"
}
}
When to Use:
- Download and archive the session recording
- Notify participants of recording availability
- Update compliance records
Handler Example:
async function handleRecordingAvailable(event) {
const { transactionId, recordingId } = event.data;
await db.transactions.update(
{ notaryCamId: transactionId },
{ recordingId, recordingStatus: 'available' }
);
// Notify stakeholders
await sendRecordingNotification(transactionId, recordingId);
}
auto-assigned-notary
Fired when a notary is automatically assigned to a transaction.
Payload Fields:
| Field | Type | Description |
|---|---|---|
transactionId | string | ID of the transaction |
participants | array | Array of assigned notary participant objects |
participants[].name | string | Full name of the assigned notary |
participants[].email | string | Email address of the assigned notary |
participants[].phone | string | Phone number of the assigned notary |
scheduleDateTime | string | Scheduled date/time for the session (if scheduled) |
fileNumber | string | File number associated with the transaction |
Payload Example:
{
"event": "auto-assigned-notary",
"transactionId": "txn_abc4d56b72c19ef",
"participants": [
{
"name": "Jordan First",
"email": "jordan.first@testmail.com",
"phone": "6175500000"
}
],
"scheduleDateTime": "2026-03-05T14:00:00-05:00",
"fileNumber": "FILE-93000"
}
When to Use:
- Track when a notary has been assigned
- Update your UI to reflect assignment status
- Notify relevant parties of the notary assignment
- Store notary contact information for reference
- Trigger any pre-session preparation workflows
Handler Example:
async function handleAutoAssignedNotary(event) {
const { transactionId, participants, scheduleDateTime, fileNumber } = event;
// Extract notary information
const notary = participants[0]; // First participant is the assigned notary
// Validate and parse schedule date
const isValidDate = scheduleDateTime && !scheduleDateTime.includes('Invalid');
const parsedDate = isValidDate ? new Date(scheduleDateTime) : null;
await db.transactions.update(
{ notaryCamId: transactionId },
{
notaryAssigned: true,
assignedAt: new Date(),
notaryName: notary.name,
notaryEmail: notary.email,
notaryPhone: notary.phone,
scheduleDateTime: parsedDate,
fileNumber: fileNumber
}
);
// Send notification to relevant parties
await notifyParticipants(transactionId, {
message: `Notary ${notary.name} has been assigned to your transaction.`,
notaryContact: notary.email,
scheduledFor: parsedDate ? parsedDate.toLocaleString() : 'Not scheduled'
});
console.log(`Notary ${notary.name} assigned to transaction ${transactionId}`);
}
Event Handling Patterns
Complete Router
async function handleWebhookEvent(event) {
switch (event.event) {
case 'transaction-status-update':
return handleStatusUpdate(event);
case 'documents-processed':
return handleDocumentsProcessed(event);
case 'tagging-started':
return handleTaggingStarted(event);
case 'recording-available':
return handleRecordingAvailable(event);
case 'auto-assigned-notary':
return handleAutoAssignedNotary(event);
default:
console.log('Unhandled event:', event.event);
return { handled: false };
}
}
Testing Events
Simulate Webhooks Locally
// Send test events to your webhook endpoint
const testEvents = [
{
event: 'transaction-status-update',
departmentId: 'test_dept',
data: { transactionId: 'test_txn_123', status: 'in-progress' }
},
{
event: 'documents-processed',
departmentId: 'test_dept',
data: {
success: true,
transactionId: 'test_txn_123',
processedCount: 1,
processedDocuments: [{ documentId: 'doc_1', originalName: 'test.pdf' }],
erroredCount: 0,
erroredDocuments: []
}
},
{
event: 'recording-available',
departmentId: 'test_dept',
data: { transactionId: 'test_txn_123', recordingId: 'rec_test_1' }
}
];
for (const event of testEvents) {
await axios.post('http://localhost:3000/webhooks/notarycam', event);
}
Next Steps
- Webhook Overview - Setup and configuration