Copyleaks 5.0.0

dotnet add package Copyleaks --version 5.0.0
                    
NuGet\Install-Package Copyleaks -Version 5.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Copyleaks" Version="5.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Copyleaks" Version="5.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Copyleaks" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Copyleaks --version 5.0.0
                    
#r "nuget: Copyleaks, 5.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Copyleaks@5.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Copyleaks&version=5.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Copyleaks&version=5.0.0
                    
Install as a Cake Tool

Copyleaks SDK

The official Copyleaks .NET library, supporting .NET 8 and later.

Copyleaks is the integrity layer for your tech stack that helps organizations and individuals understand what's human-made and original, AI-generated, or manipulated across text, image, audio and video.

This SDK gives you access to the following Copyleaks products:

  • AI Text Detection
  • AI Image Detection (synchronous, file upload and asynchronous)
  • AI Video Detection
  • Plagiarism Checker (Authenticity scans: file, URL, OCR)
  • Image Plagiarism Detection
  • Grammar Checker
  • Text Moderation

Upgrading from 4.x? See the upgrade notes in the CHANGELOG.

πŸš€ Getting Started

Before you start, ensure you have the following:

Once you have your account and API key:

Install the SDK:

dotnet add package Copyleaks

Or, in the Package Manager Console:

Install-Package Copyleaks

πŸ“š Documentation

To learn more about how to use Copyleaks API please check out our Documentation.

Creating the API clients

The SDK has one class per product: CopyleaksIdentityApi (login), CopyleaksScansApi (plagiarism scans, exports and lookups), CopyleaksAIDetectionApi, CopyleaksAiImageDetectionApi, CopyleaksAiVideoDetectionApi, CopyleaksImagePlagiarismApi, CopyleaksWritingAssistantApi and CopyleaksTextModerationApi.

API objects are thread-safe. When you do not pass an HttpClient, they all share one pooled HttpClient, so creating them is cheap. Still, create them once and reuse them:

using Copyleaks.SDK.V3.API;

var identity = new CopyleaksIdentityApi();
var scans = new CopyleaksScansApi();

In ASP.NET Core, register them as typed clients with IHttpClientFactory:

using Copyleaks.SDK.V3.API;

builder.Services.AddSingleton(new CopyleaksClientOptions { MaxRetries = 3 }); // optional
builder.Services.AddHttpClient<CopyleaksIdentityApi>();
builder.Services.AddHttpClient<CopyleaksScansApi>();
builder.Services.AddHttpClient<CopyleaksAIDetectionApi>();

// Then inject them:
public class ScanService(CopyleaksIdentityApi identity, CopyleaksScansApi scans) { /* ... */ }

You can also pass your own HttpClient: new CopyleaksScansApi(httpClient). The SDK never disposes a client you pass in.

Timeouts, retries and cancellation

CopyleaksClientOptions controls the HTTP behavior:

var options = new CopyleaksClientOptions
{
    Timeout = TimeSpan.FromSeconds(60),          // per attempt; the default comes from ConfigurationManager ("RequestsTimeout", 60 seconds)
    MaxRetries = 3,                              // 0 turns retries off
    RetryBaseDelay = TimeSpan.FromSeconds(1),    // exponential backoff with jitter
    MaxRetryDelay = TimeSpan.FromSeconds(30),    // longest wait, including Retry-After
};
var scans = new CopyleaksScansApi(options: options);
  • Calls that are safe to repeat (GET requests, login, start, delete, and submits to a fixed scan id) are retried on network errors, timeouts and HTTP 408, 429, 500, 502, 503 and 504.
  • Calls that are charged per call or trigger an action (AI Text Detection, Grammar Checker, Text Moderation, AI Image Detection, Image Plagiarism Detection, export and resend webhook) are retried only on HTTP 429.
  • The SDK honors the Retry-After header. When it asks for a longer wait than MaxRetryDelay, the SDK returns the error instead of waiting.
  • A request that runs out of time throws TimeoutException. An error response throws CopyleaksHttpException, with HttpErrorCode, ResponseBody, ErrorType, ErrorId, ErrorCode, RetryAfter and Attempt (the 1-based attempt that got the error).
  • An attempt can time out after the server accepted it. The retry of such a submit then fails with 409 Conflict. If you use a new scan id for every submit, a 409 with Attempt greater than 1 means an earlier attempt was accepted, so treat the call as successful:
