# Assess Writing in Documents

> A comprehensive guide to using the Copyleaks Grammar Checker API for assessing writing in documents.

The Copyleaks Grammar Checker API is a powerful tool to help improve the quality of written content by providing detailed feedback on grammar, spelling, sentence structure, and word choice. 

This guide will walk you through the process of submitting documents for writing assessment and retrieving the detailed feedback.

## Get started

<Steps>
  <Step>
    ### Before you begin
    Before you start, ensure you have the following:
    - An active Copyleaks account. If you don't have one, **[sign up for free](https://api.copyleaks.com/signup)**.
    - You can find your API key on the **[API Dashboard](https://api.copyleaks.com/dashboard)**.
  </Step>

  <Step>
    ### Installation
    <InstallSDKs />
  </Step>

  <Step>
    ### Login
    <GuideLogin />
  </Step>

  <Step>
    ### Submit for writing assessment
    <SubmissionMethods />
    
    For this guide, we'll demonstrate document submission for writing assessment. Each submission requires a unique `scanId` for proper tracking and identification.
    
    <Note title="File Submission Requirements">
    - **Filename:** The file extension in the `filename` parameter must match your document type (e.g., `.pdf`, `.docx`, `.txt`). See the
     full [list of supported file types](/reference/actions/miscellaneous/supported-plagiarism-file-types).
    - **Content Encoding:** The file content must be Base64 encoded and sent in the `base64` property.
    </Note>
    
    <Note>
    **What is Base64 Encoding?**

    Base64 converts binary files into text strings so they can be sent via JSON. All programming languages have built-in Base64 encoding functions, see the code examples below for your language.
    </Note>
    
    <Tip>
    For testing, set `"sandbox": true`. Sandbox mode is free and returns mock results. <br/>
    To enable writing assessment, ensure `"writingFeedback": {"enable": true}` is set in your properties.
    </Tip>
    
    <CodeGroup>
        ```http title="HTTP" icon="globe"
        PUT https://api.copyleaks.com/v3/scans/submit/file/my-writing-assessment-scan
        Content-Type: application/json
        Authorization: Bearer YOUR_LOGIN_TOKEN
        
        {
          "base64": "SGVsbG8gd29ybGQuIFRoaXMgaXMgYW4gZXhhbXBsZSB0ZXh0IHRvIGJlIGNoZWNrZWQgZm9yIGdyYW1tYXIgZXJyb3JzLg==",
          "filename": "my-document.txt",
          "properties": {
            "sandbox": true,
            "webhooks": {
              "status": "https://your.server/webhook/{STATUS}"
            },
            "writingFeedback": {
              "enable": true
            }
          }
        }
        ```
      ```bash title="cURL" icon="terminal"
      # First, encode your file to base64
      base64_content=$(base64 -w 0 my-document.docx)
      
      curl -X PUT "https://api.copyleaks.com/v3/scans/submit/file/my-writing-assessment-scan" \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer YOUR_LOGIN_TOKEN" \
        -d '{
          "base64": "'$base64_content'",
          "filename": "my-document.docx",
          "properties": {
            "sandbox": true,
            "webhooks": {
              "status": "https://your.server/webhook/{STATUS}"
            },
            "writingFeedback": {
              "enable": true
            }
          }
        }'
      ```
      ```python title="Python" icon="python"
      import base64
      import random
      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
      from copyleaks.models.submit.properties.writing_feedback import WritingFeedback

      print("Submitting a document for writing assessment...")
      
      # Read and encode the file
      with open('my-document.docx', 'rb') as file:
          file_content = file.read()
          base64_file_content = base64.b64encode(file_content).decode('utf8')
      
      # Generate a random scan ID or use a meaningful identifier
      scan_id = f"writing-scan-{random.randint(100, 100000)}"
      
      # Create a file submission
      file_submission = FileDocument(base64_file_content, "my-document.docx")
      
      # Configure Grammar Checker
      writing_feedback = WritingFeedback()
      writing_feedback.enable = True
      
      # Configure webhooks for notifications
      webhooks = SubmitWebhooks()
      webhooks.set_status('https://your.server/webhook/{STATUS}')
      
      # Set up scan properties
      scan_properties = ScanProperties(status_webhook='https://your.server/webhook/{STATUS}')
      scan_properties.set_webhooks(webhooks)
      scan_properties.set_writing_feedback(writing_feedback)
      scan_properties.set_sandbox(True)  # Turn on sandbox mode. Turn off on production.
      
      # Add properties to the submission
      file_submission.set_properties(scan_properties)
      
      # Submit the document for assessment
      Copyleaks.submit_file(auth_token, scan_id, file_submission)
      print("Document sent for writing assessment")
      print("You will be notified via webhook when the assessment completes.")
      ```
      ```javascript title="JavaScript" icon="square-js"
      const { Copyleaks, CopyleaksFileSubmissionModel } = require('plagiarism-checker');
      const fs = require('fs');

      async function submitForWritingAssessment() {
        try {
          // Read the file and encode it as base64
          const fileContent = fs.readFileSync('my-document.docx');
          const base64Content = fileContent.toString('base64');
          
          // Generate a unique scan ID
          const scanId = `writing-scan-${Date.now()}`;
          
          // Create the submission properties
          const properties = {
            sandbox: true,  // Set to false in production
            webhooks: {
              status: 'https://your.server/webhook/{STATUS}'
            },
            writingFeedback: {
              enable: true,
              // Optionally customize scoring weights
              score: {
                grammarScoreWeight: 1.0,
                mechanicsScoreWeight: 1.0,
                sentenceStructureScoreWeight: 1.0,
                wordChoiceScoreWeight: 1.0
              }
            }
          };
          
          // Create the submission model
          const submission = new CopyleaksFileSubmissionModel(
            base64Content,
            'my-document.docx',
            properties
          );
          
          // Get authentication token
          const loginResult = await Copyleaks.login(EMAIL, API_KEY);
          const authToken = loginResult.access_token;
          
          // Submit the document for assessment
          await Copyleaks.submitFile(authToken, scanId, submission);
          console.log(`Document submitted for writing assessment with scan ID: ${scanId}`);
          console.log('You will be notified via webhook when the assessment completes.');
        } catch (error) {
          console.error('Error submitting document:', error);
        }
      }

      submitForWritingAssessment();
      ```
      ```java title="Java" icon="java"
      import classes.Copyleaks;
      import models.submissions.CopyleaksFileSubmissionModel;
      import models.submissions.properties.*;
      import java.util.Base64;
      import java.nio.file.Files;
      import java.nio.file.Paths;
      import java.io.IOException;

      public class WritingAssessmentExample {
          public static void main(String[] args) {
              try {
                  // Read the file and encode it as base64
                  byte[] fileBytes = Files.readAllBytes(Paths.get("my-document.docx"));
                  String base64Content = Base64.getEncoder().encodeToString(fileBytes);
                  
                  // Set scan ID
                  String scanId = "writing-scan-" + System.currentTimeMillis();
                  
                  // Configure webhooks
                  SubmissionWebhooks webhooks = new SubmissionWebhooks("https://your.server/webhook/{STATUS}");
                  
                  // Create submission properties
                  SubmissionProperties properties = new SubmissionProperties(webhooks);
                  properties.setSandbox(true);  // Set to false in production
                  
                  // Enable writing feedback
                  WritingFeedback writingFeedback = new WritingFeedback();
                  writingFeedback.setEnable(true);
                  properties.setWritingFeedback(writingFeedback);
                  
                  // Create and submit the file
                  CopyleaksFileSubmissionModel submission = new CopyleaksFileSubmissionModel(
                      base64Content, 
                      "my-document.docx", 
                      properties
                  );
                  
                  // Submit the document
                  Copyleaks.submitFile(authToken, scanId, submission);
                  System.out.println("Document sent for writing assessment with scan ID: " + scanId);
                  System.out.println("You will be notified via webhook when the assessment completes.");
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
      }
      ```
    </CodeGroup>
  </Step>

  <Step>
    ### Wait for the completion webhook
    Once the scan is complete, Copyleaks will send a [completed webhook](/reference/data-types/authenticity/webhooks/scan-completed) to the status URL you provided.

    When Grammar Checker is enabled, the webhook response will include a `writingFeedback` section with detailed information about the writing quality.

    <Note title="Webhook Response Reference">
    For complete details on the webhook response structure, see the [Scan Completed Webhook Reference](/reference/data-types/authenticity/webhooks/scan-completed).
    </Note>
  </Step>

  <Step>
    ### Interpreting writing assessment results
    The completed webhook contains a `writingFeedback` object with the [Correction Types](/reference/data-types/writing/correction-types):
    
    1. **textStatistics**: Basic metrics about the text, including sentence count, average word and sentence length, and estimated reading time.
    
    2. **score**: Detailed breakdown of writing quality across four categories:
       - Grammar
       - Mechanics (spelling, punctuation)
       - Sentence Structure
       - Word Choice
       
       Each category includes both a count of corrections and a score (0-100).
    
    3. **readability**: An assessment of how easy the text is to read, including:
       - Overall readability score (0-100)
       - Readability level (grade level)
       - Text description of the readability
  </Step>

  <Step>
    ### Export detailed results
    To get the specific writing corrections, you need to export the detailed results using the [export endpoint](/reference/actions/downloads/export):

    <CodeGroup>
        ```http title="HTTP" icon="globe"
        POST https://api.copyleaks.com/v3/downloads/my-writing-assessment-scan/export/my-export-1
        Content-Type: application/json
        Authorization: Bearer YOUR_LOGIN_TOKEN
        
        {
          "writingFeedback": {
            "corrections": true,
            "verb": "POST",
            "headers": [
              ["Content-Type", "application/json"]
            ],
            "endpoint": "https://your.server/export/writing-feedback"
          },
          "completionWebhook": "https://your.server/webhook/export/completion",
          "maxRetries": 3,
          "developerPayload": "writing-assessment-export"
        }
        ```
      ```bash title="cURL" icon="terminal"
      curl -X POST "https://api.copyleaks.com/v3/downloads/my-writing-assessment-scan/export/my-export-1" \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer YOUR_LOGIN_TOKEN" \
        -d '{
          "writingFeedback": {
            "corrections": true,
            "verb": "POST",
            "headers": [
              ["Content-Type", "application/json"]
            ],
            "endpoint": "https://your.server/export/writing-feedback"
          },
          "completionWebhook": "https://your.server/webhook/export/completion",
          "maxRetries": 3,
          "developerPayload": "writing-assessment-export"
        }'
      ```
      ```python title="Python" icon="python"
      from copyleaks.copyleaks import Copyleaks
      from copyleaks.models.export import Export, ExportResults, WritingFeedbackExport
      from copyleaks.models.export.http_method import HttpMethod
      from copyleaks.models.export.endpoint import Endpoint

      # Set up the export
      export_id = "my-export-1"
      
      # Configure what to export
      export = Export()
      export.set_completion_webhook('https://your.server/webhook/export/completion')
      
      # Add optional parameters
      export.set_max_retries(3)  # Default is 3, can be 1-12
      export.set_developer_payload("writing-assessment-export")  # Custom identifier
      
      # Request writing feedback corrections with endpoint
      writing_feedback = WritingFeedbackExport()
      writing_feedback.set_corrections(True)
      writing_feedback.set_endpoint(Endpoint(
          HttpMethod.POST, 
          "https://your.server/export/writing-feedback",
          [["Content-Type", "application/json"]]
      ))
      export.set_writing_feedback(writing_feedback)
      
      # Start the export process
      Copyleaks.export(auth_token, scan_id, export_id, export)
      print(f"Export requested with ID: {export_id}")
      print("You will be notified via webhook when the export is ready.")
      ```
      ```javascript title="JavaScript" icon="square-js"
      const { Copyleaks, CopyleaksExportModel } = require('plagiarism-checker');

      async function exportWritingFeedback() {
        try {
          const scanId = 'my-writing-assessment-scan';
          const exportId = 'my-export-1';
          
          // Configure the export
          const exportRequest = {
            writingFeedback: {
              corrections: true,
              verb: "POST",
              headers: [
                ["Content-Type", "application/json"]
              ],
              endpoint: "https://your.server/export/writing-feedback"
            },
            completionWebhook: 'https://your.server/webhook/export/completion',
            maxRetries: 3,  // Default is 3, can be 1-12
            developerPayload: "writing-assessment-export"  // Custom identifier
          };
          
          // Get authentication token
          const loginResult = await Copyleaks.login(EMAIL, API_KEY);
          const authToken = loginResult.access_token;
          
          // Request the export
          await Copyleaks.export(authToken, scanId, exportId, exportRequest);
          console.log(`Export requested with ID: ${exportId}`);
          console.log('You will be notified via webhook when the export is ready.');
        } catch (error) {
          console.error('Error exporting results:', error);
        }
      }

      exportWritingFeedback();
      ```
      ```java title="Java" icon="java"
      import classes.Copyleaks;
      import models.exports.*;
      import java.util.ArrayList;
      import java.util.List;
      
      public class ExportWritingFeedbackExample {
          public static void main(String[] args) {
              try {
                  String scanId = "my-writing-assessment-scan";
                  String exportId = "my-export-1";
                  
                  // Create headers for endpoints
                  List<EndpointHeader> headers = new ArrayList<>();
                  headers.add(new EndpointHeader("Content-Type", "application/json"));
                  
                  // Configure writing feedback export with endpoint
                  WritingFeedbackExport writingFeedback = new WritingFeedbackExport();
                  writingFeedback.setCorrections(true);
                  writingFeedback.setEndpoint(
                      new ExportEndpoint(
                          HttpMethod.POST,
                          "https://your.server/export/writing-feedback",
                          headers
                      )
                  );
                  
                  // Create complete export request
                  CopyleaksExportModel export = new CopyleaksExportModel();
                  export.setCompletionWebhook("https://your.server/webhook/export/completion");
                  export.setWritingFeedback(writingFeedback);
                  
                  // Add optional parameters
                  export.setMaxRetries(3);  // Default is 3, can be 1-12
                  export.setDeveloperPayload("writing-assessment-export");  // Custom identifier
                  
                  // Request the export
                  Copyleaks.export(authToken, scanId, exportId, export);
                  System.out.println("Export requested with ID: " + exportId);
                  System.out.println("You will be notified via webhook when the export is ready.");
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
      }
      ```
    </CodeGroup>
  </Step>

  <Step>
    ### Summary
    You have successfully submitted a document for writing assessment and exported the detailed correction recommendations. You can now integrate these corrections into your application, display them to users, or use them to improve the document's quality.
  </Step>
</Steps>

## Next steps

<CardGroup cols={2}>
    <Card title="API Reference" icon="code" href="/reference/actions/overview">View the complete API reference for the Grammar Checker endpoints.</Card>
    <Card title="Grammar Checker Response" icon="brackets-curly" href="/reference/data-types/writing/writing-assistant">Learn about the detailed structure of Grammar Checker data, including corrections and scores.</Card>
    <Card title="Ways to Integrate the Report" icon="browser" href="/concepts/features/how-to-display">Explore different ways to integrate writing feedback into your applications.</Card>
    <Card title="Learn About Webhooks" icon="plug" href="/reference/data-types/authenticity/webhooks/overview">Understand how to use webhooks to receive notifications about scan completions and results.</Card>
</CardGroup>
