Automating Your Video Workflow with the Snapencode API
Learn how to build a fully automated video pipeline, from upload to processing and delivery, using the Snapencode client-facing API and a simple Node.js script.

In today’s content-driven world, manual video uploading and processing can be a significant bottleneck, slowing down your entire content pipeline. The true power of a platform like Snapencode lies in its API-first design, which allows you to automate these repetitive tasks and reclaim valuable time.
In this tutorial, we’ll build a practical “watch folder” script that monitors a directory for new video files, automatically uploads them to Snapencode, and confirms their processing status.
The Goal: A “Watch Folder” Uploader
Our goal is to create a Node.js script that achieves the following:
- Monitors a specific directory on a local machine or server.
- When a new video file (
.mp4
,.mov
, etc.) is added, it automatically uploads it to a designated collection in Snapencode. - After uploading, it polls the status endpoint until the video is “completed.”
- Once completed, it logs the video’s ID and is ready for the next file.
This is a perfect solution for workflows where content is generated programmatically or dropped into a shared folder by non-technical team members.
Prerequisites
- A Snapencode API Key: Generate one from your dashboard under Settings > API Keys.
- Node.js: We’ll use JavaScript and the Node.js runtime for our script.
axios
andchokidar
: Two simple packages for making API requests and watching files.
npm install axios chokidar form-data
Building the Automation Script
We’ll create a single, complete script. Let’s name it upload-watcher.js
.
Step 1: Configure the Script
First, let’s set up the configuration variables and import the necessary libraries at the top of our upload-watcher.js
file.
const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');
const path = require('path');
const chokidar = require('chokidar');
// --- Configuration ---
const API_BASE_URL = 'https://your-Snapencode-domain.com/api/client/v1';
const API_KEY = process.env.Snapencode_API_KEY || 'sk_your_api_key_here'; // Best practice: use environment variables
const TARGET_FOLDER = 'root/automated-uploads'; // The collection path in Snapencode
const WATCH_DIRECTORY = './videos-to-upload';
// A set to keep track of files currently being processed to avoid double-uploads
const processingFiles = new Set();
Using environment variables (process.env.Snapencode_API_KEY
) for your API key is much more secure than hard-coding it directly in the script.
Step 2: Create the Core Functions
Next, add the two main functions: one for handling the file upload and another for monitoring the processing status.
// (Add this code below the configuration section)
async function uploadVideo(filePath) {
console.log(`[UPLOADING] Starting upload for: ${path.basename(filePath)}`);
processingFiles.add(filePath); // Mark file as being processed
const form = new FormData();
form.append('video', fs.createReadStream(filePath));
form.append('folder', TARGET_FOLDER);
try {
const response = await axios.post(`${API_BASE_URL}/uploads`, form, {
headers: { ...form.getHeaders(), 'Authorization': `Bearer ${API_KEY}` },
});
console.log(`[SUCCESS] Upload accepted! Video ID: ${response.data.data.id}`);
return response.data.data.id;
} catch (error) {
console.error(`[FAILURE] Upload failed for ${path.basename(filePath)}:`, error.response?.data?.message || error.message);
return null;
}
}
async function monitorStatus(videoId, filePath) {
if (!videoId) {
processingFiles.delete(filePath); // Remove from processing set on failure
return;
}
console.log(`[MONITORING] Watching status for Video ID: ${videoId}`);
const interval = setInterval(async () => {
try {
const response = await axios.get(`${API_BASE_URL}/uploads/${videoId}`, {
headers: { 'Authorization': `Bearer ${API_KEY}` },
});
const { status, status_text } = response.data.data;
if (status === 6) { // Completed
console.log(`✅ [COMPLETE] Processing finished for Video ID: ${videoId}!`);
clearInterval(interval);
processingFiles.delete(filePath); // Remove from set on success
} else if (status === 7) { // Failed
console.error(`❌ [FAILED] Processing failed for Video ID: ${videoId}.`);
clearInterval(interval);
processingFiles.delete(filePath);
} else {
console.log(`[STATUS] Video ID ${videoId}: ${status_text} (${status})`);
}
} catch (error) {
console.error(`[ERROR] Could not get status for ${videoId}:`, error.message);
clearInterval(interval);
processingFiles.delete(filePath);
}
}, 5000); // Check every 5 seconds
}
This script demonstrates a server-to-server interaction. Never expose your secret API key in client-side browser code.
Step 3: Initialize the File Watcher
Finally, add the chokidar
logic to the end of the script. This will watch the directory and trigger our functions when a new file is added.
// (Add this code to the end of the file)
function initializeWatcher() {
console.log(`--- Snapencode Watch Folder Initialized ---`);
console.log(`Watching for new videos in: ${path.resolve(WATCH_DIRECTORY)}`);
if (!fs.existsSync(WATCH_DIRECTORY)) {
console.log(`Creating watch directory...`);
fs.mkdirSync(WATCH_DIRECTORY, { recursive: true });
}
const watcher = chokidar.watch(WATCH_DIRECTORY, {
ignored: /(^|[\/\\])\../, // ignore dotfiles
persistent: true,
ignoreInitial: true, // Don't upload files that are already there on startup
});
watcher.on('add', (filePath) => {
if (processingFiles.has(filePath)) {
return; // Skip if already being processed
}
console.log(`[DETECTED] New file: ${path.basename(filePath)}`);
// Wait a moment to ensure the file is fully written before uploading
setTimeout(async () => {
const videoId = await uploadVideo(filePath);
await monitorStatus(videoId, filePath);
}, 2000);
});
}
initializeWatcher();
Step 4: Run Your Watcher
With the upload-watcher.js
file complete, you can run it from your terminal.
# Best practice: set the API key as an environment variable
export Snapencode_API_KEY="sk_your_api_key_here"
# Run the script
node upload-watcher.js
Now, any new video file you drop into the ./videos-to-upload
directory will be automatically uploaded and processed!