try
{
    await scans.SubmitFileAsync(scanId, document, token);
}
catch (CopyleaksHttpException ex) when (ex.HttpErrorCode == HttpStatusCode.Conflict && ex.Attempt > 1)
{
    // With a new scan id per submit, an earlier attempt created this scan; only its response was lost.
}
  • The PDF report and usage history downloads are streamed. Their timeout also covers reading the body (and, for the usage history, writing it to your stream), and a failure while the body is read is not retried. If a usage history download fails partway, your stream may already hold part of the CSV.
  • Every async method takes an optional CancellationToken:
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
uint credits = await scans.CreditBalanceAsync(token, cts.Token);

πŸ’‘ Usage Examples

Here are some common usage examples for the Copyleaks SDK. You can also see a comprehensive code example in the SampleWebApplication.csproj on our GitHub repository: SampleWebApplication.

Get Authentication Token

This example demonstrates how to log in to the Copyleaks API and obtain an authentication token.

using System;
using System.Threading.Tasks;
using Copyleaks.SDK.V3.API;

public class Program
{
    // --- Your Credentials ---
    private const string USER_EMAIL = "YOUR_EMAIL_ADDRESS";
    private const string USER_KEY = "YOUR_API_KEY";
    // --------------------

    public static async Task Main(string[] args)
    {
        // Log in to the Copyleaks API
        Console.WriteLine("Authenticating...");
        var identityClient = new CopyleaksIdentityApi();
        var loginResponse = await identityClient.LoginAsync(USER_EMAIL, USER_KEY).ConfigureAwait(false);
        string authToken = loginResponse.Token; // valid for 48 hours; reuse it
        Console.WriteLine("Logged in successfully!");
    }
}

For a detailed understanding of the authentication process, refer to the Copyleaks Login Endpoint Documentation.

Submit Text for Plagiarism Scan

This example shows how to prepare and submit raw text content for a plagiarism scan.

using System;
using System.Text;
using System.Threading.Tasks;
using Copyleaks.SDK.V3.API;
using Copyleaks.SDK.V3.API.Models.Requests;
using Copyleaks.SDK.V3.API.Models.Requests.Properties;
using Copyleaks.SDK.V3.API.Models.Types;

public class Program
{
    // --- Your Credentials ---
    private const string USER_EMAIL = "YOUR_EMAIL_ADDRESS";
    private const string USER_KEY = "YOUR_API_KEY";
    private const string WEBHOOK_URL = "https://your-server.com/webhook/{STATUS}";
    // --------------------

    public static async Task Main(string[] args)
    {
        var identityClient = new CopyleaksIdentityApi();
        var scansClient = new CopyleaksScansApi();

        var loginResponse = await identityClient.LoginAsync(USER_EMAIL, USER_KEY).ConfigureAwait(false);
        var authToken = loginResponse.Token;

        // A unique scan ID for the scan
        // In case this scan ID already exists for this user Copyleaks API will return HTTP 409 Conflict result
        string scanId = Guid.NewGuid().ToString();
        string scannedText = "Hello world";

        ClientScanProperties clientScanProperties = new ClientScanProperties();

        clientScanProperties.Action = eSubmitAction.Scan;
        clientScanProperties.Webhooks = new Webhooks
        {
            // Copyleaks API will POST the scan results to the 'completed' callback
            Status = new Uri(WEBHOOK_URL)
        };

        // Sandbox mode does not take any credits
        clientScanProperties.Sandbox = true;

        clientScanProperties.ReportSection.Create = true;

        // Submit a file for scan in https://api.copyleaks.com
        await scansClient.SubmitFileAsync(scanId, new FileDocument
        {
            Base64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(scannedText)),
            Filename = "text.txt",
            PropertiesSection = clientScanProperties
        },
        authToken).ConfigureAwait(false);
    }
}

For large files, submit a stream instead of a base64 string. The SDK encodes the file while it reads it:

