# Submit File

> Scan files to find where the content has been used elsewhere and check its originality.

<RequestExample>

```bash title="cURL" icon="terminal"
curl --request PUT \
  --url https://api.copyleaks.com/v3/scans/submit/file/my-scan-123 \
  --header 'Authorization: Bearer YOUR_LOGIN_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{
    "base64": "SGVsbG8gd29ybGQh",
    "filename": "file.txt",
    "properties": {
      "webhooks": {
        "status": "https://my-server.com/webhook/{STATUS}"
      },
      "sandbox": true
    }
  }'
```

```python title="Python" icon="python"
import base64
from copyleaks.copyleaks import Copyleaks
from copyleaks.models.submit.document import FileDocument
from copyleaks.models.submit.properties.scan_properties import ScanProperties
from copyleaks.models.submit.properties.submit_webhooks import SubmitWebhooks

auth_token = Copyleaks.login("your@email.address", "YOUR_API_KEY")

with open("file.txt", "rb") as f:
    b64 = base64.b64encode(f.read()).decode("utf-8")

submission = FileDocument(b64, "file.txt")
submission.set_properties(ScanProperties(
    webhooks=SubmitWebhooks(status="https://my-server.com/webhook/{STATUS}"),
    sandbox=True,
))

Copyleaks.submit_file(auth_token, "my-scan-123", submission)
```

```javascript title="JavaScript" icon="square-js"
const { Copyleaks, CopyleaksFileSubmissionModel } = require('plagiarism-checker');
const fs = require('fs');

const copyleaks = new Copyleaks();
const auth = await copyleaks.loginAsync('YOUR_EMAIL', 'YOUR_API_KEY');

const base64Content = fs.readFileSync('file.txt').toString('base64');
const submission = new CopyleaksFileSubmissionModel(base64Content, 'file.txt', {
  sandbox: true,
  webhooks: { status: 'https://my-server.com/webhook/{STATUS}' },
});

await copyleaks.submitFileAsync(auth, 'my-scan-123', submission);
```

```java title="Java" icon="java"
import classes.Copyleaks;
import models.submissions.CopyleaksFileSubmissionModel;
import models.submissions.properties.*;
import java.util.Base64;
import java.nio.file.*;

String authToken = Copyleaks.login("your@email", "API_KEY");
String b64 = Base64.getEncoder().encodeToString(Files.readAllBytes(Paths.get("file.txt")));

SubmissionWebhooks hooks = new SubmissionWebhooks("https://my-server.com/webhook/{STATUS}");
SubmissionProperties props = new SubmissionProperties(hooks);
props.setSandbox(true);

Copyleaks.submitFile(authToken, "my-scan-123",
  new CopyleaksFileSubmissionModel(b64, "file.txt", props));
```

</RequestExample>

<ResponseExample>

```json 201 Created
{
  "scannedDocument": {
    "scanId": "scan-id32",
    "totalWords": 2,
    "totalExcluded": 0,
    "credits": 0,
    "expectedCredits": 1,
    "creationTime": "2025-08-05T07:19:08.181236Z",
    "metadata": { "filename": "file.txt" },
    "detectedLanguage": "en"
  },
  "results": {
    "score": { "aggregatedScore": 50.0, "identicalWords": 1 },
    "internet": [
      { "url": "http://example.com/", "id": "2a1b402420", "title": "Example Domain" }
    ]
  },
  "status": 0,
  "developerPayload": ""
}
```

</ResponseExample>

Scan files to find where the content has been used elsewhere and check its originality. Using submit-file you can scan various file types for plagiarism and identify copied content. See [supported formats](/reference/actions/miscellaneous/supported-plagiarism-file-types).

<Warning>
**Authentication Required.** You need to login with a user and API key in order to access this method. Add this HTTP header to your request:

**Authorization: Bearer &lt;Your-Login-Token&gt;**
</Warning>

## Request

### Path Parameters

<ParamField path="scanId" type="string" required>
  A unique scan id provided by you. We recommend you use the same id in your database to represent the scan in the Copyleaks database. This will help you to debug incidents. Using the same ID for the same file will help you to avoid network problems that may lead to multiple scans for the same file. Learn more about [the criteria for creating a Scan ID](/concepts/management/choosing-scan-id).

  `>= 3 characters` `<= 36 characters`

  Match pattern: ``[a-z0-9] !@$^&-+%=_(){}<>';:/.",~`|``
</ParamField>

### Headers

```http
Content-Type: application/json
Authorization: Bearer YOUR_LOGIN_TOKEN
```

### Request Body

The request body is a JSON object containing the file to scan.

