Skip to main content

Your First Transaction

This tutorial walks you through creating a complete notarization transaction from start to finish. By the end, you'll have created users, uploaded documents, and activated a transaction ready for notarization.

What You'll Build

Authenticate with the API
Create user accounts for participants
Create a transaction
Upload documents
Set transaction metadata (optional)
Activate the transaction

Time to complete: ~30 minutes

Prerequisites

Before starting, ensure you have:

  • API credentials (Partner ID, API Key, API Secret)
  • Department ID
  • Workflow ID
  • At least one PDF document to test with

Complete Workflow

Step-by-Step Implementation

Step 1: Authenticate

First, exchange your credentials for a JWT token.

const axios = require('axios');

const BASE_URL = '{BASE_URL}';

// Step 1: Authenticate
async function authenticate() {
console.log('Step 1: Authenticating...');

const response = await axios.post(
`${BASE_URL}/api/v4/authorize/`,
{
partnerId: process.env.NOTARYCAM_PARTNER_ID,
apiKey: process.env.NOTARYCAM_API_KEY,
apiSecret: process.env.NOTARYCAM_API_SECRET
},
{
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}
);

console.log(' Authenticated successfully');
return response.data.token;
}

const token = await authenticate();
Save Your Token

Store the token for use in all subsequent requests. It's valid for 24 hours.

Step 2: Create Users

Create user accounts for all participants in your transaction. In this example, we'll create two signers.

// Step 2: Create Users
async function createParticipants(token) {
console.log('Step 2: Creating users...');

// Create first signer
const user1Response = await axios.post(
`${BASE_URL}/api/v4/users`,
{
departments: [process.env.NOTARYCAM_DEPARTMENT_ID],
email: 'john.doe@example.com',
firstName: 'John',
lastName: 'Doe',
phone: '+15551234567',
dateOfBirth: '1985-06-15T00:00:00.000Z',
address: {
country: 'US',
street: '123 Main Street',
city: 'San Francisco',
state: 'CA',
postalCode: '94102'
}
},
{
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
}
);

const user1Id = user1Response.data.user._id;
console.log(` Created user 1: ${user1Id}`);

// Create second signer
const user2Response = await axios.post(
`${BASE_URL}/api/v4/users`,
{
departments: [process.env.NOTARYCAM_DEPARTMENT_ID],
email: 'jane.smith@example.com',
firstName: 'Jane',
lastName: 'Smith',
phone: '+15559876543',
dateOfBirth: '1990-03-22T00:00:00.000Z',
address: {
country: 'US',
street: '456 Oak Avenue',
city: 'Austin',
state: 'TX',
postalCode: '78701'
}
},
{
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
}
);

const user2Id = user2Response.data.user._id;
console.log(` Created user 2: ${user2Id}`);

return [user1Id, user2Id];
}

const [user1Id, user2Id] = await createParticipants(token);
Participant Roles

Common roles include: signer, notary, witness, observer, preparer, submitter, credible-witness. See User Roles for details.

Step 3: Create Transaction

Now create the transaction and assign participants with their roles.

// Step 3: Create Transaction
async function createTransaction(token, user1Id, user2Id) {
console.log('Step 3: Creating transaction...');

const response = await axios.post(
`${BASE_URL}/api/v4/transactions/`,
{
department: process.env.NOTARYCAM_DEPARTMENT_ID, // Required
participants: [
{ user: user1Id, role: 'signer' },
{ user: user2Id, role: 'signer' }
],
workflow: process.env.NOTARYCAM_WORKFLOW_ID // Optional - auto-assigned if not provided
},
{
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
}
);

const transactionId = response.data.transaction._id;
console.log(` Transaction created: ${transactionId}`);

// Save participant room URLs
response.data.transaction.participants.forEach((p, i) => {
console.log(` Participant ${i + 1} room: ${p.roomURL}`);
});

return transactionId;
}

const transactionId = await createTransaction(token, user1Id, user2Id);

Important: Save the participant roomURL values - participants will use these to join the notarization session.

Step 4: Upload Documents

Upload documents using multipart form data. The request requires two form fields: the file(s) and a documentData JSON field that maps each file to its document type.

const FormData = require('form-data');
const fs = require('fs');

// Step 4: Upload Documents
async function uploadDocuments(token, transactionId) {
console.log('Step 4: Uploading documents...');

const form = new FormData();

// Attach the file
form.append('documents', fs.createReadStream('./sample-document.pdf'));

// Attach document metadata (must match filenames)
form.append('documentData', JSON.stringify([
{ fileName: 'sample-document.pdf', type: 'notarize' }
]));

const response = await axios.post(
`${BASE_URL}/api/v4/transactions/${transactionId}/documents`,
form,
{
headers: {
'Authorization': `Bearer ${token}`,
...form.getHeaders()
}
}
);

console.log(` Uploaded ${response.data.documentsReceived} document(s)`);
}

await uploadDocuments(token, transactionId);

Document Types:

  • notarize - Requires notarization
  • sign - Signature only
  • support - Supporting document (no signature)
  • other - Other document type

Step 5: Set Metadata (Optional)

Add custom metadata for tracking and reporting. This step is optional but recommended.

// Step 5: Set Metadata (Optional)
async function setMetadata(token, transactionId) {
console.log('Step 5: Setting metadata...');

const response = await axios.put(
`${BASE_URL}/api/v4/transactions/${transactionId}/metadata`,
{
notes: ['First API transaction', 'Test integration'],
customFields: [
{ name: 'Project', value: 'API Integration' },
{ name: 'Environment', value: 'Development' }
],
realEstate: {
loanNumber: 'TEST-123456',
transactionType: 'refinance',
propertyAddress: {
street: '789 Property Lane',
city: 'Seattle',
state: 'WA',
postalCode: '98101',
country: 'US'
}
}
},
{
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
}
);

console.log(' Metadata set successfully');
}