using (var file = File.OpenRead("thesis.pdf"))
    await scansClient.SubmitFileAsync(scanId, file, "thesis.pdf", clientScanProperties, authToken);

For a full guide please refer to our step by step Guide

For a detailed understanding of the plagiarism detection process, refer to the Copyleaks Submit Endpoint Documentation

More scan features

Every feature below is optional. Properties you leave unset are not sent, so the API default applies.

using Copyleaks.SDK.V3.API.Models.Requests.Properties;
using Copyleaks.SDK.V3.API.Models.Requests.WritingAssistant;

var properties = new ClientScanProperties
{
    Sandbox = true,
    Webhooks = new Webhooks { Status = new Uri("https://your-server.com/webhook/{STATUS}") },

    // AI detection, with AI Logic explanations and a sensitivity from 1 to 3
    AIGeneratedText = new AIGeneratedText { Detect = true, Sensitivity = 2, Explain = new AIExplainSettings { Enable = true } },

    // Grammar Checker inside the scan (weights default to 1.0)
    WritingFeedback = new WritingFeedbackSettings { Enable = true, Score = new Score { GrammarScoreWeight = 0.5 } },

    // Gen-AI Overview of the scan
    Overview = new OverviewSettings { Enable = true },

    // Citation Checker
    References = new ReferencesSettings { Validate = true },

    // AI Source Match (online) and Internal AI Source Match
    AISourceMatch = new AISourceMatch { Enable = true },
    InternalAISourceMatch = new InternalAISourceMatch { Enable = true },

    // PDF report time zone, and analytics ids
    ScanTimeZone = "America/New_York",
    Course = new CourseEntity { Id = "course-101" },
    Assignment = new AssignmentEntity { Id = "essay-3" },
    Institution = new InstitutionEntity { Id = "my-university" },
};

// Only compare against internal database and repository results whose scan id matches a pattern,
// and drop results that link to some domains or contain some phrases
properties.ProtectionLayersSection.Include = new ScanningInclude { IdPattern = "2026-*" };
properties.ProtectionLayersSection.Exclude.BacklinksDomains = new[] { "example.com" };
properties.ProtectionLayersSection.Exclude.Text = new[] { "lorem ipsum" };

// PDF report: pick the version and the highlight colors
properties.ReportSection.Create = true;
properties.ReportSection.ReportVersion = "latest";
properties.ReportSection.Colors = new ReportCustomizationColors { AIDetection = "#FE5758", WritingFeedback = "#FF9A02" };

The completed webhook has ReferencesValidation (Citation Checker summary) and Results.InternalAIData. Export the AI detection, Grammar Checker and overview reports with the export call:

await scansClient.ExportAsync(scanId, "export-1", new ExportRequest
{
    CompletionWebhook = new Uri("https://your-server.com/export/completed"),
    AIDetection = new ExportTask { Verb = "PUT", Endpoint = new Uri("https://your-server.com/export/ai") },
    WritingFeedback = new ExportTask { Verb = "PUT", Endpoint = new Uri("https://your-server.com/export/grammar") },
    Overview = new ExportTask { Verb = "PUT", Endpoint = new Uri("https://your-server.com/export/overview") },
    CrawledVersion = new ExportTask { Verb = "PUT", Endpoint = new Uri("https://your-server.com/export/crawled") },
}, authToken);

The uploaded files are an AIDetectionResult, a WritingAssistantResult, an OverviewResult and a DownloadSourceResponse (which includes the per-reference Citation Checker results).

If a webhook did not arrive, ask for it again (for scans that completed, failed, were indexed or were price-checked):

await scansClient.ResendWebhookAsync(scanId, authToken);

Reading the AI alert from the completed webhook

When a scan runs AI detection (clientScanProperties.AIGeneratedText.Detect = true), the completed webhook reports AI-generated text as a suspected-ai-text alert. The alert's additionalData is a JSON string, and the SDK decodes it into an AIDetectionResult.

using System;
using Copyleaks.SDK.V3.API.Models.Responses.Webhooks;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;