<ParamField body="base64" type="string" required>
  A base64 data string of a file. If you would like to scan plain text, encode it as base64 and submit it.

      Example: `aGVsbG8gd29ybGQ=`
</ParamField>
<ParamField body="filename" type="string" required>
  The name of the file as it will appear in the Copyleaks scan report Make sure to include the right extension for your filetype.
      `<= 255` characters
      Example: `Myfile.pdf`
</ParamField>
<ParamField body="properties" type="object" required>
  Configuration options for the scan.
  <Expandable title="properties">
    <ScanSubmitProperties />
  </Expandable>
</ParamField>

<Note title="Integration Testing">
For testing purposes, use sandbox mode, which does not consume credits.
</Note>

## Responses

<Tabs>
  <Tab title="201">
    <Check>**201 Created** - The scan was successfully created and is now processing.</Check>

    ```json
    {
      "scannedDocument": {
        "scanId": "scan-id32",
        "totalWords": 2,
        "totalExcluded": 0,
        "credits": 0,
        "expectedCredits": 1,
        "creationTime": "2025-08-05T07:19:08.181236Z",
        "metadata": {
          "filename": "file.txt"
        },
        "enabled": {
          "plagiarismDetection": true,
          "aiDetection": false,
          "explainableAi": false,
          "writingFeedback": false,
          "pdfReport": true,
          "cheatDetection": false,
          "referencesValidation": false,
          "aiSourceMatch": false,
          "internalAiSourceMatch": false
        },
        "detectedLanguage": "en"
      },
      "results": {
        "score": {
          "identicalWords": 1,
          "minorChangedWords": 0,
          "relatedMeaningWords": 0,
          "aggregatedScore": 50.0
        },
        "internet": [
          {
            "url": "http://example.com/",
            "id": "2a1b402420",
            "title": "Example Domain",
            "introduction": "Example Domain This domain is for use in illustrative examples in documents. You may use this domain in literature without...",
            "matchedWords": 1,
            "identicalWords": 1,
            "similarWords": 0,
            "paraphrasedWords": 0,
            "totalWords": 28,
            "metadata": {
              "authors": []
            },
            "tags": []
          }
        ],
        "database": [],
        "batch": [],
        "repositories": [],
        "internalAIData": []
      },
      "notifications": {
        "alerts": [
          {
            "code": "suspected-ai-text",
            "title": "Potential AI-Generated Text Detected",
            "message": "We are unable to verify that the text was written by a human.",
            "severity": 4,
            "additionalData": "{\"results\": [{\"classification\": 2, \"probability\": 0.7307997032499992, \"matches\": [ {\"text\": {\"chars\": {\"starts\": [0], \"lengths\": [1453]}, \"words\": {\"starts\": [0], \"lengths\": [230]}}}]}], \"summary\": {\"human\": 0.0, \"ai\": 1.0}, \"modelVersion\": \"v8.0\"}",
            "category": 2
          }
        ]
      },
      "writingFeedback": {
        "textStatistics": {
          "sentenceCount": 5,
          "averageWordLength": 4.7,
          "averageSentenceLength": 12.8,
          "readingTimeSeconds": 21.0,
          "speakingTimeSeconds": 29.5
        },
        "score": {
          "grammarCorrectionsCount": 1,
          "grammarCorrectionsScore": 93,
          "grammarScoreWeight": 1.0,
          "mechanicsCorrectionsCount": 1,
          "mechanicsCorrectionsScore": 93,
          "mechanicsScoreWeight": 1.0,
          "sentenceStructureCorrectionsCount": 1,
          "sentenceStructureCorrectionsScore": 93,
          "sentenceStructureScoreWeight": 1.0,
          "wordChoiceCorrectionsCount": 0,
          "wordChoiceCorrectionsScore": 100,
          "wordChoiceScoreWeight": 1.0,
          "overallScore": 94
        },
        "readability": {
          "score": 95,
          "readabilityLevel": 1,
          "readabilityLevelText": "5th Grader",
          "readabilityLevelDescription": "Very easy to read"
        }
      },
      "status": 0,
      "developerPayload": ""
    }
    ```
  </Tab>
  <Tab title="400">
    <Warning>**400 Bad Request** - The filename field is required.</Warning>

  </Tab>
  <Tab title="401">
    <Warning>**401 Unauthorized** - Authentication failed or API key is invalid.</Warning>

  </Tab>
  <Tab title="409">
    <Warning>**409 Conflict** - A scan with the same Id already exists in the system.</Warning>

  </Tab>
  <Tab title="429">
    <Warning>**429 Too Many Requests** - Rate limit exceeded. Please retry after the specified time.</Warning>

  </Tab>
</Tabs>
