New Breakthrough
Detecting AI-Written code is now easier and more accurate with the latest engine update. Start checking
Start checking
Read more
Developer API
Node.js SDK
Build plagiarism detection into your apps. Check code against 427B+ sources.
const response = await fetch('https://codequiry.com/api/v1/check', {
method: 'POST',
headers: { 'apikey': 'YOUR_API_KEY' },
body: formData
});
// Check created!
NODE.JS SDK
Codequiry SDK for Node.js
The official Node.js SDK for Codequiry provides a powerful, async/await-based interface for integrating plagiarism detection into your Node.js applications. Perfect for educational platforms, code review systems, and automated assignment checking.
Open Source: View the complete source code and contribute at
github.com/cqchecker/codequiry-sdk
Installation
npm (Recommended)
npm install codequiry
Yarn
yarn add codequiry
Requirements: Node.js 14.0.0 or higher, supports ESM and CommonJS modules
Quick Start
1. Initialize the Client
const { CodequiryClient } = require('codequiry');
// Initialize with your API key
const client = new CodequiryClient({
apiKey: 'your-api-key-here',
baseUrl: 'https://codequiry.com/api/v1' // Optional
});
// Verify connection
async function testConnection() {
try {
const account = await client.getAccountInfo();
console.log(`Connected as: ${account.name}`);
console.log(`Checks remaining: ${account.checks_remaining}`);
} catch (error) {
console.error('Connection failed:', error.message);
}
}
testConnection();
2. Complete Workflow Example
async function runPlagiarismCheck() {
try {
// 1. Create a new check
const check = await client.createCheck({
name: 'Assignment 1 - JavaScript Basics',
language: 15 // JavaScript
});
console.log(`Created check: ${check.id}`);
// 2. Upload files (array of file paths or buffers)
const files = [
'student1_submission.js',
'student2_submission.js',
'student3_submission.js'
];
for (const filePath of files) {
const result = await client.uploadFile(check.id, filePath);
console.log(`Uploaded: ${result.filename}`);
}
// 3. Start the analysis
const analysis = await client.startCheck(check.id, {
webcheck: true, // Check against web sources
dbcheck: true // Check against database
});
console.log('Analysis started...');
// 4. Monitor progress
const results = await client.waitForCompletion(check.id, {
pollInterval: 30000, // Check every 30 seconds
timeout: 600000 // 10 minute timeout
});
// 5. Get overview results
const overview = await client.getOverview(check.id);
console.log('Analysis complete!');
console.log(`Found ${overview.submissions.length} submissions`);
// 6. Process results
const suspiciousSubmissions = overview.submissions.filter(
sub => parseFloat(sub.total_result) > 50
);
for (const submission of suspiciousSubmissions) {
console.log(`⚠️ ${submission.filename}: ${submission.total_result}% similarity`);
// Get detailed results
const details = await client.getDetailedResults(check.id, submission.id);
// Process other matches
details.other_matches.forEach(match => {
console.log(` → Match with ${match.file_matched}: ${match.similarity}%`);
});
}
return overview;
} catch (error) {
console.error('Error:', error.message);
throw error;
}
}
// Run the check
runPlagiarismCheck()
.then(results => console.log('Check completed successfully'))
.catch(error => console.error('Check failed:', error));
Advanced Features
Multiple Upload Methods
// Upload from file path
await client.uploadFile(checkId, './code.js');
// Upload from buffer
const buffer = fs.readFileSync('./code.js');
await client.uploadBuffer(checkId, buffer, 'code.js');
// Upload from string
const code = 'console.log("Hello World");';
await client.uploadString(checkId, code, 'hello.js');
// Bulk upload
const files = ['file1.js', 'file2.js', 'file3.js'];
await client.uploadMultiple(checkId, files);
Configuration Options
const client = new CodequiryClient({
apiKey: 'your-api-key',
baseUrl: 'https://codequiry.com/api/v1',
timeout: 30000, // Request timeout
retries: 3, // Auto retry failed requests
debug: false, // Enable debug logging
headers: { // Custom headers
'User-Agent': 'MyApp/1.0'
}
});
// Configure analysis options
await client.startCheck(checkId, {
webcheck: true,
dbcheck: false,
test_type: 1, // Analysis engine type
sensitivity: 'high' // Detection sensitivity
});
Express.js Integration
Perfect for building web applications with plagiarism detection:
const express = require('express');
const multer = require('multer');
const { CodequiryClient } = require('codequiry');
const app = express();
const upload = multer({ dest: 'uploads/' });
const codequiry = new CodequiryClient({ apiKey: process.env.CODEQUIRY_API_KEY });
// Upload and check endpoint
app.post('/check-plagiarism', upload.array('files'), async (req, res) => {
try {
const { name, language } = req.body;
// Create check
const check = await codequiry.createCheck({ name, language: parseInt(language) });
// Upload files
const uploadPromises = req.files.map(file =>
codequiry.uploadFile(check.id, file.path)
);
await Promise.all(uploadPromises);
// Start analysis
await codequiry.startCheck(check.id, {
webcheck: true,
dbcheck: true
});
res.json({
success: true,
checkId: check.id,
message: 'Analysis started. Use /check-status to monitor progress.'
});
} catch (error) {
res.status(500).json({
success: false,
error: error.message
});
}
});
// Check status endpoint
app.get('/check-status/:checkId', async (req, res) => {
try {
const { checkId } = req.params;
const status = await codequiry.getCheckStatus(checkId);
if (status.status_id === 4) { // Completed
const overview = await codequiry.getOverview(checkId);
res.json({
status: 'completed',
results: overview
});
} else {
res.json({
status: 'processing',
progress: status.progress || 'In queue'
});
}
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.listen(3000, () => {
console.log('Plagiarism detection server running on port 3000');
});
Async/Await Patterns
Sequential Processing
// Process checks one by one
async function processSequentially(assignments) {
const results = [];
for (const assignment of assignments) {
try {
const check = await client.createCheck({
name: assignment.name,
language: assignment.language
});
// Upload files
for (const file of assignment.files) {
await client.uploadFile(check.id, file);
}
// Start and wait for completion
await client.startCheck(check.id);
const result = await client.waitForCompletion(check.id);
results.push({
assignment: assignment.name,
checkId: check.id,
completed: true
});
} catch (error) {
results.push({
assignment: assignment.name,
error: error.message,
completed: false
});
}
}
return results;
}
Parallel Processing
// Process multiple checks simultaneously
async function processInParallel(assignments) {
const checkPromises = assignments.map(async (assignment) => {
try {
const check = await client.createCheck({
name: assignment.name,
language: assignment.language
});
// Upload all files in parallel
const uploadPromises = assignment.files.map(file =>
client.uploadFile(check.id, file)
);
await Promise.all(uploadPromises);
// Start analysis
await client.startCheck(check.id);
return {
assignment: assignment.name,
checkId: check.id,
status: 'started'
};
} catch (error) {
return {
assignment: assignment.name,
error: error.message,
status: 'failed'
};
}
});
return await Promise.all(checkPromises);
}
Error Handling & Best Practices
// Comprehensive error handling
class PlagiarismChecker {
constructor(apiKey) {
this.client = new CodequiryClient({
apiKey,
retries: 3,
timeout: 30000
});
}
async checkWithRetry(assignment, maxRetries = 3) {
let attempt = 0;
while (attempt < maxRetries) {
try {
return await this.performCheck(assignment);
} catch (error) {
attempt++;
if (error.status === 429) {
// Rate limited - wait and retry
const waitTime = Math.pow(2, attempt) * 1000;
await this.sleep(waitTime);
continue;
}
if (error.status === 422) {
// Client error - don't retry
throw new Error(`Invalid request: ${error.message}`);
}
if (attempt === maxRetries) {
throw new Error(`Failed after ${maxRetries} attempts: ${error.message}`);
}
// Wait before retrying
await this.sleep(2000 * attempt);
}
}
}
async performCheck(assignment) {
// Create check with validation
if (!assignment.files || assignment.files.length === 0) {
throw new Error('No files provided for analysis');
}
const check = await this.client.createCheck({
name: assignment.name || 'Untitled Check',
language: assignment.language || 1
});
// Upload with progress tracking
console.log(`Uploading ${assignment.files.length} files...`);
let uploaded = 0;
for (const file of assignment.files) {
await this.client.uploadFile(check.id, file);
uploaded++;
console.log(`Progress: ${uploaded}/${assignment.files.length} files uploaded`);
}
// Start analysis with options
await this.client.startCheck(check.id, {
webcheck: assignment.checkWeb || true,
dbcheck: assignment.checkDatabase || true
});
console.log('Analysis started, waiting for completion...');
// Wait with timeout
const results = await this.client.waitForCompletion(check.id, {
pollInterval: 30000,
timeout: 600000,
onProgress: (status) => {
console.log(`Status: ${status.message || 'Processing...'}`);
}
});
return results;
}
sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
}
// Usage
const checker = new PlagiarismChecker(process.env.CODEQUIRY_API_KEY);
async function main() {
try {
const result = await checker.checkWithRetry({
name: 'Final Exam - Data Structures',
language: 1, // Java
files: ['student1.java', 'student2.java'],
checkWeb: true,
checkDatabase: true
});
console.log('Check completed successfully:', result);
} catch (error) {
console.error('Check failed:', error.message);
}
}
main();