[ApiController]
[Route("/webhook")]
public class WebhookController : ControllerBase
{
    [HttpPost]
    [Route("completed/{scanId}")]
    public IActionResult CompletedWebhookProcessor([FromRoute] string scanId, [FromBody] CompletedWebhookModel completedWebhook)
    {
        // The first "suspected-ai-text" alert, or null when the scan produced no AI alert
        var aiAlert = completedWebhook.GetAIDetectionAlert();
        if (aiAlert != null)
        {
            try
            {
                // additionalData decoded into AIDetectionResult. Same as completedWebhook.GetAIDetectionResult().
                // null when the alert has no data; throws a Newtonsoft JsonException when additionalData is not valid JSON or does not match the AIDetectionResult shape.
                var aiResult = aiAlert.GetAIDetectionResult();
                if (aiResult != null && aiResult.Summary != null)
                {
                    Console.WriteLine($"AI: {aiResult.Summary.AI:P0}, human: {aiResult.Summary.Human:P0}, model: {aiResult.ModelVersion}");
                    foreach (var section in aiResult.Results ?? new())
                    {
                        // Classification: 1 = human, 2 = AI
                        Console.WriteLine($"Classification {section.Classification}, matches: {section.Matches?.Count ?? 0}");
                    }
                }
            }
            catch (JsonException ex)
            {
                Console.Error.WriteLine($"Could not decode the AI alert of scan {scanId}: {ex.Message}");
            }
        }
        // Acknowledge the webhook even when the AI alert could not be decoded.
        return Ok();
    }
}
  • GetAIDetectionAlert() returns null when the completed webhook contains no suspected-ai-text alert.
  • GetAIDetectionResult() returns null when the alert has no data or when the data is valid JSON that is not a JSON object. It throws a Newtonsoft JsonException when additionalData is not valid JSON or does not match the AIDetectionResult shape. The raw string stays available in aiAlert.AdditionalData.
  • The legacy CompletedCallback model has the same GetAIDetectionResult() method on each AlertNotification.

For more details, refer to the Copyleaks scan completed webhook Documentation

AI Text Detection

Use the AI detection client to determine if content was generated by artificial intelligence.

using System;
using System.Threading.Tasks;
using Copyleaks.SDK.V3.API;
using Copyleaks.SDK.V3.API.Models.Requests.AIDetection;

public class Program
{
    // --- Your Credentials ---
    private const string USER_EMAIL = "YOUR_EMAIL_ADDRESS";
    private const string USER_KEY = "YOUR_API_KEY";
    // --------------------

    public static async Task Main(string[] args)
    {
        var identityClient = new CopyleaksIdentityApi();
        var aiDetectionClient = new CopyleaksAIDetectionApi();

        var loginResponse = await identityClient.LoginAsync(USER_EMAIL, USER_KEY).ConfigureAwait(false);
        var authToken = loginResponse.Token;
        string scanId = Guid.NewGuid().ToString();
        var text = @"Lions are social animals, living in groups called prides, typically consisting of several females, their offspring, and a few males. Female lions are the primary hunters, working together to catch prey. Lions are known for their strength, teamwork, and complex social structures.";

        var naturalLanguageDocument = new NaturalLanguageDocument()
        {
            Text = text,
            Sandbox = true,
            Explain = true,     // AI Logic (optional)
            Sensitivity = 2,    // 1 to 3 (optional)
        };

        var res = await aiDetectionClient.SubmitNaturalLanguageAsync(scanId, naturalLanguageDocument, authToken).ConfigureAwait(false);
        Console.WriteLine($"AI: {res.Summary.AI:P0}");

        // The AI Text Detection credit balance, and the file types AI detection supports in scans
        uint aiCredits = await aiDetectionClient.CreditBalanceAsync(authToken);
        var aiFileTypes = await aiDetectionClient.GetSupportedFileTypesAsync(); // no login needed
    }
}

For a full guide please refer to our step by step Guide

For a detailed understanding of the AI Text Detection process, refer to the Copyleaks detect natural language Endpoint Documentation

Grammar Checker (CopyleaksWritingAssistantApi)

Get intelligent suggestions for improving grammar, spelling, style, and overall writing quality.

using System;
using System.Threading.Tasks;
using Copyleaks.SDK.V3.API;
using Copyleaks.SDK.V3.API.Models.Requests.WritingAssistant;