await setMetadata(token, transactionId);

Step 6: Activate Transaction

The final step! This triggers notifications and makes the transaction available to participants.

// Step 6: Activate Transaction
async function activateTransaction(token, transactionId) {
console.log('Step 6: Activating transaction...');

const response = await axios.put(
`${BASE_URL}/api/v4/transactions/${transactionId}/activate`,
{},
{
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
}
);

console.log(' Transaction activated!');
console.log('\n Success! Your transaction is now active.');
}

await activateTransaction(token, transactionId);

What Happens Next?

After activation:

  1. ** Notifications Sent** - Participants receive emails with their room URLs
  2. ** Session Scheduled** - Transaction becomes available for the notarization session
  3. ** Webhooks Triggered** - You receive webhook events for status changes
  4. ** Participants Join** - Users can access their room URLs to join the session

Complete Example

Here's the entire workflow in one script:

const axios = require('axios');
require('dotenv').config();

const BASE_URL = '{BASE_URL}';

async function createFirstTransaction() {
try {
// Step 1: Authenticate
console.log('Step 1: Authenticating...');
const authResponse = await axios.post(
`${BASE_URL}/api/v4/authorize/`,
{
partnerId: process.env.NOTARYCAM_PARTNER_ID,
apiKey: process.env.NOTARYCAM_API_KEY,
apiSecret: process.env.NOTARYCAM_API_SECRET
},
{ headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }
);
const token = authResponse.data.token;
console.log(' Authenticated\n');

// Step 2: Create Users
console.log('Step 2: Creating users...');
const headers = {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
};

const user1 = await axios.post(`${BASE_URL}/api/v4/users`, {
departments: [process.env.NOTARYCAM_DEPARTMENT_ID],
email: 'john.doe@example.com',
firstName: 'John',
lastName: 'Doe',
phone: '+15551234567',
dateOfBirth: '1985-06-15T00:00:00.000Z',
address: {
country: 'US',
street: '123 Main St',
city: 'San Francisco',
state: 'CA',
postalCode: '94102'
}
}, { headers });

const user2 = await axios.post(`${BASE_URL}/api/v4/users`, {
departments: [process.env.NOTARYCAM_DEPARTMENT_ID],
email: 'jane.smith@example.com',
firstName: 'Jane',
lastName: 'Smith',
phone: '+15559876543',
dateOfBirth: '1990-03-22T00:00:00.000Z',
address: {
country: 'US',
street: '456 Oak Ave',
city: 'Austin',
state: 'TX',
postalCode: '78701'
}
}, { headers });

console.log(` Created users\n`);

// Step 3: Create Transaction
console.log('Step 3: Creating transaction...');
const transaction = await axios.post(`${BASE_URL}/api/v4/transactions/`, {
department: process.env.NOTARYCAM_DEPARTMENT_ID, // Required
participants: [
{ user: user1.data.user._id, role: 'signer' },
{ user: user2.data.user._id, role: 'signer' }
],
workflow: process.env.NOTARYCAM_WORKFLOW_ID
}, { headers });

const transactionId = transaction.data.transaction._id;
console.log(` Transaction created: ${transactionId}\n`);

// Step 4: Upload Documents
console.log('Step 4: Uploading documents...');
const FormData = require('form-data');
const fs = require('fs');
const form = new FormData();
form.append('documents', fs.createReadStream('./sample.pdf'));
form.append('documentData', JSON.stringify([
{ fileName: 'sample.pdf', type: 'notarize' }
]));
await axios.post(
`${BASE_URL}/api/v4/transactions/${transactionId}/documents`,
form,
{ headers: { ...headers, ...form.getHeaders() } }
);
console.log(' Documents uploaded\n');

// Step 5: Set Metadata (Optional)
console.log('Step 5: Setting metadata...');
await axios.put(
`${BASE_URL}/api/v4/transactions/${transactionId}/metadata`,
{
notes: ['First API transaction'],
customFields: [{ name: 'Source', value: 'API Tutorial' }]
},
{ headers }
);
console.log(' Metadata set\n');

// Step 6: Activate
console.log('Step 6: Activating transaction...');
await axios.put(
`${BASE_URL}/api/v4/transactions/${transactionId}/activate`,
{},
{ headers }
);
console.log(' Transaction activated\n');

console.log(' Complete! Transaction ID:', transactionId);
console.log('\nParticipant Room URLs:');
transaction.data.transaction.participants.forEach((p, i) => {
console.log(` ${i + 1}. ${p.user.email}: ${p.roomURL}`);
});

} catch (error) {
console.error(' Error:', error.response?.data || error.message);
process.exit(1);
}
}

// Run it
createFirstTransaction();

Troubleshooting

Common Issues

"Invalid credentials" error?

  • Verify your environment variables are set correctly
  • Check you're using the right base URL (sandbox vs production)
  • Ensure API keys haven't expired

Documents not uploading?

  • Verify the document URL is publicly accessible
  • Check the file is a PDF
  • Ensure file size is under 25MB

Transaction won't activate?

  • Ensure at least one document is uploaded
  • Verify all required participants are added
  • Check that workflow ID is valid

Next Steps

Congratulations! You've created your first NotaryCam transaction. Now explore:

Need Help?