Code Plagiarism
Detection API
Build plagiarism detection into your apps. Check code against 20+ billion sources.
Codequiry SDK for Java
The official Java SDK for Codequiry provides a robust, thread-safe interface for enterprise Java applications. Built for Java 11+ with support for both synchronous and asynchronous operations.
📦 Installation
Add the dependency to your project using your preferred build tool:
Maven
<dependency>
<groupId>com.codequiry</groupId>
<artifactId>codequiry-java</artifactId>
<version>1.2.0</version>
</dependency>
Gradle
// Groovy DSL
implementation 'com.codequiry:codequiry-java:1.2.0'
// Kotlin DSL
implementation("com.codequiry:codequiry-java:1.2.0")
🚀 Quick Start
Initialize the client and verify your API key:
import com.codequiry.CodequiryClient;
import com.codequiry.models.*;
public class QuickStart {
public static void main(String[] args) {
// Initialize client with your API key
CodequiryClient client = new CodequiryClient.Builder()
.apiKey("your-api-key-here")
.baseUrl("https://codequiry.com/api/v1")
.timeout(30_000) // 30 second timeout
.maxRetries(3)
.build();
try {
// Test connection
AccountInfo account = client.getAccountInfo();
System.out.println("Connected as: " + account.getName());
System.out.println("Plan: " + account.getPlan());
System.out.println("Checks remaining: " + account.getChecksRemaining());
} catch (CodequiryException e) {
System.err.println("Error: " + e.getMessage());
System.err.println("Status: " + e.getStatusCode());
}
}
}
🔄 Complete Workflow Example
A full end-to-end example showing how to create a check, upload files, run analysis, and retrieve results:
import com.codequiry.CodequiryClient;
import com.codequiry.models.*;
import java.io.File;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class PlagiarismChecker {
private final CodequiryClient client;
public PlagiarismChecker(String apiKey) {
this.client = new CodequiryClient.Builder()
.apiKey(apiKey)
.timeout(30_000)
.maxRetries(3)
.build();
}
public CheckOverview runCheck(String name, int language, List<File> files)
throws CodequiryException, InterruptedException {
// 1. Create check
Check check = client.createCheck(new CreateCheckRequest(name, language));
System.out.println("Created check: " + check.getId());
// 2. Upload files
for (File file : files) {
UploadResult result = client.uploadFile(check.getId(), file);
System.out.println("Uploaded: " + file.getName());
}
// 3. Start analysis
client.startCheck(new StartCheckRequest(check.getId(), 1, true, true));
System.out.println("Analysis started...");
// 4. Poll for completion
CheckStatus status = waitForCompletion(check.getId());
System.out.println("Analysis complete! Status: " + status.getStatus());
// 5. Get results
CheckOverview overview = client.getCheckOverview(check.getId());
// Process results
for (Submission submission : overview.getSubmissions()) {
System.out.printf("%s: %.1f%% similarity%n",
submission.getFilename(),
submission.getTotalResult());
if (submission.getTotalResult() > 50.0) {
System.out.println(" ⚠ HIGH SIMILARITY - Review required");
}
}
return overview;
}
private CheckStatus waitForCompletion(int checkId)
throws CodequiryException, InterruptedException {
long startTime = System.currentTimeMillis();
long timeout = TimeUnit.MINUTES.toMillis(10);
while (System.currentTimeMillis() - startTime < timeout) {
CheckStatus status = client.getCheckStatus(checkId);
if (status.getStatusId() == 4) { // Completed
return status;
}
if (status.getStatusId() == 5) { // Error
throw new CodequiryException("Analysis failed: " + status.getStatusMessage());
}
System.out.printf("Progress: %d%% - %s%n",
status.getProgress(), status.getStatusMessage());
Thread.sleep(30_000); // Wait 30 seconds
}
throw new CodequiryException("Analysis timed out after 10 minutes");
}
public static void main(String[] args) throws Exception {
PlagiarismChecker checker = new PlagiarismChecker("your-api-key-here");
List<File> files = List.of(
new File("student1_submission.zip"),
new File("student2_submission.zip"),
new File("student3_submission.zip")
);
CheckOverview results = checker.runCheck(
"Java Assignment - Data Structures",
13, // Java language ID
files
);
System.out.printf("Analyzed %d submissions%n", results.getSubmissions().size());
}
}
⚡ Async Operations with CompletableFuture
Leverage Java's CompletableFuture for non-blocking, asynchronous API calls:
import com.codequiry.CodequiryClient;
import com.codequiry.CodequiryAsyncClient;
import com.codequiry.models.*;
import java.io.File;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
public class AsyncPlagiarismChecker {
private final CodequiryAsyncClient asyncClient;
private final ExecutorService executor;
public AsyncPlagiarismChecker(String apiKey) {
CodequiryClient client = new CodequiryClient.Builder()
.apiKey(apiKey)
.timeout(30_000)
.build();
this.asyncClient = new CodequiryAsyncClient(client);
this.executor = Executors.newFixedThreadPool(4);
}
public CompletableFuture<CheckOverview> runCheckAsync(
String name, int language, List<File> files) {
// Create check asynchronously
return asyncClient.createCheckAsync(new CreateCheckRequest(name, language))
.thenCompose(check -> {
System.out.println("Created check: " + check.getId());
// Upload all files concurrently
List<CompletableFuture<UploadResult>> uploads = files.stream()
.map(file -> asyncClient.uploadFileAsync(check.getId(), file)
.thenApply(result -> {
System.out.println("Uploaded: " + file.getName());
return result;
}))
.collect(Collectors.toList());
// Wait for all uploads, then start analysis
return CompletableFuture.allOf(uploads.toArray(new CompletableFuture[0]))
.thenCompose(v -> {
System.out.println("All files uploaded. Starting analysis...");
return asyncClient.startCheckAsync(
new StartCheckRequest(check.getId(), 1, true, true));
})
.thenCompose(v -> pollStatusAsync(check.getId()))
.thenCompose(status -> asyncClient.getOverviewAsync(check.getId()));
});
}
private CompletableFuture<CheckStatus> pollStatusAsync(int checkId) {
return CompletableFuture.supplyAsync(() -> {
long startTime = System.currentTimeMillis();
long timeout = 600_000; // 10 minutes
while (System.currentTimeMillis() - startTime < timeout) {
try {
CheckStatus status = asyncClient.getClient()
.getCheckStatus(checkId);
if (status.getStatusId() == 4) return status;
if (status.getStatusId() == 5) {
throw new RuntimeException("Analysis failed");
}
System.out.printf("Progress: %d%%%n", status.getProgress());
Thread.sleep(30_000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
}
throw new RuntimeException("Timeout");
}, executor);
}
public static void main(String[] args) throws Exception {
AsyncPlagiarismChecker checker = new AsyncPlagiarismChecker("your-api-key-here");
List<File> files = List.of(
new File("student1.zip"),
new File("student2.zip"),
new File("student3.zip")
);
// Run asynchronously
CompletableFuture<CheckOverview> future = checker.runCheckAsync(
"Async Assignment Check", 14, files
);
// Do other work while check runs...
System.out.println("Check running in background...");
// Get results when ready
CheckOverview overview = future.get();
overview.getSubmissions().forEach(sub ->
System.out.printf("%s: %.1f%% similarity%n",
sub.getFilename(), sub.getTotalResult())
);
}
}
🔧 Error Handling
The SDK provides structured exception handling with detailed error information:
import com.codequiry.CodequiryClient;
import com.codequiry.exceptions.*;
public class ErrorHandling {
public static void main(String[] args) {
CodequiryClient client = new CodequiryClient.Builder()
.apiKey("your-api-key-here")
.build();
try {
var check = client.createCheck(
new CreateCheckRequest("Test", 14));
} catch (AuthenticationException e) {
// 401 - Invalid API key
System.err.println("Invalid API key: " + e.getMessage());
} catch (ValidationException e) {
// 422 - Invalid parameters
System.err.println("Validation error: " + e.getMessage());
e.getErrors().forEach((field, message) ->
System.err.println(" " + field + ": " + message));
} catch (RateLimitException e) {
// 429 - Rate limit exceeded
System.err.println("Rate limited. Retry after: " + e.getRetryAfter() + "s");
} catch (NotFoundException e) {
// 404 - Resource not found
System.err.println("Not found: " + e.getMessage());
} catch (CodequiryException e) {
// Any other API error
System.err.println("API error " + e.getStatusCode() + ": " + e.getMessage());
} catch (Exception e) {
// Network or other errors
System.err.println("Unexpected error: " + e.getMessage());
}
}
}
🌱 Spring Boot Integration
Integrate Codequiry seamlessly into your Spring Boot application:
Configuration
# application.yml
codequiry:
api-key: ${CODEQUIRY_API_KEY}
base-url: https://codequiry.com/api/v1
timeout: 30000
max-retries: 3
Configuration Bean
import com.codequiry.CodequiryClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CodequiryConfig {
@Value("${codequiry.api-key}")
private String apiKey;
@Value("${codequiry.base-url:https://codequiry.com/api/v1}")
private String baseUrl;
@Value("${codequiry.timeout:30000}")
private int timeout;
@Value("${codequiry.max-retries:3}")
private int maxRetries;
@Bean
public CodequiryClient codequiryClient() {
return new CodequiryClient.Builder()
.apiKey(apiKey)
.baseUrl(baseUrl)
.timeout(timeout)
.maxRetries(maxRetries)
.build();
}
}
Service Layer
import com.codequiry.CodequiryClient;
import com.codequiry.models.*;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.List;
@Service
public class PlagiarismService {
private final CodequiryClient client;
public PlagiarismService(CodequiryClient client) {
this.client = client;
}
public Check createAndUpload(String name, int language, List<MultipartFile> files)
throws CodequiryException, IOException {
// Create check
Check check = client.createCheck(new CreateCheckRequest(name, language));
// Upload each file
for (MultipartFile multipartFile : files) {
File tempFile = Files.createTempFile("upload-", ".zip").toFile();
try {
multipartFile.transferTo(tempFile);
client.uploadFile(check.getId(), tempFile);
} finally {
tempFile.delete();
}
}
return check;
}
public void startAnalysis(int checkId, int testType) throws CodequiryException {
client.startCheck(new StartCheckRequest(checkId, testType, true, true));
}
public CheckStatus getStatus(int checkId) throws CodequiryException {
return client.getCheckStatus(checkId);
}
public CheckOverview getResults(int checkId) throws CodequiryException {
return client.getCheckOverview(checkId);
}
}
REST Controller
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/api/plagiarism")
public class PlagiarismController {
private final PlagiarismService plagiarismService;
public PlagiarismController(PlagiarismService plagiarismService) {
this.plagiarismService = plagiarismService;
}
@PostMapping("/check")
public ResponseEntity<?> createCheck(
@RequestParam String name,
@RequestParam int language,
@RequestParam("files") List<MultipartFile> files) {
try {
Check check = plagiarismService.createAndUpload(name, language, files);
plagiarismService.startAnalysis(check.getId(), 1);
return ResponseEntity.ok(Map.of(
"success", true,
"check_id", check.getId(),
"message", "Check created and analysis started"
));
} catch (Exception e) {
return ResponseEntity.badRequest().body(Map.of(
"success", false,
"error", e.getMessage()
));
}
}
@GetMapping("/check/{checkId}/status")
public ResponseEntity<?> getStatus(@PathVariable int checkId) {
try {
CheckStatus status = plagiarismService.getStatus(checkId);
return ResponseEntity.ok(status);
} catch (Exception e) {
return ResponseEntity.badRequest().body(Map.of(
"error", e.getMessage()
));
}
}
@GetMapping("/check/{checkId}/results")
public ResponseEntity<?> getResults(@PathVariable int checkId) {
try {
CheckOverview overview = plagiarismService.getResults(checkId);
return ResponseEntity.ok(overview);
} catch (Exception e) {
return ResponseEntity.badRequest().body(Map.of(
"error", e.getMessage()
));
}
}
}
🧵 Thread-Safe Batch Processing
Process multiple assignments concurrently with thread-safe batch operations:
import com.codequiry.CodequiryClient;
import com.codequiry.models.*;
import java.io.File;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;
public class BatchProcessor {
private final CodequiryClient client;
private final ExecutorService executor;
private final Semaphore semaphore;
public BatchProcessor(CodequiryClient client, int maxConcurrent) {
this.client = client;
this.executor = Executors.newFixedThreadPool(maxConcurrent);
this.semaphore = new Semaphore(maxConcurrent);
}
public record Assignment(String name, int language, List<File> files) {}
public record Result(Assignment assignment, int checkId, CheckOverview overview, Exception error) {}
public List<Result> processAssignments(List<Assignment> assignments)
throws InterruptedException {
List<Future<Result>> futures = new ArrayList<>();
for (Assignment assignment : assignments) {
Future<Result> future = executor.submit(() -> {
semaphore.acquire();
try {
return processAssignment(assignment);
} finally {
semaphore.release();
}
});
futures.add(future);
}
// Collect results
return futures.stream()
.map(future -> {
try {
return future.get(15, TimeUnit.MINUTES);
} catch (Exception e) {
return new Result(null, 0, null, e);
}
})
.collect(Collectors.toList());
}
private Result processAssignment(Assignment assignment) {
try {
// Create check
Check check = client.createCheck(
new CreateCheckRequest(assignment.name(), assignment.language()));
// Upload files
for (File file : assignment.files()) {
client.uploadFile(check.getId(), file);
}
// Start analysis
client.startCheck(new StartCheckRequest(check.getId(), 1, true, true));
// Wait for completion
long deadline = System.currentTimeMillis() + 600_000;
while (System.currentTimeMillis() < deadline) {
CheckStatus status = client.getCheckStatus(check.getId());
if (status.getStatusId() == 4) {
CheckOverview overview = client.getCheckOverview(check.getId());
return new Result(assignment, check.getId(), overview, null);
}
if (status.getStatusId() == 5) {
throw new RuntimeException("Analysis failed: " + status.getStatusMessage());
}
Thread.sleep(30_000);
}
throw new RuntimeException("Timeout");
} catch (Exception e) {
return new Result(assignment, 0, null, e);
}
}
public void shutdown() {
executor.shutdown();
}
// Usage
public static void main(String[] args) throws Exception {
CodequiryClient client = new CodequiryClient.Builder()
.apiKey("your-api-key-here")
.build();
BatchProcessor processor = new BatchProcessor(client, 5);
List<Assignment> assignments = List.of(
new Assignment("CS101 - Week 1", 14,
List.of(new File("week1_student1.zip"), new File("week1_student2.zip"))),
new Assignment("CS101 - Week 2", 14,
List.of(new File("week2_student1.zip"), new File("week2_student2.zip"))),
new Assignment("CS201 - Midterm", 13,
List.of(new File("midterm_student1.zip"), new File("midterm_student2.zip")))
);
List<Result> results = processor.processAssignments(assignments);
for (Result result : results) {
if (result.error() != null) {
System.err.printf("FAILED: %s - %s%n",
result.assignment().name(), result.error().getMessage());
} else {
System.out.printf("OK: %s - %d submissions analyzed%n",
result.assignment().name(),
result.overview().getSubmissions().size());
}
}
processor.shutdown();
}
}
📋 API Method Reference
Complete list of available methods in the Java SDK:
| Method | Description | Returns |
|---|---|---|
getAccountInfo() |
Get account details and subscription info | AccountInfo |
getLanguages() |
List all supported programming languages | List<Language> |
getTestTypes() |
List available analysis engines | List<TestType> |
getChecks() |
List all your plagiarism checks | List<Check> |
createCheck(request) |
Create a new plagiarism check | Check |
uploadFile(checkId, file) |
Upload a ZIP file to a check | UploadResult |
batchUpload(checkId, files) |
Upload multiple files at once | BatchUploadResult |
startCheck(request) |
Start plagiarism analysis | void |
getCheckStatus(checkId) |
Get check progress and status | CheckStatus |
getCheckOverview(checkId) |
Get results overview with scores | CheckOverview |
getCheckResults(checkId, subId) |
Get detailed match analysis | CheckResults |
getCheckSummary(checkId) |
Get aggregate statistics | CheckSummary |
exportResults(checkId, format) |
Export results as CSV or JSON | ExportResult |
getAIResults(checkId) |
Get AI detection results | AIResults |
updateCheck(checkId, request) |
Update check name or language | Check |
deleteCheck(checkId) |
Delete a check permanently | void |
deleteSubmission(checkId, subId) |
Remove a submission from a check | void |