public class Program
{
    // --- Your Credentials ---
    private const string USER_EMAIL = "YOUR_EMAIL_ADDRESS";
    private const string USER_KEY = "YOUR_API_KEY";
    // --------------------

    public static async Task Main(string[] args)
    {
        var identityClient = new CopyleaksIdentityApi();
        var writingAssistantClient = new CopyleaksWritingAssistantApi();

        var loginResponse = await identityClient.LoginAsync(USER_EMAIL, USER_KEY).ConfigureAwait(false);
        var authToken = loginResponse.Token;
        string scanId = Guid.NewGuid().ToString();
        var text = @"Lions are the only cat that live in groups, called pride. A prides typically consists of a few adult males, several feales, and their offspring. This social structure is essential for hunting and raising young cubs. Female lions, or lionesses are the primary hunters of the prid. They work together in cordinated groups to take down prey usually targeting large herbiores like zbras, wildebeest and buffalo. Their teamwork and strategy during hunts highlight the intelligence and coperation that are key to their survival.";

        var document = new WritingAssistantDocument()
        {
            Sandbox = true,
            Text = text,
            // Optional. Every weight you do not set stays at 1.0.
            Score = new Score()
            {
                SentenceStructureScoreWeight = 0.2,
                GrammarScoreWeight = 0.3,
                MechanicsScoreWeight = 0.4,
                WordChoiceScoreWeight = 0.5,
            },
        };

        var res = await writingAssistantClient.SubmitTextAsync(scanId, document, authToken).ConfigureAwait(false);

        // The correction types are public, so no login is needed
        var correctionTypes = await writingAssistantClient.GetCorrectionTypesAsync("en");
    }
}

For a full guide please refer to our step by step Guide

For a detailed understanding of the Grammar Checker (CopyleaksWritingAssistantApi) process, refer to the Copyleaks writing feedback Endpoint Documentation

Text Moderation

Scan and moderate text content for unsafe, inappropriate, or policy-violating material across various categories. Send between 1 and 16 labels.

using System;
using System.Threading.Tasks;
using Copyleaks.SDK.V3.API;
using Copyleaks.SDK.V3.API.Models.Constants;
using Copyleaks.SDK.V3.API.Models.Requests.TextModeration;

public class Program
{
    // --- Your Credentials ---
    private const string USER_EMAIL = "YOUR_EMAIL_ADDRESS";
    private const string USER_KEY = "YOUR_API_KEY";
    // --------------------

    public static async Task Main(string[] args)
    {
        var identityClient = new CopyleaksIdentityApi();
        var textModerationClient = new CopyleaksTextModerationApi();

        var loginResponse = await identityClient.LoginAsync(USER_EMAIL, USER_KEY).ConfigureAwait(false);
        var authToken = loginResponse.Token;
        string scanId = Guid.NewGuid().ToString();

        var labelsArray = new CopyleaksTextModerationLabel[]
        {
            new CopyleaksTextModerationLabel(CopyleaksTextModerationConstants.ADULT_V1),
            new CopyleaksTextModerationLabel(CopyleaksTextModerationConstants.TOXIC_V1),
            new CopyleaksTextModerationLabel(CopyleaksTextModerationConstants.VIOLENT_V1),
            new CopyleaksTextModerationLabel(CopyleaksTextModerationConstants.PROFANITY_V1),
            new CopyleaksTextModerationLabel(CopyleaksTextModerationConstants.SELF_HARM_V1),
            new CopyleaksTextModerationLabel(CopyleaksTextModerationConstants.HARASSMENT_V1),
            new CopyleaksTextModerationLabel(CopyleaksTextModerationConstants.HATE_SPEECH_V1),
            new CopyleaksTextModerationLabel(CopyleaksTextModerationConstants.DRUGS_V1),
            new CopyleaksTextModerationLabel(CopyleaksTextModerationConstants.FIREARMS_V1),
            new CopyleaksTextModerationLabel(CopyleaksTextModerationConstants.CYBERSECURITY_V1)
        };

        var model = new CopyleaksTextModerationRequestModel(
            text: "This is some text to scan.",
            sandbox: true,
            language: CopyleaksTextModerationLanguages.ENGLISH,
            labels: labelsArray
        );

        var result = await textModerationClient.SubmitTextAsync(scanId, model, authToken).ConfigureAwait(false);
    }
}

For a full guide please refer to our step by step Guide

For a detailed understanding of the Text moderation process, refer to the Copyleaks text moderation Endpoint Documentation

AI Image Detection

Determine if a given image was generated or partially generated by an AI.

using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Copyleaks.SDK.V3.API;
using Copyleaks.SDK.V3.API.Models.Constants;
using Copyleaks.SDK.V3.API.Models.Requests.AiImageDetection;

public class Program
{
    // --- Your Credentials ---
    private const string USER_EMAIL = "YOUR_EMAIL_ADDRESS";
    private const string USER_KEY = "YOUR_API_KEY";
    // --------------------

    public static async Task Main(string[] args)
    {
        var identityClient = new CopyleaksIdentityApi();
        var imageDetectionClient = new CopyleaksAiImageDetectionApi();

        var loginResponse = await identityClient.LoginAsync(USER_EMAIL, USER_KEY).ConfigureAwait(false);
        var authToken = loginResponse.Token;
        string scanId = Guid.NewGuid().ToString();

        // Upload the image as a file (recommended: no base64 overhead)
        var model = new CopyleaksAiImageDetectionRequestModel(
            fileName: "my-image.png",
            model: CopyleaksAiImageDetectionModels.AI_IMAGE_1_ULTRA,
            sandbox: true)
        {
            MaskType = CopyleaksAiImageMaskTypes.HEATMAP,     // optional: "binary" (default), "heatmap" or "none"
            ObjectDetection = new List<CopyleaksAiImageObjectDetectionItem>   // optional: up to 3 objects
            {
                new CopyleaksAiImageObjectDetectionItem("face"),
            },
        };

        using (var image = File.OpenRead("PATH TO YOUR IMAGE"))
        {
            var result = await imageDetectionClient.SubmitFileAsync(scanId, image, model, authToken).ConfigureAwait(false);
            Console.WriteLine($"AI detected: {result.IsAiDetected}, AI share: {result.Summary.Ai:P0}");
        }

        // Or send base64 JSON, as before:
        // var json = new CopyleaksAiImageDetectionRequestModel(base64Image, "my-image.png", CopyleaksAiImageDetectionModels.AI_IMAGE_1_ULTRA, sandbox: true);
        // var result = await imageDetectionClient.SubmitAsync(scanId, json, authToken);
    }
}

To analyze an image URL asynchronously, submit it and receive the result on your webhook (with the same shape as CopyleaksAiImageDetectionResponseModel):

using Copyleaks.SDK.V3.API.Models.Requests.Shared;

await imageDetectionClient.SubmitUrlAsync(scanId, new CopyleaksAiImageDetectionAsyncRequestModel
{
    Url = new Uri("https://example.com/image1.png"),
    FileName = "image1.png",
    Model = CopyleaksAiImageDetectionModels.AI_IMAGE_1_ULTRA,
    Webhooks = new CopyleaksAsyncWebhooks { Url = new Uri("https://your-server.com/webhook/ai-image") },
    Sandbox = true,
}, authToken);

If the asynchronous detection failed, the webhook body has Error (Type, Id, Code, Message, and the optional Url and Details) instead of the result, so check Error first. DeveloperPayload echoes the value from the submit request.

For a full guide please refer to our step by step Guide

For a detailed understanding of the AI Image Detection process, refer to the Copyleaks image detection Endpoint Documentation

AI Video Detection

Submit a video URL. The result is posted to your webhook as a CopyleaksAiVideoDetectionResponseModel.

using Copyleaks.SDK.V3.API;
using Copyleaks.SDK.V3.API.Models.Constants;
using Copyleaks.SDK.V3.API.Models.Requests.AiVideoDetection;
using Copyleaks.SDK.V3.API.Models.Requests.Shared;

var videoClient = new CopyleaksAiVideoDetectionApi();
await videoClient.SubmitAsync("my-video-scan-1", new CopyleaksAiVideoDetectionRequestModel
{
    Url = new Uri("https://example.com/my-video.mp4"),
    Filename = "my-video.mp4",
    Model = CopyleaksAiVideoDetectionModels.AI_VIDEO_1_PRO,
    Webhooks = new CopyleaksAsyncWebhooks { Url = new Uri("https://your-server.com/webhook/ai-video") },
    Sandbox = true,
}, authToken);

In your webhook, read the body as a CopyleaksAiVideoDetectionResponseModel (namespace Copyleaks.SDK.V3.API.Models.Responses.AiVideoDetection). Check Error first: when the detection failed, the body has only Error (Type, Id, Code, Message, and the optional Url and Details) and DeveloperPayload, which echoes the value from the submit request.

var result = JsonConvert.DeserializeObject<CopyleaksAiVideoDetectionResponseModel>(body);
if (result.Error != null)
    Console.WriteLine($"Detection failed: {result.Error.Id} ({result.Error.Code}): {result.Error.Message}");
else
    Console.WriteLine($"AI detected: {result.IsAiDetected}, overall AI share: {result.Summary.OverallAIRatio:P0}");

For a detailed understanding of the AI Video Detection process, refer to the Copyleaks AI video detection Endpoint Documentation

Image Plagiarism Detection

Search the web for copies of an image, in one synchronous call.

using Copyleaks.SDK.V3.API;
using Copyleaks.SDK.V3.API.Models.Requests.ImagePlagiarism;

var imagePlagiarismClient = new CopyleaksImagePlagiarismApi();
using (var image = File.OpenRead("my-photo.jpg"))
{
    var result = await imagePlagiarismClient.SubmitAsync("my-scan-1", image,
        new CopyleaksImagePlagiarismRequestModel("my-photo.jpg", sandbox: true), authToken);

    Console.WriteLine($"Total matches: {result.Matches.Score.TotalMatches}");
    foreach (var match in result.Matches.Internet)
        Console.WriteLine($"{(match.MatchType == 0 ? "Full" : "Partial")} match: {match.Url}");
}

For a detailed understanding of the Image Plagiarism Detection process, refer to the Copyleaks image plagiarism Endpoint Documentation

Account and lookup calls

var scansClient = new CopyleaksScansApi();

uint credits = await scansClient.CreditBalanceAsync(authToken);

// Private Cloud Hub repository information (requires the Admin or Super Admin role)
var repository = await scansClient.GetRepositoryInfoAsync("my-repository-id", authToken);

// Public lookups, no login needed
var fileTypes = await scansClient.GetSupportedFileTypesAsync();
string[] ocrLanguages = await scansClient.GetOcrLanguageListAsync();
var crossLanguages = await scansClient.GetAllowedCrossLanguagesAsync();   // codes in crossLanguages.ResultLanguageCodes
var releaseNotes = await scansClient.GetReleaseNotesAsync();

Further Resources

  • Copyleaks API Dashboard: Manage your API keys, monitor usage, and view analytics from your personalized dashboard. Access Dashboard
  • Copyleaks SDK Documentation: Explore comprehensive guides, API references, and code examples for seamless integration. Read Documentation

Support

  • If you need assistance, please contact Copyleaks Support via our support portal: Contact Copyleaks Support.
  • To arrange a product demonstration, book a demo here: Booking Link.
Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
5.0.0 7 11/3/2026
4.1.0 956 9/30/2025
4.0.0 333 8/31/2025
3.2.0 870 8/7/2025
3.1.1 290 8/4/2025
3.1.0 491 7/10/2025
3.0.0 287 7/2/2025
2.3.1 8,714 5/13/2025
2.3.0 399 5/12/2025
2.2.0 4,410 9/12/2024
2.1.1 12,096 6/8/2023
2.1.0 7,348 6/6/2023
2.0.1 1,220 5/8/2023
2.0.0 372 5/4/2023
1.9.4 3,982 12/20/2022
1.9.3 2,188 12/8/2022
1.9.2 513 12/8/2022
1.9.1 1,314 6/13/2022
1.9.0 692 6/12/2022
1.8.5 16,132 7/5/2021
Loading failed