Introduction
Welcome to API Documentation: Writing Services
The writing service provides a single API layout for underlying grammar, essay, plagiarism, short answer, and statistics scoring. It also provides access to the model service. This documentation outlines the request and response objects used by all services, service-level differences in parameters used, and how validation is done for all services.
Using the Writing Service
The general format of the request and response is the same when requesting a score on any service. The available services with a score
method are: grammar, essay, plagiarism, short answer, and statistics.
The fields of the scoreSettings
object in the request body will vary between these services, allowing the user to configure their request for that particular service. Similarly, the score
object in the response body will contain different fields depending on the particular service requested by the user. These differences will be covered in further detail under the documentation for each service.
Note that when a service does not follow this format, the full request/response body will be specified in the documentation. Otherwise, only the objects of interest will be specified.
Obtaining Access
You can request an API test key by filling out the Registration Form. This key is required in the HTTP request header to authenticate your requests.
Making a Request
Once you have your API key, you can issue HTTP requests using the method specified for each service in this documentation.
HTTP Request Headers
The following headers are required for every request sent to the Writing Service API.
Header | Type | Required | Description |
---|---|---|---|
apiKey | String | Yes | Permanent secret API key for the organization to access all writing services. |
clientId | String | Yes | ID of the client organization submitting the request. Can be used for all writing services |
Content-Type | String | Yes | application/json |
HTTP Request Body Format for Scores
General format for writing service request
{
"appId":"myApplicationId",
"authorId":"myAuthorId",
"authorFullName":"Anakin Skywalker",
"authorEmail":"myemail@gmail.com",
"authorMetaData":"The Best Author",
"docId":"yyyyy",
"metaData": {
"productId":"death-star-edition-2",
"level":"1"
},
"optIn":true,
"scoreSettings":{ "Varies by service"},
"scoreType":"GRAMMAR",
"textData":"",
"textName":"",
"textFile":"",
"topicId":"testing"
}
{
"appId":"myApplicationId",
"authorId":"myAuthorId",
"authorFullName":"Anakin Skywalker",
"authorEmail":"myemail@gmail.com",
"authorMetaData":"The Best Author",
"docId":"yyyyy",
"metaData": {
"productId":"death-star-edition-2",
"level":"1"
},
"optIn":true,
"scoreSettings":{ "Varies by service"},
"scoreType":"GRAMMAR",
"textData":"",
"textName":"",
"textFile":"",
"topicId":"testing"
}
When requesting a score, use this format for the body of your HTTP request. The contents of scoreSettings
will vary between services, and you can find the configuration options for each service here in this documentation.
For HTTP Requests that do not follow this format, the documentation will specify the full expected body format instead.
Parameter | Type | Required | Description |
---|---|---|---|
appId | String | No | ID of the client application from which the request is being sent |
authorId | String | Yes | If the customer wishes to associate the request with a user/author, this parameter can be provided. If it already exists in the User table, the doc submitted will be associated with that user. If an entry does not exist for the provided authorId, a new one will be created. |
authorFullName | String | No | If the authorId provided does not exist in the User Table, following field will be used while creating the new authorId in the table. (Recommended to provide following field to associate the author full name with the authorId) |
authorEmail | String | No | If the authorId provided does not exist in the User Table, following field will be used while creating the new authorId in the table. (Recommended to provide following field to associate the author Email address with the authorId) |
authorMetaData | String | No | Following field will be used to add meta data about author while creating the new authorId |
docId | String | No | If this is a revised version of a document that has already been submitted, the previously-returned docId can be provided in the request to ensure that the versions are connected, and the new version will receive a revNum (revision number) incremented one higher than the latest version with the same docId. If a docId is not provided, a new one will be generated and returned, along with a revNum of 0. If a docId is provided that does not exist in the DB, the provided ID will be ignored and a new one will be generated. |
metaData | Object | No | Parameter that can be used to store any additional information about the request or document. |
optIn | Boolean | Yes for Plagiarism | Indicates whether the client opts to have their input text stored in the Vantage DB for analytics purposes. If false or not provided, only a checksum, input length, and (for grammar) flagged sections of the input will be stored. NOTE: for plagiarism checks, optIn is required to be true |
scoreSettings | Object | Varies by service | An object that contains parameters that are specific to each service. Some services have required parameters (like modelName for essay and short answer), while others have optional parameters |
scoreType | String | Yes | Says which service is being requested. Server side maps this request to an Enum with the values "ESSAY", "ESSAY_WITH_TUTOR", "GRAMMAR", "PLAGIARISM", "SHORT_ANSWER", "SHORT_ANSWER_WITH_TUTOR" and "STATISTICS". |
textData | String | Yes | The text content being submitted for a check. Entire content will be stored in DB if optIn is true. |
textName | String | No | May be used to provide a name for the document composed of the textData or textFile. |
textFile | File | No | Input text in file format. Currently not available for this version. |
topicId | String | No | Can be used for something like response category (sports, creative, persuasive, business, etc.), but is not used for anything right now. Mostly would be helpful for internal analytics. |
metaData
metaData
...
"metaData": {
"productId":"myProduct",
"level":"1"
}
...
...
"metaData": {
"productId":"myProduct",
"level":"1"
}
...
The metaData
field can be used to pass a JSON object that will be stored alongside your request. Use this if you want to store arbitrary data related to your request that can be queried later. If included, metaData must be a valid JSON object.
Understanding the Response
The responses for scores will use this format, and the specific contents of score
will vary depending on the service. For responses that do not return scores, they will simply return their results in the body. In each case, you can find further details here in this documentation.
HTTP Response Body Format for Scores
General format for writing service response
{
"scoreId": "yyyyy",
"docId": "zzzzz",
"revNum": 0,
"inputLength": 75,
"scoreType": "GRAMMAR",
"timestamp": "2020-02-03 19:58:15",
"totalProcessTimeMs": 9,
"completed": true,
"failCode": null,
"failMessage": null,
"score": {}
}
{
"scoreId": "yyyyy",
"docId": "zzzzz",
"revNum": 0,
"inputLength": 75,
"scoreType": "GRAMMAR",
"timestamp": "2020-02-03 19:58:15",
"totalProcessTimeMs": 9,
"completed": true,
"failCode": null,
"failMessage": null,
"score": {}
}
Parameter | Type | Description |
---|---|---|
scoreId | String | A unique ID generated for the request. Can be used to fetch the same score again on /getScore at a later date (not yet available for all services) |
docId | String | If a valid docId was provided in the request (an entry tied to the docId was found in the DB), the same docId will be returned in the response with an incremented revNum. Otherwise, a newly generated docId will be returned. |
revNum | Integer | Tied to docId. If the request did not provide a valid docId, a new one will be returned with revNum 0. If a provided docId exists in the DB, this revNum will be one higher than the previous version. Used to keep track of multiple iterations of a document, and protect against plagiarism flags on previous submissions. |
inputLength | Integer | Character length of the input text. NOTE: This will likely soon be replaced by wordCount for all services |
scoreType | String | Indicates what service provided the score. Server side maps this request to an Enum with the values "ESSAY", "GRAMMAR", "PLAGIARISM", and "SHORT_ANSWER" |
timestamp | String | Timestamp of when the score request was completed. String in format yyyy-MM-dd HH:mm:ss |
totalProcessTimeMs | Long | The amount of time it took to process the request on the server side (measured in milliseconds) |
completed | Boolean | Indicates whether the check completed successfully. If this is false, there should be a string provided in failCode |
failCode | String | If completed is false, a fail reason should be provided. The server has an Enum for failReason with values described in table in 2.1 |
failMessage | String | Additional details regarding a failed request. |
score | Object | Score object with fields that depend on the service that was called. |
Code Table - Failure Codes
Failed Response
{
"scoreId": null,
"docId": null,
"revNum": 0,
"inputLength": 0,
"scoreType": null,
"timestamp": null,
"totalProcessTimeMs": null,
"completed": false,
"failCode": "INVALID_REQUEST",
"failMessage": "JSON parse error: Duplicate field 'modelName'; ...",
"score": null
}
{
"scoreId": null,
"docId": null,
"revNum": 0,
"inputLength": 0,
"scoreType": null,
"timestamp": null,
"totalProcessTimeMs": null,
"completed": false,
"failCode": "INVALID_REQUEST",
"failMessage": "JSON parse error: Duplicate field 'modelName'; ...",
"score": null
}
Code | Service Used For | Description |
---|---|---|
INTERNAL_ERROR | All | An unexpected error has occurred. Please contact Vantage for resolution. |
INVALID_REQUEST | All | A generic error with the request. See failMessage for more details. |
ORGANIZATION_NOT_FOUND | All | The clientId provided is not associated with a registered organization. |
ORGANIZATION_NOT_SUBSCRIBED | All | The organization that sent the request does not have the requested service in its subscription. |
AUTHOR_NOT_PROVIDED | All | The authorId was not provided. |
AUTHOR_NOT_FOUND | All | The authorId provided was not associated with an existing Author. |
DOCUMENT_NOT_PROVIDED | All | The docId was not provided. |
DOCUMENT_NOT_FOUND | Plagiarism | The docId provided was not associated with an existing Document. |
SETTINGS_NOT_PROVIDED | All | The request settings were not provided. |
OUT_OF_CREDIT | All | The organization has no more credits for the service requested. |
NONEXISTANT_SERVICE | All | The service requested does not exist. Must be "ESSAY", "GRAMMAR", "PLAGIARISM", "STATISTICS" or "SHORT_ANSWER" |
NOT_OPTED_IN | Plagiarism | In order to do a plagiarism check, the user request opt in to have the text stored for comparison against future checks. |
TOO_SHORT | Plagiarism | The text in the request was too short to be analyzed for plagiarism. There must be more than 50 characters. |
IN_PROGRESS | Plagiarism | The request is still being processed. In response to getScores() when analysis in not yet complete. |
MODEL_NOT_AVAILABLE | Essay, Short_Answer | The scoring model could not be found for the given modelName. |
TEXT_DATA_NOT_PROVIDED | All | The text data was not provided. |
Grammar
POST Grammar Score
Request Endpoint
POST https://api.writeshift.com/grammar/v1/score
Request Objects
Request
{
"appId": "myApplicationId",
"authorId": "myAuthorId",
"authorFullName" : "Han Solo",
"authorEmail" : "Han@starwars.com",
"authorMetaData" : "Cadet 124-329",
"optIn": true,
"scoreSettings": {
"adviceDetailLevel": "THREE",
"adviceLanguage": "ENGLISH",
"checkLevel": 3,
"checkMode": "FULL_CHECK",
"dialect": "American",
"dialectOption": "ize",
"docLimits": {
"maxwords": 0,
"nounadj": -1,
"op_inrow": -1,
"op_inten": -1,
"prepnum": -1,
"sp_btw_sents": 0,
"split": -1
},
"docspace": {
"chk_in_quotes": false,
"end_para_char": null,
"end_para_flag": false,
"grammar_flag": false,
"linespace": 1,
"marspace": 0,
"martab": 0,
"parspace": 0,
"partab": 0
},
"formalityLevel": "Formal",
"ignoreNonEnglishInput": false,
"ignoreSeverity3": false,
"language": "American English",
"productName": "ALL",
"ruleSettingMethod": "LEVELS",
"ruleTypeMap": {},
"spellerChoice": "BASIC"
},
"scoreType": "GRAMMAR",
"textData": "There is some poeple who go to to the store.",
"topicId": "myTopicId"
}
curl --location --request POST 'https://api.writeshift.com/grammar/v1/score' \
--header 'apiKey: xxxxx' \
--header 'clientId: myClientId' \
--header 'Content-Type: application/json' \
--data-raw '{
"appId": "myApplicationId",
"authorId": "myAuthorId",
"authorFullName" : "Han Solo",
"authorEmail" : "Han@starwars.com",
"authorMetaData" : "Cadet 124-329",
"optIn": true,
"scoreSettings": {
"adviceDetailLevel": "THREE",
"adviceLanguage": "ENGLISH",
"checkLevel": 3,
"checkMode": "FULL_CHECK",
"dialect": "American",
"dialectOption": "ize",
"docLimits": {
"maxwords": 0,
"nounadj": -1,
"op_inrow": -1,
"op_inten": -1,
"prepnum": -1,
"sp_btw_sents": 0,
"split": -1
},
"docspace": {
"chk_in_quotes": false,
"end_para_char": null,
"end_para_flag": false,
"grammar_flag": false,
"linespace": 1,
"marspace": 0,
"martab": 0,
"parspace": 0,
"partab": 0
},
"formalityLevel": "Formal",
"ignoreNonEnglishInput": false,
"ignoreSeverity3": false,
"language": "American English",
"productName": "ALL",
"ruleSettingMethod": "LEVELS",
"ruleTypeMap": {},
"spellerChoice": "BASIC"
},
"scoreType": "GRAMMAR",
"textData": "There is some poeple who go to to the store.",
"topicId": "myTopicId"
}'
scoreSettings
Parameter | Type | Required | Description |
---|---|---|---|
adviceDetailLevel | String | No | Indicates how much detail should be given on the advice that comes with grammar error flags. Maps to an enum with the values "ONE", "TWO", "THREE" where ONE is least detail and THREE is most. Default: "THREE" |
adviceLanguage | String | No | The name of the language in which the grammar advice will be given. Options are "ENGLISH", "SPANISH", "FRENCH", "GERMAN", "TRADITIONAL_CHINESE", "SIMPLIFIED_CHINESE" (some advice with the Simplified Chinese selection will be English), "JAPANESE", and "KOREAN" Default: "ENGLISH" |
checkLevel | Integer | No | The level of depth that the grammar check should cover. 1 is only spelling and basic grammar rules, 2 includes more advanced grammar and syntax, and 3 includes style suggestions and highest-level/formal grammar patterns Default: 3 |
checkMode | String | No | The mode of the engine during the check. Options are "FULL_CHECK", "QUICK_CHECK", "SPELL_CHECK" and "ADVANCED_SPELL". Default: "FULL_CHECK" |
dialect | String | No | Indicates which dialect the author is writing with. Current options are "American English" and "British English". The two dialects have some slight differences in grammar and spelling rules. Default: "AMERICAN" |
dialectOption | String | No | DEPRECATED - Indicates which dialect the author is writing with. Current options are "ize" (corresponding to American English) and "ise" (corresponding to British English). Default: "ize" |
docLimitslanguage | Object | No | IGNORED - Allows user to define certain limits for a given document. The default values disable the relevant limits. "maxwords" sets the maximum amount of words allowed per sentence. "nounadj" sets the maximum number of nominal adjuncts to allow per noun phrase. "op_inrow" sets the maximum number of identical sentence openers. "op_inten" sets the maximum number of identical sentence openers within ten sentences. "prepnum" sets the maximum possible prepositional phrases in a row. "sp_btw_sents" sets the number of spaces required between sentences. "split" sets the maximum number of words in a split infinitive. Default: "maxwords": 0, "nounadj": -1, "op_inrow": -1, "op_inten": -1, "prepnum": -1, "sp_btw_sents": 0, "split": -1 |
docspace | Object | No | IGNORED - Allows user to define certain spacing parameters on a document-wide basis. "chk_in_quotes" determines whether or not the engine should check quoted text. "end_para_char" sets an end of paragraph character. "end_para_flag" is an internal flag and should not be changed. "grammar_flag" is an internal flag and should not be changed. "linespace" sets the document-wide linespacing. "marspace" sets the number of margin spaces. "martab" sets the number of margin tabs. "parspace" sets the number of paragraph spaces. "partab" sets the number of paragraph tabs. "chk_in_quotes": false, "end_para_char": null, "end_para_flag": false, "grammar_flag": false, "linespace": 1, "marspace": 0, "martab": 0, "parspace": 0, "partab": 0 |
formalityLevel | String | No | Level of formality of the text. Current options are "Formal" and "Informal". "Formal" has some more restrictive style rules, such as disallowing contractions. Default: "FORMAL" |
ignoreNonEnglishInput | Boolean | No | Determines whether the engine should detect and ignore non-English input. Default: true |
ignoreSeverity3 | Boolean | No | Allows the user to ignore rules that have been labeled "Severity 3". This is an older alternative to the checkLevel parameter, and the two should probably be combined. Default: false |
language | String | No | Toggle to differentiate American and British English. Default: "American English" |
productName | String | No | Allows the user to query the engine as if it were a certain product. Default: "ALL" |
ruleSettingMethod | String | No | Parameter that tells the engine how to determine which rules are active. Options are "CHECK_MODE", "LEVELS" and "INDIVIDUAL". Default method is determined based on the checkMode and checkLevel parameters in the request. Only select "INDIVIDUAL" if you intend to specify a custom ruleTypeMap (see below). |
ruleTypeMap | Object | No | Map of manual rule type settings to instruct the engine that certain rule types must be on or off. The map must be made up of String-Boolean pairs, with the String denoting the ruleClassID of the desired rule, and the Boolean denoting whether or not the rule should be turned on (true) or off (false). For example, if we want to turn off all punctuation-related errors within the request, we would note down the punctuation ruleClassID (22) and add it to the ruleTypeMap as follows: "22":false |
spellerChoice | String | No | The type of spell corrector to be used in the grammar check. The options are "BASIC", which is faster and does primarily statistics-based ML analysis, and "ADVANCED", which is slightly slower, adds more heavy-duty machine learning elements, and considers context in suggestions. Default: "BASIC" |
Response Objects
Response
{
"scoreId": "yyyyy",
"docId": "zzzzz",
"revNum": 0,
"inputLength": 44,
"scoreType": "GRAMMAR",
"timestamp": "2020-03-23 18:03:03",
"totalProcessTimeMs": 25,
"completed": true,
"failCode": null,
"failMessage": null,
"score": {
"count": 3,
"feedbackList": [
{
"errorId": 0,
"ruleClassId": 111,
"ruleClassCategory": "GRAMMAR",
"ruleClassName": "G_TWO_SUBJ_VERB",
"ruleClassDescription": "Agreement with 'here'/'there'",
"ruleNumber": 1,
"ruleDescription": "Clauses with 'here'/'there'",
"highlightOffset": 6,
"highlightLength": 2,
"replacementOffsetList": [],
"replacementList": [],
"englishAdviceLevels": {
"1": "The verb after \"there\" must agree in number with the following noun phrase.",
"3": "'There' and 'here' are not usually subjects of a sentence. In sentences beginning with 'there' or 'here', the true subject and verb must agree in number. The true subject is found in the predicate noun. This rule also applies to questions with 'there' and 'here'.\n\n Examples of usage:\n \n Here comes your dinner. ('Here' is an adverb; the verb is 'comes'; the subject is 'dinner'. 'Comes' agrees with 'dinner'.)\n \n There are three reasons you can't go. ('There' is a place-holder; the verb is 'are'; the subject is 'reasons'. 'Are' agrees with 'reasons'.)\n \n Have there been any phone calls for me? ('There' is a place-holder; the auxiliary verb is 'have'; the subject is 'phone calls'. 'Have' agrees with 'phone calls'.)\n \n Has there been a rash of car thefts? ('There' is a place-holder; the auxiliary verb is 'has'; the subject is 'rash'. 'Has' agrees with 'rash'.)"
},
"adviceLevels": {
"1": "The verb after \"there\" must agree in number with the following noun phrase.",
"3": "'There' and 'here' are not usually subjects of a sentence. In sentences beginning with 'there' or 'here', the true subject and verb must agree in number. The true subject is found in the predicate noun. This rule also applies to questions with 'there' and 'here'.\n\n Examples of usage:\n \n Here comes your dinner. ('Here' is an adverb; the verb is 'comes'; the subject is 'dinner'. 'Comes' agrees with 'dinner'.)\n \n There are three reasons you can't go. ('There' is a place-holder; the verb is 'are'; the subject is 'reasons'. 'Are' agrees with 'reasons'.)\n \n Have there been any phone calls for me? ('There' is a place-holder; the auxiliary verb is 'have'; the subject is 'phone calls'. 'Have' agrees with 'phone calls'.)\n \n Has there been a rash of car thefts? ('There' is a place-holder; the auxiliary verb is 'has'; the subject is 'rash'. 'Has' agrees with 'rash'.)"
}
},
{
"errorId": 1,
"ruleClassId": 1,
"ruleClassCategory": "SPELLING",
"ruleClassName": "G_SPELLING",
"ruleClassDescription": "Spelling errors",
"ruleNumber": 1,
"ruleDescription": "Words not in dictionaries",
"highlightOffset": 14,
"highlightLength": 6,
"replacementOffsetList": [
14
],
"replacementList": [
"people"
],
"englishAdviceLevels": {
"1": "The word \"poeple\" is not in the dictionary."
},
"adviceLevels": {
"1": "The word \"poeple\" is not in the dictionary."
}
},
{
"errorId": 2,
"ruleClassId": 4,
"ruleClassCategory": "GRAMMAR",
"ruleClassName": "G_DOUBLED_WORD",
"ruleClassDescription": "Doubled words",
"ruleNumber": 1,
"ruleDescription": "Doubled words",
"highlightOffset": 31,
"highlightLength": 2,
"replacementOffsetList": [],
"replacementList": [],
"englishAdviceLevels": {
"1": "Consider deleting the repeated word \"to\".",
"2": "Doubling of words is a common typographical error, but identical words in sequence may sometimes be appropriate (for example, 'I gave the plant I was allergic to to my friend').",
"3": "Although it is acceptable to use two identical words in sequence if each has its own meaning, such duplications can be confusing for the reader. You may want to rephrase the sentence to make it more comprehensible. A sentence like 'It was that that she could never forgive' might be rewritten 'That was what she could never forgive'. A sentence like 'I got what I asked for for Christmas' might become 'This Christmas I got what I asked for'."
},
"adviceLevels": {
"1": "Consider deleting the repeated word \"to\".",
"2": "Doubling of words is a common typographical error, but identical words in sequence may sometimes be appropriate (for example, 'I gave the plant I was allergic to to my friend').",
"3": "Although it is acceptable to use two identical words in sequence if each has its own meaning, such duplications can be confusing for the reader. You may want to rephrase the sentence to make it more comprehensible. A sentence like 'It was that that she could never forgive' might be rewritten 'That was what she could never forgive'. A sentence like 'I got what I asked for for Christmas' might become 'This Christmas I got what I asked for'."
}
}
]
}
}
{
"scoreId": "yyyyy",
"docId": "zzzzz",
"revNum": 0,
"inputLength": 44,
"scoreType": "GRAMMAR",
"timestamp": "2020-03-23 18:03:03",
"totalProcessTimeMs": 25,
"completed": true,
"failCode": null,
"failMessage": null,
"score": {
"count": 3,
"feedbackList": [
{
"errorId": 0,
"ruleClassId": 111,
"ruleClassCategory": "GRAMMAR",
"ruleClassName": "G_TWO_SUBJ_VERB",
"ruleClassDescription": "Agreement with 'here'/'there'",
"ruleNumber": 1,
"ruleDescription": "Clauses with 'here'/'there'",
"highlightOffset": 6,
"highlightLength": 2,
"replacementOffsetList": [],
"replacementList": [],
"englishAdviceLevels": {
"1": "The verb after \"there\" must agree in number with the following noun phrase.",
"3": "'There' and 'here' are not usually subjects of a sentence. In sentences beginning with 'there' or 'here', the true subject and verb must agree in number. The true subject is found in the predicate noun. This rule also applies to questions with 'there' and 'here'.\n\n Examples of usage:\n \n Here comes your dinner. ('Here' is an adverb; the verb is 'comes'; the subject is 'dinner'. 'Comes' agrees with 'dinner'.)\n \n There are three reasons you can't go. ('There' is a place-holder; the verb is 'are'; the subject is 'reasons'. 'Are' agrees with 'reasons'.)\n \n Have there been any phone calls for me? ('There' is a place-holder; the auxiliary verb is 'have'; the subject is 'phone calls'. 'Have' agrees with 'phone calls'.)\n \n Has there been a rash of car thefts? ('There' is a place-holder; the auxiliary verb is 'has'; the subject is 'rash'. 'Has' agrees with 'rash'.)"
},
"adviceLevels": {
"1": "The verb after \"there\" must agree in number with the following noun phrase.",
"3": "'There' and 'here' are not usually subjects of a sentence. In sentences beginning with 'there' or 'here', the true subject and verb must agree in number. The true subject is found in the predicate noun. This rule also applies to questions with 'there' and 'here'.\n\n Examples of usage:\n \n Here comes your dinner. ('Here' is an adverb; the verb is 'comes'; the subject is 'dinner'. 'Comes' agrees with 'dinner'.)\n \n There are three reasons you can't go. ('There' is a place-holder; the verb is 'are'; the subject is 'reasons'. 'Are' agrees with 'reasons'.)\n \n Have there been any phone calls for me? ('There' is a place-holder; the auxiliary verb is 'have'; the subject is 'phone calls'. 'Have' agrees with 'phone calls'.)\n \n Has there been a rash of car thefts? ('There' is a place-holder; the auxiliary verb is 'has'; the subject is 'rash'. 'Has' agrees with 'rash'.)"
}
},
{
"errorId": 1,
"ruleClassId": 1,
"ruleClassCategory": "SPELLING",
"ruleClassName": "G_SPELLING",
"ruleClassDescription": "Spelling errors",
"ruleNumber": 1,
"ruleDescription": "Words not in dictionaries",
"highlightOffset": 14,
"highlightLength": 6,
"replacementOffsetList": [
14
],
"replacementList": [
"people"
],
"englishAdviceLevels": {
"1": "The word \"poeple\" is not in the dictionary."
},
"adviceLevels": {
"1": "The word \"poeple\" is not in the dictionary."
}
},
{
"errorId": 2,
"ruleClassId": 4,
"ruleClassCategory": "GRAMMAR",
"ruleClassName": "G_DOUBLED_WORD",
"ruleClassDescription": "Doubled words",
"ruleNumber": 1,
"ruleDescription": "Doubled words",
"highlightOffset": 31,
"highlightLength": 2,
"replacementOffsetList": [],
"replacementList": [],
"englishAdviceLevels": {
"1": "Consider deleting the repeated word \"to\".",
"2": "Doubling of words is a common typographical error, but identical words in sequence may sometimes be appropriate (for example, 'I gave the plant I was allergic to to my friend').",
"3": "Although it is acceptable to use two identical words in sequence if each has its own meaning, such duplications can be confusing for the reader. You may want to rephrase the sentence to make it more comprehensible. A sentence like 'It was that that she could never forgive' might be rewritten 'That was what she could never forgive'. A sentence like 'I got what I asked for for Christmas' might become 'This Christmas I got what I asked for'."
},
"adviceLevels": {
"1": "Consider deleting the repeated word \"to\".",
"2": "Doubling of words is a common typographical error, but identical words in sequence may sometimes be appropriate (for example, 'I gave the plant I was allergic to to my friend').",
"3": "Although it is acceptable to use two identical words in sequence if each has its own meaning, such duplications can be confusing for the reader. You may want to rephrase the sentence to make it more comprehensible. A sentence like 'It was that that she could never forgive' might be rewritten 'That was what she could never forgive'. A sentence like 'I got what I asked for for Christmas' might become 'This Christmas I got what I asked for'."
}
}
]
}
}
score
Field | Type | Description |
---|---|---|
count | Integer | Number of grammar errors detected in the text |
feedbackList | List of Objects | List of feedback objects, one for each error |
feedback
Field | Type | Description |
---|---|---|
errorId | Integer | Index of the error in the list. |
ruleClassId | Integer | ID of the error category of the flagged error. |
ruleClassCategory | String | Category of the rule (SPELLING or GRAMMAR). |
ruleClassName | String | Name of the error category of the flagged error, e.g., "CAPITALIZATION". |
ruleClassDescription | String | Brief description of the error category of the flagged error, e.g., "Capitalization errors". |
ruleDescription | String | Brief description of the flagged error |
highlightOffset | Integer | Offset of the beginning of the flagged error, measured in characters from the beginning of the text. |
highlightLength | Integer | Length, in characters, of the highlighted section of the text, starting from highlightOffset. |
replacementOffsetList | List of Integers | Start offsets for the replacements in the replacementList. Should always be the same length as replacementList. In almost every case, the offset will be the same for each replacement suggestion. |
replacementList | List of Strings | List of replacement options for the highlighted text. Not all flagged errors will have replacement options. |
englishAdviceLevels | Map Integer,String | Grammar advice in English, with detail level as keys (corresponding to checkLevel in request settings). Advice may not always have every level (for example, a flagged error could have level 1 and 3 advice). |
adviceLevels | Map Integer,String | Grammar advice in user-selected advice language (corresponding to adviceLanguage in request settings), with detail level as keys. Occasionally there will be only English advice for an error, in which case this map will be empty. |
POST Client Feedback
Request Endpoint
POST https://api.writeshift.com/grammar/v1/feedback
Request Body
Request
{
"scoreId": "yyyyy",
"docId": "zzzzz",
"errorId": 3,
"ignored": false,
"replacementSelection": "manager"
}
curl --location --request POST 'https://api.writeshift.com/grammar/v1/feedback' \
--header 'apiKey: xxxxx' \
--header 'clientId: myClientId' \
--header 'Content-Type: application/json' \
--data-raw '{
"scoreId": "yyyyy",
"docId": "zzzzz",
"errorId": 3,
"ignored": false,
"replacementSelection": "manager"
}'
Parameter | Type | Required | Description |
---|---|---|---|
scoreId | String | Yes | The score Id available in the score response |
docId | String | Yes | The doc Id available in the score response |
errorId | Integer | Yes | error id from the response for which the feedback is been provided |
ignored | Boolean | Yes | If the suggested feedback was applied or ignored |
replacementSelection | String | No | The replacement suggestion that was selected |
Response Body
Response Information
"Client feedback processed."
"Client feedback processed."
A successful request will return the text: Client feedback processed.
GET Grammar Health
Request Endpoint
GET https://api.writeshift.com/grammar/v1/health
Request
https://api.writeshift.com/grammar/v1/health
curl https://api.writeshift.com/grammar/v1/health
No headers or parameters are neccesary.
Response Information
Success Response
{
"status": "UP"
}
{
"status": "UP"
}
Fail Response
{
"status": "DOWN"
}
{
"status": "DOWN"
}
Status Code | Response Body | Description |
---|---|---|
200 | {"status": "UP"} | The service is running successfully. |
503 | {"status": "DOWN"} | There is a problem with the service. |
Essay
POST Essay Score
Request Endpoint
POST https://api.writeshift.com/essayscore/v1/score
Request Objects
Request
{
"appId": "myApplicationId",
"authorId": "myAuthorId",
"authorFullName" : "Darth Sidious",
"authorEmail" : "Sidious@satrwars.com",
"authorMetaData" : "extraAuthorData",
"optIn": true,
"scoreSettings": {
"textName": "Sample Essay",
"roundScores": false,
"scoreUnscorable": false,
"modelName": "UniqueModelName",
"tutorType":"UniqueTutorName"
},
"scoreType": "ESSAY_WITH_TUTOR",
"textData": "Darth Sidious, a Force-sensitive human male, was the Dark Lord of the Sith and Galactic Emperor who ruled the galaxy from the fall of the Galactic Republic to the fragmentation of the Galactic Empire. ",
"topicId": "testing"
}
curl --location --request POST 'https://api.writeshift.com/essayscore/v1/score' \
--header 'apiKey: xxxxx' \
--header 'clientId: myClientId' \
--header 'Content-Type: application/json' \
--data-raw '{
"appId": "myApplicationId",
"authorId": "myAuthorId",
"authorFullName" : "Darth Sidious",
"authorEmail" : "Sidious@satrwars.com",
"authorMetaData" : "extraAuthorData",
"optIn": true,
"scoreSettings": {
"textName": "Sample Essay",
"roundScores": false,
"scoreUnscorable": false,
"modelName": "UniqueModelName",
"tutorType":"UniqueTutorName"
},
"scoreType": "ESSAY_WITH_TUTOR",
"textData": "Darth Sidious, a Force-sensitive human male, was the Dark Lord of the Sith and Galactic Emperor who ruled the galaxy from the fall of the Galactic Republic to the fragmentation of the Galactic Empire. ",
"topicId": "testing"
}'
scoreSettings
Parameter | Type | Required | Description |
---|---|---|---|
textName | String | No | The name of a text |
roundScores | Boolean | No | When true, holistic and dimensional scores are rounded up to the nearest integer. Default value is false. |
scoreUnscorable | Boolean | No | Provide a score for the essay even if it has an unscorable code attached. Default value is false. |
modelName | String | Yes | Name of the model to be used for the essay check. No blank accepted. |
tutorType | String | No | If the user is requesting the ESSAY_WITH_TUTOR service, this will say what kind of advice should be returned. This optional value allows an override of the default tutorType configured for the model. |
Response Objects
Successful Response
{
"scoreId": "yyyyy",
"docId": "zzzzz",
"revNum": 0,
"inputLength": 360,
"scoreType": "ESSAY",
"timestamp": "Mon Feb 10 19:02:54 UTC 2020",
"totalProcessTimeMs": 356,
"completed": true,
"failCode": null,
"failMessage": null,
"score": {
"holisticScore": 2.0,
"holisticScale": 4,
"holisticTutorFeedback": null,
"dimensionalScores": [
{
"label": "Domain 1",
"scale": 4,
"score": 2.0,
"tutorFeedback": null
},
{
"label": "Domain 2",
"scale": 4,
"score": 2.0,
"tutorFeedback": null
},
{
"label": "Domain 3",
"scale": 4,
"score": 2.0,
"tutorFeedback": null
},
{
"label": "Domain 4",
"scale": 4,
"score": 2.0,
"tutorFeedback": null
},
{
"label": "Domain 5",
"scale": 4,
"score": 2.0,
"tutorFeedback": null
}
],
"unscorableType": "OK",
"unscorableDescription": "Essay scored with no issues."
}
}
{
"scoreId": "yyyyy",
"docId": "zzzzz",
"revNum": 0,
"inputLength": 360,
"scoreType": "ESSAY",
"timestamp": "Mon Feb 10 19:02:54 UTC 2020",
"totalProcessTimeMs": 356,
"completed": true,
"failCode": null,
"failMessage": null,
"score": {
"holisticScore": 2.0,
"holisticScale": 4,
"holisticTutorFeedback": null,
"dimensionalScores": [
{
"label": "Domain 1",
"scale": 4,
"score": 2.0,
"tutorFeedback": null
},
{
"label": "Domain 2",
"scale": 4,
"score": 2.0,
"tutorFeedback": null
},
{
"label": "Domain 3",
"scale": 4,
"score": 2.0,
"tutorFeedback": null
},
{
"label": "Domain 4",
"scale": 4,
"score": 2.0,
"tutorFeedback": null
},
{
"label": "Domain 5",
"scale": 4,
"score": 2.0,
"tutorFeedback": null
}
],
"unscorableType": "OK",
"unscorableDescription": "Essay scored with no issues."
}
}
score
Parameter | Type | Description |
---|---|---|
holisticScore | Double | Overall Score of the submitted essay |
holisticScale | Integer | Scale that the overall holistic score comes from (starting at 0) |
holisticFeedback | String | If ESSAY_WITH_TUTOR was requested, this field will provide holistic feedback depending on the score and requested type of advice (see tutorType in request settings). Otherwise, this will be null. |
dimensionalScores | List of Objects | List of score objects for each dimension of the model |
unscorableType | String | Brief explanation of failure. (Refer table 4.1.2.2 for details) |
unscorableDescription | String | Sentence length description of the reason that the essay could not be scored. (Refer to "Unscorable Type Codes") |
dimensionalScores
Field | Type | Description |
---|---|---|
tutorFeedback | String | If the ESSAY_WITH_TUTOR service was requested, this field will have feedback specifically tailored to the requested type, this category, and the score range for this dimension. If feedback for this category is not available or just ESSAY was requested, this will be null. |
label | String | The category that the dimension handles, such as "Style". Most essay models have default categories, but custom models can have their own labels. |
scale | Integer | The scale on which this dimension is scored. Can vary from the holistic scale and from the scale of other dimensions, but only in custom models. |
score | Float | The score for this dimension, scored only according to the given category. |
Code Table - Unscorable Type
Unscorable Response
{
"scoreId": "yyyyy",
"docId": "zzzzz",
"revNum": 0,
"inputLength": 46,
"scoreType": "ESSAY_WITH_TUTOR",
"timestamp": "Fri Feb 07 21:55:22 UTC 2020",
"totalProcessTimeMs": 374,
"completed": true,
"failCode": null,
"failMessage": null,
"score": {
"holisticScore": -1.0,
"holisticScale": 4,
"holisticTutorFeedback": null,
"dimensionalScores": null,
"unscorableType": "TOO_SHORT",
"unscorableDescription": "Essay is too short to grade."
}
}
{
"scoreId": "yyyyy",
"docId": "zzzzz",
"revNum": 0,
"inputLength": 46,
"scoreType": "ESSAY_WITH_TUTOR",
"timestamp": "Fri Feb 07 21:55:22 UTC 2020",
"totalProcessTimeMs": 374,
"completed": true,
"failCode": null,
"failMessage": null,
"score": {
"holisticScore": -1.0,
"holisticScale": 4,
"holisticTutorFeedback": null,
"dimensionalScores": null,
"unscorableType": "TOO_SHORT",
"unscorableDescription": "Essay is too short to grade."
}
}
unscorableType | Description |
---|---|
OK | Essay scored with no issues. |
TOO_SHORT | Essay is too short to grade. |
OFF_TOPIC | Essay is off-topic. |
REPETITIOUS | Essay is repetitious. |
INSUFFICIENT_DEVELOPMENT | Essay has inadequate development |
UNKNOWN_WORDS | Essay contains too many unknown words. |
BAD_SYNTAX | Essay contains major syntax problems. |
COPIED_QUESTION | Essay substantially copied the question. |
POST Batch Score
Request Endpoint
POST https://api.writeshift.com/essayscore/v1/batchScore
Request Objects
Request
https://api.writeshift.com/essayscore/v1/batchScore?fileId={fileUUID}
curl --location --request GET 'https://api.writeshift.com/essayscore/v1/batchScore?fileId=fileUUID' \
--header 'apiKey: xxxxx' \
--header 'clientId: myClientId' \
--header 'Content-Type: application/json'
scoreSettings
Parameter | Type | Required | Description |
---|---|---|---|
fileId | UUID | Yes | UUID of the uploaded scoring file returned by the API call fileupload/directory |
textName | String | No | The name of a text |
roundScores | Boolean | No | When true, holistic and dimensional scores are rounded up to the nearest integer. Default value is false. |
scoreUnscorable | Boolean | No | Provide a score for the essay even if it has an unscorable code attached. Default value is false. |
modelName | String | Yes | Name of the model to be used for the essay check. No blank accepted. |
tutorType | String | No | If the user is requesting the ESSAY_WITH_TUTOR service, this will say what kind of advice should be returned. This optional value allows an override of the default tutorType configured for the model. |
Response Objects
Successful Response
{
"scoreId": "yyyyy",
"docId": "zzzzz",
"revNum": 0,
"inputLength": 360,
"scoreType": "ESSAY",
"timestamp": "Mon Feb 10 19:02:54 UTC 2020",
"totalProcessTimeMs": 356,
"completed": true,
"failCode": null,
"failMessage": null,
"score": {
"holisticScore": 2.0,
"holisticScale": 4,
"holisticTutorFeedback": null,
"dimensionalScores": [
{
"label": "Explanation of transformational leadership behavior types",
"scale": 4,
"score": 2.0,
"tutorFeedback": null
},
{
"label": "Organization",
"scale": 4,
"score": 2.0,
"tutorFeedback": "null
},
{
"label": "Language Mechanics, Voice, & Style",
"scale": 4,
"score": 2.0,
"tutorFeedback": null
}
],
"unscorableType": "OK",
"unscorableDescription": "Essay scored with no issues."
}
}
{
"scoreId": "yyyyy",
"docId": "zzzzz",
"revNum": 0,
"inputLength": 360,
"scoreType": "ESSAY",
"timestamp": "Mon Feb 10 19:02:54 UTC 2020",
"totalProcessTimeMs": 356,
"completed": true,
"failCode": null,
"failMessage": null,
"score": {
"holisticScore": 2.0,
"holisticScale": 4,
"holisticTutorFeedback": null,
"dimensionalScores": [
{
"label": "Explanation of transformational leadership behavior types",
"scale": 4,
"score": 2.0,
"tutorFeedback": null
},
{
"label": "Organization",
"scale": 4,
"score": 2.0,
"tutorFeedback": "null
},
{
"label": "Language Mechanics, Voice, & Style",
"scale": 4,
"score": 2.0,
"tutorFeedback": null
}
],
"unscorableType": "OK",
"unscorableDescription": "Essay scored with no issues."
}
}
score
Parameter | Type | Description |
---|---|---|
holisticScore | Double | Overall Score of the submitted essay |
holisticScale | Integer | Scale that the overall holistic score comes from (starting at 0) |
holisticFeedback | String | If ESSAY_WITH_TUTOR was requested, this field will provide holistic feedback depending on the score and requested type of advice (see tutorType in request settings). Otherwise, this will be null. |
dimensionalScores | List of Objects | List of score objects for each dimension of the model |
unscorableType | String | Brief explanation of failure. (Refer table 4.1.2.2 for details) |
unscorableDescription | String | Sentence length description of the reason that the essay could not be scored. (Refer to "Unscorable Type Codes") |
dimensionalScores
Field | Type | Description |
---|---|---|
tutorFeedback | String | If the ESSAY_WITH_TUTOR service was requested, this field will have feedback specifically tailored to the requested type, this category, and the score range for this dimension. If feedback for this category is not available or just ESSAY was requested, this will be null. |
label | String | The category that the dimension handles, such as "Style". Most essay models have default categories, but custom models can have their own labels. |
scale | Integer | The scale on which this dimension is scored. Can vary from the holistic scale and from the scale of other dimensions, but only in custom models. |
score | Float | The score for this dimension, scored only according to the given category. |
POST File Upload
Request Endpoint
POST https://api.writeshift.com/essayscore/v1/fileupload/directory
Request Objects
Request
https://api.writeshift.com/essayscore/v1/fileupload/directory
curl --location --request GET 'https://api.writeshift.com/essayscore/v1/fileupload/directory \
--header 'apiKey: xxxxx' \
--header 'clientId: myClientId' \
--header 'Content-Type: application/json'
fileSettings
Parameter | File Type | Required | Description |
---|---|---|---|
fileName | txt | Yes | Your batch scoring file |
Response Objects
Successful Response
{
"fileId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx",
"filePath": "Your_batch_essays_file_name.txt",
"failCode": null
}
{
"fileId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx",
"filePath": "Your_batch_essays_file_name.txt",
"failCode": null
}
fileInfo
Parameter | Type | Description |
---|---|---|
fileId | UUID | Your file id generated by API and use with batchScore method |
GET Essay Health
Request Endpoint
GET https://api.writeshift.com/essayscore/v1/health
Request
https://api.writeshift.com/essayscore/v1/health
curl https://api.writeshift.com/essayscore/v1/health
No headers or parameters are neccesary.
Response Information
Success Response
{
"status": "UP"
}
{
"status": "UP"
}
Fail Response
{
"status": "DOWN"
}
{
"status": "DOWN"
}
Status Code | Response Body | Description |
---|---|---|
200 | {"status": "UP"} | The service is running successfully. |
503 | {"status": "DOWN"} | There is a problem with the service. |
Audio
POST Audio File Upload
Request Endpoint
POST https://api.writeshift.com/essayscore/v1/fileupload/uploadAudioFile
Request Parameters
Request
https://api.writeshift.com/essayscore/v1/fileupload/uploadAudioFile
curl --location --request GET 'https://api.writeshift.com/essayscore/v1/fileupload/uploadAudioFile \
--header 'apiKey: xxxxx' \
--header 'clientId: myClientId' \
--header 'Content-Type: application/json'
Parameter | File Type | Required | Description |
---|---|---|---|
fileName | mp3 | Yes | Your audio file |
File name convention
scoringModel_authorId_documentId
Response Objects
Successful Response
{
"fileId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx",
"filePath": "scoringModel_authorId_documentId",
"failCode": null
}
{
"fileId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx",
"filePath": "scoringModel_authorId_documentId",
"failCode": null
}
Failed Response
{
"fileId": null,
"filePath": null,
"failCode": "INVALID_FILE_NAME"
}
{
"fileId": null,
"filePath": null,
"failCode": "INVALID_FILE_NAME"
}
fileInfo
Parameter | Type | Description |
---|---|---|
fileId | UUID | Your file id generated by API |
GET Audio File Score
Request Endpoint
GET https://api.writeshift.com/essayscore/v1/getScore
Request Parameters
Request
https://api.writeshift.com/essayscore/v1/getScore?docId={documentId}
curl --location --request GET 'https://api.writeshift.com/essayscore/v1/getScore?docId=scoringModel_authorId_documentId' \
--header 'apiKey: xxxxx' \
--header 'clientId: myClientId' \
--header 'Content-Type: application/json'
Field | Type | Required | Description |
---|---|---|---|
docId | String | Yes | The ID of the document |
The score of the audio request is unique and returns a JSON object. For more scoring details check Essay section above.
score
Parameter | Type | Description |
---|---|---|
completed | Boolean | True if finished scoring the document; false if still in progress. |
holisticScore | Double | Overall Score of the submitted transcript |
holisticScale | Integer | Scale that the overall holistic score comes from (starting at 0) |
holisticFeedback | String | This will be null if the feedback is not provided |
dimensionalScores | List of Objects | List of score objects for each dimension of the model |
unscorableType | String | Brief explanation of failure. (Refer to "Unscorable Type Codes" on Essay section for details) |
unscorableDescription | String | Sentence length description of the reason that the essay could not be scored. (Refer to "Unscorable Type Codes" on Essay section) |
Successful Response
{
"scoreId": "yyyyy",
"docId": "zzzzz",
"revNum": 0,
"inputLength": 360,
"scoreType": "ESSAY",
"timestamp": "Mon Feb 10 19:02:54 UTC 2020",
"totalProcessTimeMs": 356,
"completed": true,
"failCode": null,
"failMessage": null,
"score": {
"holisticScore": 2.0,
"holisticScale": 4,
"holisticTutorFeedback": null,
"dimensionalScores": [
{
"label": "Domain 1",
"scale": 4,
"score": 2.0,
"tutorFeedback": null
},
{
"label": "Domain 2",
"scale": 4,
"score": 2.0,
"tutorFeedback": null
},
{
"label": "Domain 3",
"scale": 4,
"score": 2.0,
"tutorFeedback": null
},
{
"label": "Domain 4",
"scale": 4,
"score": 2.0,
"tutorFeedback": null
},
{
"label": "Domain 5",
"scale": 4,
"score": 2.0,
"tutorFeedback": null
}
],
"unscorableType": "OK",
"unscorableDescription": "Essay scored with no issues."
}
}
{
"scoreId": "yyyyy",
"docId": "zzzzz",
"revNum": 0,
"inputLength": 360,
"scoreType": "ESSAY",
"timestamp": "Mon Feb 10 19:02:54 UTC 2020",
"totalProcessTimeMs": 356,
"completed": true,
"failCode": null,
"failMessage": null,
"score": {
"holisticScore": 2.0,
"holisticScale": 4,
"holisticTutorFeedback": null,
"dimensionalScores": [
{
"label": "Domain 1",
"scale": 4,
"score": 2.0,
"tutorFeedback": null
},
{
"label": "Domain 2",
"scale": 4,
"score": 2.0,
"tutorFeedback": null
},
{
"label": "Domain 3",
"scale": 4,
"score": 2.0,
"tutorFeedback": null
},
{
"label": "Domain 4",
"scale": 4,
"score": 2.0,
"tutorFeedback": null
},
{
"label": "Domain 5",
"scale": 4,
"score": 2.0,
"tutorFeedback": null
}
],
"unscorableType": "OK",
"unscorableDescription": "Essay scored with no issues."
}
}
Plagiarism
The process for obtaining a plagiarism score involves two steps.
- Send POST request with text. The response will provide an ID of the document to be check for plagiarism.
- Send GET request with ID in order to get JSON with results.
POST Plagiarism Text Submission
Request Endpoint
POST https://api.writeshift.com/plagiarism/v1/score
Alternative Credentials
Header | Type | Description |
---|---|---|
accessToken | String | A temporary access token generated with /model/v1/getAccessToken. |
Request Objects
Submission Request
{
"appId": "myApplicationId",
"authorId": "myAuthorId",
"docId": "myUniqueDocId",
"optIn": true,
"scoreSettings": {
"callbackUrl": "https://webhook.site/yyyyy"
},
"matchSources":{
"sourceType":"DOCUMENT",
"docId" :"zzzzz",
"plagPercent":50
},
"scoreType": "PLAGIARISM",
"textData": " Armstrongs first step onto the moon surface was broadcast on live TV to a worldwide audience. Since eating this bland sandwich, I start to collect the classwork to go to town. Shes an amazing person. I questioned her as to how often the power was out. \"How can the provision of consulting and advisory services be consistent with the requirements of auditor independence?\"",
"textName": "document215",
"topicId": "myTopicId"
}
curl --location --request POST 'https://api.writeshift.com/plagiarism/v1/score' \
--header 'apiKey: xxxxx' \
--header 'clientId: myClientId' \
--header 'Content-Type: application/json' \
--data-raw '{
"appId": "myApplicationId",
"authorId": "myAuthorId",
"docId": "myUniqueDocId",
"optIn": true,
"scoreSettings": {
"callbackUrl": "https://webhook.site/yyyyy"
},
"matchSources":{
"sourceType":"DOCUMENT",
"docId" :"zzzzz",
"plagPercent":50
},
"scoreType": "PLAGIARISM",
"textData": " Armstrongs first step onto the moon surface was broadcast on live TV to a worldwide audience. Since eating this bland sandwich, I start to collect the classwork to go to town. Shes an amazing person. I questioned her as to how often the power was out. \"How can the provision of consulting and advisory services be consistent with the requirements of auditor independence?\"",
"textName": "document215",
"topicId": "myTopicId"
}'
As the only asynchronous of the four services, plagiarism has a slightly different scoring procedure. Like with the other services, a Writing Service Request must be sent to /score to initiate a check. The response to this request, however, will be a simple confirmation object.
scoreSettings
Field | Type | Description |
---|---|---|
callbackUrl | String | Optional URL. When the text is finished processing, a GET request will be submitted to this URL. |
Response Body
Submission Response
{
"docId": "yyyyy",
"failMessage": null
}
{
"docId": "yyyyy",
"failMessage": null
}
The submission response is a simple confirmation oject containing the docId that can be queried to receive the full report.
Field | Type | Description |
---|---|---|
docId | String | The ID of the submitted text. This should be used to request the plagiarism score. |
failMessage | String | If the plagiarism check cannot be initiated, an explanation will be given. Otherwise, this will be null. |
Callback
Outbound GET Request from Writing Service
{
"docId": "yyyyy",
"revNum": 0,
"authorId": "authorId from request",
"status": "complete"
}
{
"docId": "yyyyy",
"revNum": 0,
"authorId": "authorId from request",
"status": "complete"
}
If the user provided a callback URL in the request, a GET request with the following format will be sent to the URL when the check is done:
Field | Type | Description |
---|---|---|
docId | String | The docId of the text being checked |
revNum | Integer | Revision number of the docId being checked |
authorId | String | Author Id from request |
status | String | This will be "complete" if the check is successful; otherwise it will have an error message. |
GET Plagiarism Report
Request Endpoint
GET https://api.writeshift.com/plagiarism/v1/getScore
Request Parameters
Request
https://api.writeshift.com/plagiarism/v1/getScore?docId={xxxxx}(&docAuthorId={myAuthorId})
curl --location --request GET 'https://api.writeshift.com/plagiarism/v1/getScore?docId=xxxxx&docAuthorId=myAuthorId' \
--header 'apiKey: xxxxx' \
--header 'clientId: myClientId' \
--header 'Content-Type: application/json'
Field | Type | Required | Description |
---|---|---|---|
docId | String | Yes | The ID of the document |
docAuthorId | String | No | The ID of the author |
Response Objects
Response
{
"scoreId":"yyyyy",
"docId":"zzzzz",
"revNum":0,
"inputLength":565,
"scoreType":"PLAGIARISM",
"timestamp":"Fri Nov 01 15:48:53 EDT 2019",
"totalProcessTimeMs":3029835399,
"completed":true,
"failCode":null,
"failMessage":null,
"score":{
"wordCount":91,
"plagWordCount":91,
"plagPercent":100.0,
"sourceCount":2,
"matchSources":[
{
"sourceId":1,
"url":"https://en.wikipedia.org/wiki/Writing",
"docId":null,
"docName":null,
"docMetaData":null,
"docAuthorId":null,
"sourceType":"WEB",
"plagPercent":100.0,
"plagWordCount":91,
"sentenceMatches":[
{
"strongestMatchAcrossSources":true,
"sentenceId":1,
"matchSourceIds":[
1,
2,
3,
4
],
"sentence":"Within a language system, writing relies on many of the same structures as speech, such as vocabulary, grammar, and semantics, with the added dependency of a system of signs or symbols",
"matched":"Within a language system writing relies on many of the same structures as speech such as vocabulary grammar and semantics with the added dependency of a system of signs or symbols <<. . .>>",
"highlightOffset":380,
"highlightLength":184,
"wordCount":31,
"longestMatchFragmentWordCount":31,
"plagWordCount":31,
"plagPercent":100.0,
"matchType":"EXACT_MATCH"
},
{
"strongestMatchAcrossSources":true,
"sentenceId":2,
"matchSourceIds":[
1,
2,
3
],
"sentence":"For languages that utilize a writing system, inscriptions can complement spoken language by creating a durable version of speech that can be stored for future reference or transmitted across distance",
"matched":"For languages that utilize a writing system inscriptions can complement spoken language by creating a durable version of speech that can be stored for future reference or transmitted across distance <<. . .>>",
"highlightOffset":92,
"highlightLength":199,
"wordCount":30,
"longestMatchFragmentWordCount":30,
"plagWordCount":30,
"plagPercent":100.0,
"matchType":"EXACT_MATCH"
},
{
"strongestMatchAcrossSources":true,
"sentenceId":3,
"matchSourceIds":[
1,
2
],
"sentence":"Writing, in other words, is not a language, but a tool used to make languages readable",
"matched":"Writing in other words is not a language but a tool used to make languages readable <<. . .>>",
"highlightOffset":293,
"highlightLength":86,
"wordCount":16,
"longestMatchFragmentWordCount":16,
"plagWordCount":16,
"plagPercent":100.0,
"matchType":"EXACT_MATCH"
},
{
"strongestMatchAcrossSources":true,
"sentenceId":4,
"matchSourceIds":[
1,
2
],
"sentence":"Writing is a medium of human communication that represents language with signs and symbols",
"matched":"Writing is a medium of human communication that represents language with signs and symbols <<. . .>>",
"highlightOffset":0,
"highlightLength":90,
"wordCount":14,
"longestMatchFragmentWordCount":14,
"plagWordCount":14,
"plagPercent":100.0,
"matchType":"EXACT_MATCH"
}
]
},
{
"sourceId":2,
"url":"https://www.upwork.com/o/profiles/users/_~01bde877105f58f806/",
"docId":null,
"docName":null,
"docMetaData":null,
"docAuthorId":null,
"sourceType":"WEB",
"plagPercent":94.51,
"plagWordCount":86,
"sentenceMatches":[
{
"sentenceId":5,
"matchSourceIds":[
1,
2,
3
],
"sentence":"For languages that utilize a writing system, inscriptions can complement spoken language by creating a durable version of speech that can be stored for future reference or transmitted across distance",
"matched":"For languages that utilize a writing system inscriptions can complement spoken language by creating a durable version of speech that can be stored for future reference or transmitted across distance <<. . .>>",
"highlightOffset":92,
"highlightLength":199,
"wordCount":30,
"longestMatchFragmentWordCount":30,
"plagWordCount":30,
"plagPercent":100.0,
"matchType":"EXACT_MATCH"
},
{
"sentenceId":6,
"matchSourceIds":[
1,
2,
3,
4
],
"sentence":"Within a language system, writing relies on many of the same structures as speech, such as vocabulary, grammar, and semantics, with the added dependency of a system of signs or symbols",
"matched":"Within a language system writing relies on many of the same structures as speech such as vocabulary grammar and semantics with the added dependency of a <<s To>>",
"highlightOffset":380,
"highlightLength":184,
"wordCount":31,
"longestMatchFragmentWordCount":26,
"plagWordCount":26,
"plagPercent":83.88,
"matchType":"PARTIAL_MATCH",
"sentenceFragments":[
{
"text":"Within a language system, writing relies on many of the same structures as speech, such as vocabulary, grammar, and semantics, with the added dependency of a",
"wordCount":26,
"fragType":"MATCH",
"highlightOffset":380,
"highlightLength":157
}
],
"matchFragments":[
{
"text":"Within a language system writing relies on many of the same structures as speech such as vocabulary grammar and semantics with the added dependency of a",
"wordCount":26,
"fragType":"MATCH"
},
{
"text":"s To",
"wordCount":2,
"fragType":"ALTERED"
}
]
},
{
"sentenceId":7,
"matchSourceIds":[
1,
2
],
"sentence":"Writing, in other words, is not a language, but a tool used to make languages readable",
"matched":"Writing in other words is not a language but a tool used to make languages readable <<. . .>>",
"highlightOffset":293,
"highlightLength":86,
"wordCount":16,
"longestMatchFragmentWordCount":16,
"plagWordCount":16,
"plagPercent":100.0,
"matchType":"EXACT_MATCH"
},
{
"sentenceId":8,
"matchSourceIds":[
1,
2
],
"sentence":"Writing is a medium of human communication that represents language with signs and symbols",
"matched":"Writing is a medium of human communication that represents language with signs and symbols <<. . .>>",
"highlightOffset":0,
"highlightLength":90,
"wordCount":14,
"longestMatchFragmentWordCount":14,
"plagWordCount":14,
"plagPercent":100.0,
"matchType":"EXACT_MATCH"
}
]
},
],
"relatedSources":[
{
"sourceType":"WEB",
"url":"https://www.quora.com/Is-there-an-optimal-language-dialect-and-medium-for-human-communication"
}
]
}
}
{
"scoreId":"yyyyy",
"docId":"zzzzz",
"revNum":0,
"inputLength":565,
"scoreType":"PLAGIARISM",
"timestamp":"Fri Nov 01 15:48:53 EDT 2019",
"totalProcessTimeMs":3029835399,
"completed":true,
"failCode":null,
"failMessage":null,
"score":{
"wordCount":91,
"plagWordCount":91,
"plagPercent":100.0,
"sourceCount":2,
"matchSources":[
{
"sourceId":1,
"url":"https://en.wikipedia.org/wiki/Writing",
"docId":null,
"docName":null,
"docMetaData":null,
"docAuthorId":null,
"sourceType":"WEB",
"plagPercent":100.0,
"plagWordCount":91,
"sentenceMatches":[
{
"strongestMatchAcrossSources":true,
"sentenceId":1,
"matchSourceIds":[
1,
2,
3,
4
],
"sentence":"Within a language system, writing relies on many of the same structures as speech, such as vocabulary, grammar, and semantics, with the added dependency of a system of signs or symbols",
"matched":"Within a language system writing relies on many of the same structures as speech such as vocabulary grammar and semantics with the added dependency of a system of signs or symbols <<. . .>>",
"highlightOffset":380,
"highlightLength":184,
"wordCount":31,
"longestMatchFragmentWordCount":31,
"plagWordCount":31,
"plagPercent":100.0,
"matchType":"EXACT_MATCH"
},
{
"strongestMatchAcrossSources":true,
"sentenceId":2,
"matchSourceIds":[
1,
2,
3
],
"sentence":"For languages that utilize a writing system, inscriptions can complement spoken language by creating a durable version of speech that can be stored for future reference or transmitted across distance",
"matched":"For languages that utilize a writing system inscriptions can complement spoken language by creating a durable version of speech that can be stored for future reference or transmitted across distance <<. . .>>",
"highlightOffset":92,
"highlightLength":199,
"wordCount":30,
"longestMatchFragmentWordCount":30,
"plagWordCount":30,
"plagPercent":100.0,
"matchType":"EXACT_MATCH"
},
{
"strongestMatchAcrossSources":true,
"sentenceId":3,
"matchSourceIds":[
1,
2
],
"sentence":"Writing, in other words, is not a language, but a tool used to make languages readable",
"matched":"Writing in other words is not a language but a tool used to make languages readable <<. . .>>",
"highlightOffset":293,
"highlightLength":86,
"wordCount":16,
"longestMatchFragmentWordCount":16,
"plagWordCount":16,
"plagPercent":100.0,
"matchType":"EXACT_MATCH"
},
{
"strongestMatchAcrossSources":true,
"sentenceId":4,
"matchSourceIds":[
1,
2
],
"sentence":"Writing is a medium of human communication that represents language with signs and symbols",
"matched":"Writing is a medium of human communication that represents language with signs and symbols <<. . .>>",
"highlightOffset":0,
"highlightLength":90,
"wordCount":14,
"longestMatchFragmentWordCount":14,
"plagWordCount":14,
"plagPercent":100.0,
"matchType":"EXACT_MATCH"
}
]
},
{
"sourceId":2,
"url":"https://www.upwork.com/o/profiles/users/_~01bde877105f58f806/",
"docId":null,
"docName":null,
"docMetaData":null,
"docAuthorId":null,
"sourceType":"WEB",
"plagPercent":94.51,
"plagWordCount":86,
"sentenceMatches":[
{
"sentenceId":5,
"matchSourceIds":[
1,
2,
3
],
"sentence":"For languages that utilize a writing system, inscriptions can complement spoken language by creating a durable version of speech that can be stored for future reference or transmitted across distance",
"matched":"For languages that utilize a writing system inscriptions can complement spoken language by creating a durable version of speech that can be stored for future reference or transmitted across distance <<. . .>>",
"highlightOffset":92,
"highlightLength":199,
"wordCount":30,
"longestMatchFragmentWordCount":30,
"plagWordCount":30,
"plagPercent":100.0,
"matchType":"EXACT_MATCH"
},
{
"sentenceId":6,
"matchSourceIds":[
1,
2,
3,
4
],
"sentence":"Within a language system, writing relies on many of the same structures as speech, such as vocabulary, grammar, and semantics, with the added dependency of a system of signs or symbols",
"matched":"Within a language system writing relies on many of the same structures as speech such as vocabulary grammar and semantics with the added dependency of a <<s To>>",
"highlightOffset":380,
"highlightLength":184,
"wordCount":31,
"longestMatchFragmentWordCount":26,
"plagWordCount":26,
"plagPercent":83.88,
"matchType":"PARTIAL_MATCH",
"sentenceFragments":[
{
"text":"Within a language system, writing relies on many of the same structures as speech, such as vocabulary, grammar, and semantics, with the added dependency of a",
"wordCount":26,
"fragType":"MATCH",
"highlightOffset":380,
"highlightLength":157
}
],
"matchFragments":[
{
"text":"Within a language system writing relies on many of the same structures as speech such as vocabulary grammar and semantics with the added dependency of a",
"wordCount":26,
"fragType":"MATCH"
},
{
"text":"s To",
"wordCount":2,
"fragType":"ALTERED"
}
]
},
{
"sentenceId":7,
"matchSourceIds":[
1,
2
],
"sentence":"Writing, in other words, is not a language, but a tool used to make languages readable",
"matched":"Writing in other words is not a language but a tool used to make languages readable <<. . .>>",
"highlightOffset":293,
"highlightLength":86,
"wordCount":16,
"longestMatchFragmentWordCount":16,
"plagWordCount":16,
"plagPercent":100.0,
"matchType":"EXACT_MATCH"
},
{
"sentenceId":8,
"matchSourceIds":[
1,
2
],
"sentence":"Writing is a medium of human communication that represents language with signs and symbols",
"matched":"Writing is a medium of human communication that represents language with signs and symbols <<. . .>>",
"highlightOffset":0,
"highlightLength":90,
"wordCount":14,
"longestMatchFragmentWordCount":14,
"plagWordCount":14,
"plagPercent":100.0,
"matchType":"EXACT_MATCH"
}
]
},
],
"relatedSources":[
{
"sourceType":"WEB",
"url":"https://www.quora.com/Is-there-an-optimal-language-dialect-and-medium-for-human-communication"
}
]
}
}
The score of the plagiarism request is unique in that is has several layered JSON objects.
score
Field | Type | Description |
---|---|---|
wordCount | Long | The number of words in the document being analyzed for plagiarism. |
plagWordCount | Long | The number of words found to be plagiarized across all sources, considering the strongest matches per sentence. |
plagPercent | Double | The percentage of words found to be plagiarized across all sources, considering the strongest matches per sentence. (0 - 100) |
sourceCount | Integer | The number of sources found with sentences matching those of the submitted document. |
matchSources | List of Objects | List of sources detected to plagiarized (Multiple sentence matches can come from a single source object. Details below |
relatedSources | List of Objects | A list of related sources, which are similar in content to the input but likely not plagiarized. Details below |
matchSources
Field | Type | Description |
---|---|---|
sourceId | Integer | Unique identifier of the source within this score. |
url | String | For "WEB" match source type. Link to the matched source found. A link will only be provided for freely available sources from the internet. |
docId | String | For "DOCUMENT" match source type. The "docId" of the document that was matched in the repository (from another user submission). |
docName | String | For "DOCUMENT" match source type. The "textName" that was associated with the repository document. |
docMetaData | String | For "DOCUMENT" match source type. The "metaData" that was associated with the repository document. |
docAuthorId | String | For "DOCUMENT" match source type. The "authorId" attached to the repository document. |
sourceType | String | Source of the plagiarism match; can be either "WEB" (from the internet) or "DOCUMENT" (from another user submission) |
plagPercent | Double | The percentage of words in the submitted document that match sentences from this source. (0 - 100) For example, if only this source is considered, this value would be the overall plagPercent. |
plagWordCount | Integer | The number of words found to be plagiarized from this source. |
sentenceMatches | List of Objects | List of sentences match objects, one for each plagiarized sentence from the provided source. |
sentenceMatches
Field | Type | Description |
---|---|---|
strongestMatchAcrossSources | Boolean | When present, this flag indicates that this sentence match was the strongest from any source and was included in the overall plagPercent of the score. For example, this property may be referenced to determine which sentences should be highlighted in the inputted text to represent the overall score. |
sentenceId | Integer | Unique identifier of the sentence within this score. |
matchSourceIds | Integer[] | List of all sourceIds that contain a plagiarism match for this sentence. |
sentence | String | Inputted sentence from the text. |
matched | String | Sentence from the source that matched the inputted sentence. |
highlightOffset | Integer | Offset of the beginning of the inputted sentence, measured in characters from the beginning of the text. |
highlightLength | Integer | Length, in characters, of the highlighted sentence, starting from highlightOffset. |
wordCount | Integer | The number of words in the inputted sentence. |
longestMatchFragmentWordCount | Integer | Longest number of consecutive words within the sentence that exactly match the source. |
plagWordCount | Integer | The number of words plagiarized from the "matched" sentence. |
plagPercent | Double | The percentage of words (0 - 100) plagiarized from the "matched" sentence. |
matchType | String | The type of sentence match.
|
sentenceFragments | List of Objects | For "PARTIAL_MATCH" types, this provides a breakdown of the parts of the inputted sentence that matched or did not match the source text. |
matchFragments | List of Objects | For "PARTIAL_MATCH" types, this provides a breakdown of the parts of the source sentence that matched or did not match the inputted sentence. |
sentenceFragments
Field | Type | Description |
---|---|---|
text | String | The subset of words from the inputted sentence considered by this fragment. |
wordCount | Integer | The number of words represented by the fragment. |
fragType | String | The type of fragment.
|
highlightOffset | Integer | Offset of the beginning of the fragment, measured in characters from the beginning of the text. This provides the option of highlighting these portions of the plagiarized sentence differently according to fragType. |
highlightLength | Integer | Length, in characters, of the highlighted fragment, starting from highlightOffset. |
matchFragments
Field | Type | Description |
---|---|---|
text | String | The subset of words from the inputted sentence considered by this fragment. |
fragType | String | The type of fragment.
|
wordCount | Integer | The number of words represented by the fragment. |
relatedSources
Field | Type | Description |
---|---|---|
url | String | If the source is from the internet, a link will be provided. If the source is from another student submission, this field will be null. |
sourceType | String | Like in Plagiarism Match, source indicates whether the source is from the internet ("WEB") or from another user submission ("DOCUMENT") |
GET Plagiarism Health
Request Endpoint
GET https://api.writeshift.com/plagiarism/v1/health
Request
https://api.writeshift.com/plagiarism/v1/health
curl https://api.writeshift.com/plagiarism/v1/health
No headers or parameters are neccesary.
Response Information
Success Response
{
"status": "UP"
}
{
"status": "UP"
}
Fail Response
{
"status": "DOWN"
}
{
"status": "DOWN"
}
Status Code | Response Body | Description |
---|---|---|
200 | {"status": "UP"} | The service is running successfully. |
503 | {"status": "DOWN"} | There is a problem with the service. |
Short Answer
POST Short Answer Score
Request Endpoint
POST https://api.writeshift.com/shortscore/v1/score
Request Objects
Request
{
"appId": "myApplicationId",
"authorId": "myAuthorId",
"authorFullName": "Darth Vader",
"authorEmail": "Vader@starwars.abc",
"authorMetaData": "sample meta data for test",
"optIn": true,
"scoreSettings": {
"textName": "Sample Short Answer",
"modelName": "UniqueModelName",
"tutorType":"tutor_SA"
},
"scoreType": "SHORT_ANSWER",
"textData": "TEXT-DATA",
"topicId": "testing"
}
curl --location --request POST 'https://api.writeshift.com/shortscore/v1/score' \
--header 'apiKey: xxxxx' \
--header 'clientId: myClientId' \
--header 'Content-Type: application/json' \
--data-raw '{
"appId": "myApplicationId",
"authorId": "myAuthorId",
"authorFullName": "Darth Vader",
"authorEmail": "Vader@starwars.abc",
"authorMetaData": "sample meta data for test",
"optIn": true,
"scoreSettings": {
"textName": "Sample Short Answer",
"modelName": "UniqueModelName",
"tutorType":"tutor_SA"
},
"scoreType": "SHORT_ANSWER",
"textData": "TEXT-DATA",
"topicId": "testing"
}'
scoreType
in this request might be SHORT_ANSWER
or SHORT_ANSWER_WITH_TUTOR
the only difference in returned JSON will be whether tutorFeedback
is null or populated.
scoreSettings
Parameter | Type | Required | Description |
---|---|---|---|
textName | String | No | May be used to provide a name for the document |
modelName | String | Yes | Name of the model to be used for the short answer check. |
tutorType | String | No | If the user is requesting the SHORT_ANSWER_WITH_TUTOR service, this will say what kind of advice should be returned. This optional value allows an override of the default tutorType configured for the model. |
Response Objects
Response
{
"scoreId": "yyyyy",
"docId": "zzzzz",
"revNum": 0,
"inputLength": 679,
"scoreType": "SHORT_ANSWER_WITH_TUTOR",
"timestamp": "Wed Feb 12 20:15:31 UTC 2020",
"totalProcessTimeMs": 0,
"completed": true,
"failCode": null,
"failMessage": null,
"score": {
"dimensionalScores": [
{
"label": "Identification of type of leadership",
"scale": 3,
"score": 3.0,
"sequence": 1,
"probability": 0.86,
"tutorFeedback": "You clearly identified Emma's lack of transformational leadership behavior in this scenario. You earned the highest possible score for this criterion."
},
{
"label": "Identification of specific types of behavior",
"scale": 3,
"score": 3.0,
"sequence": 1,
"probability": 0.89,
"tutorFeedback": "Great job identifying two of the following specific types of transformational leadership behavior: idealized influence, inspirational motivation, intellectual stimulation, and individualized consideration. You earned the highest possible score for this criterion."
}
]
}
}
{
"scoreId": "yyyyy",
"docId": "zzzzz",
"revNum": 0,
"inputLength": 679,
"scoreType": "SHORT_ANSWER_WITH_TUTOR",
"timestamp": "Wed Feb 12 20:15:31 UTC 2020",
"totalProcessTimeMs": 0,
"completed": true,
"failCode": null,
"failMessage": null,
"score": {
"dimensionalScores": [
{
"label": "Identification of type of leadership",
"scale": 3,
"score": 3.0,
"sequence": 1,
"probability": 0.86,
"tutorFeedback": "You clearly identified Emma's lack of transformational leadership behavior in this scenario. You earned the highest possible score for this criterion."
},
{
"label": "Identification of specific types of behavior",
"scale": 3,
"score": 3.0,
"sequence": 1,
"probability": 0.89,
"tutorFeedback": "Great job identifying two of the following specific types of transformational leadership behavior: idealized influence, inspirational motivation, intellectual stimulation, and individualized consideration. You earned the highest possible score for this criterion."
}
]
}
}
score
Field | Type | Description |
---|---|---|
dimensionalScores | List of Objects | List of score objects for each dimension of the model. |
dimension
Field | Type | Description |
---|---|---|
label | String | For models with multiple dimensions, the label describes the meaning of each dimension. |
scale | Integer | The scale on which this dimension is scored. |
score | Float | The score for this dimension. |
sequence | Integer | The sequence for this dimension |
probability | Float | Confidence measure of the score classification (from 0-100). |
tutorFeedback | String | If the SHORT_ANSWER_WITH_TUTOR service was requested, this field will have feedback specifically tailored to the requested type, this category, and the score range for this dimension. If feedback for this category is not available or just SHORT_ANSWER was requested, this will be null. |
GET Short Answer Health
Request Endpoint
GET https://api.writeshift.com/shortscore/v1/health
Request
https://api.writeshift.com/shortscore/v1/health
curl https://api.writeshift.com/shortscore/v1/health
No headers or parameters are neccesary.
Response Information
Success Response
{
"status": "UP"
}
{
"status": "UP"
}
Fail Response
{
"status": "DOWN"
}
{
"status": "DOWN"
}
Status Code | Response Body | Description |
---|---|---|
200 | {"status": "UP"} | The service is running successfully. |
503 | {"status": "DOWN"} | There is a problem with the service. |
Statistics
POST Statistics Score
Request Endpoint
POST https://api.writeshift.com/stats/v1/score
Request Objects
Request
{
"appId": "myApplicationId",
"authorId": "myAuthorId",
"authorFullName": "Obi-Wan Kenobi",
"authorEmail": "Obi-Wan@starwars.abc",
"authorMetaData": "author for testing",
"optIn": true,
"textName": "Sample Text",
"scoreType": "STATISTICS",
"textData": "They covered the precious mahogany coffin with a brown amalgam of rocks, decomposed organisms, and weeds. It was my turn to take the shovel, but I felt too ashamed to dutifully send her off when I had not properly said goodbye. I refused to throw dirt on her. I refused to let go of my grandmother, to accept a death I had not seen coming, to believe that an illness could not only interrupt, but steal a beloved life.When my parents finally revealed to me that my grandmother had been battling liver cancer, I was twelve and I was angry-mostly with myself. They had wanted to protect me-only six years old at the time-from the complex and morose concept of death. However, when the end inevitably arrived, I wasnt trying to comprehend what dying was; I was trying to understand how I had been able to abandon my sick grandmother in favor of playing with friends and watching TV. Hurt that my parents had deceived me and resentful of my own oblivion, I committed myself to preventing such blindness from resurfacing.",
"topicId": "testing"
}
curl --location --request POST 'https://api.writeshift.com/stats/v1/score' \
--header 'apiKey: xxxxx' \
--header 'clientId: myClientId' \
--header 'Content-Type: application/json' \
--data-raw '{
"appId": "myApplicationId",
"authorId": "myAuthorId",
"authorFullName": "Obi-Wan Kenobi",
"authorEmail": "Obi-Wan@starwars.abc",
"authorMetaData": "author for testing",
"optIn": true,
"textName": "Sample Text",
"scoreType": "STATISTICS",
"textData": "They covered the precious mahogany coffin with a brown amalgam of rocks, decomposed organisms, and weeds. It was my turn to take the shovel, but I felt too ashamed to dutifully send her off when I had not properly said goodbye. I refused to throw dirt on her. I refused to let go of my grandmother, to accept a death I had not seen coming, to believe that an illness could not only interrupt, but steal a beloved life.When my parents finally revealed to me that my grandmother had been battling liver cancer, I was twelve and I was angry-mostly with myself. They had wanted to protect me-only six years old at the time-from the complex and morose concept of death. However, when the end inevitably arrived, I wasnt trying to comprehend what dying was; I was trying to understand how I had been able to abandon my sick grandmother in favor of playing with friends and watching TV. Hurt that my parents had deceived me and resentful of my own oblivion, I committed myself to preventing such blindness from resurfacing.",
"topicId": "testing"
}'
scoreSettings
There are no configurable parameters for the statistics service, so scoreSettings
should not be included.
Response Objects
Response
{
"scoreId": "yyyyy",
"docId": "zzzzz",
"revNum": 0,
"inputLength": 1017,
"scoreType": "STATISTICS",
"timestamp": "Wed Feb 12 21:46:00 UTC 2020",
"totalProcessTimeMs": 3,
"completed": true,
"failCode": null,
"failMessage": null,
"score": {
"wordCount": 186,
"sentenceCount": 9,
"fleschKincaidGradeLevel": 10.04,
"fleschReadingEase": 59.87
}
}
{
"scoreId": "yyyyy",
"docId": "zzzzz",
"revNum": 0,
"inputLength": 1017,
"scoreType": "STATISTICS",
"timestamp": "Wed Feb 12 21:46:00 UTC 2020",
"totalProcessTimeMs": 3,
"completed": true,
"failCode": null,
"failMessage": null,
"score": {
"wordCount": 186,
"sentenceCount": 9,
"fleschKincaidGradeLevel": 10.04,
"fleschReadingEase": 59.87
}
}
score
Field | Type | Description |
---|---|---|
wordCount | Integer | Number of words in the provided text |
sentenceCount | Integer | Number of sentences in the provided text |
fleschKincaidGradeLevel | Double | Flesh-Kincaid Grade level |
fleschReadingEase | Double | Flesh-Reading Ease score |
GET Statistics Health
Request Endpoint
GET https://api.writeshift.com/stats/v1/health
Request
https://api.writeshift.com/stats/v1/health
curl https://api.writeshift.com/stats/v1/health
No headers or parameters are neccesary.
Response Information
Success Response
{
"status": "UP"
}
{
"status": "UP"
}
Fail Response
{
"status": "DOWN"
}
{
"status": "DOWN"
}
Status Code | Response Body | Description |
---|---|---|
200 | {"status": "UP"} | The service is running successfully. |
503 | {"status": "DOWN"} | There is a problem with the service. |
Model
GET Model Info
Request Endpoint
GET https://api.writeshift.com/model/v1/getInfo
Request Parameters
Request
https://api.writeshift.com/model/v1/getInfo?modelName={myModelName}&serviceType={SHORT_ANSWER|ESSAY}
curl --location --request GET 'https://api.writeshift.com/model/v1/getInfo?modelName=MHEleadr&serviceType=SHORT_ANSWER' \
--header 'apiKey: xxxxx' \
--header 'clientId: myClientId' \
--header 'Content-Type: application/json'
Parameter | Description |
---|---|
modelName | The unique model name that you are requesting information about. |
serviceType | Either SHORT_ANSWER or ESSAY depending on the writing service. |
Response Objects
Response
{
"timestamp": "Thu Feb 13 16:17:06 UTC 2020",
"totalProcessTimeMs": 5,
"completed": true,
"failCode": null,
"failMessage": null,
"modelDetails": {
"modelName": "UniqueModelName",
"modelType": "SHORT_ANSWER",
"description": "Principles of Management Module: Leadership",
"promptContent": "Emma is the team lead at a data analytics firm. She believes in encouraging her team members to fulfill their job responsibilities by rewarding them when they achieve their goals and punishing them when they dont. Based on her leadership style, her team consistently meets company expectations. Based on the scenario, is Emma exhibiting transformational leadership? If you think she is, explain why by including and describing two specific types of transformational behavior based on the scenario. If not, explain how she can exhibit transformational leadership by including and describing two specific types of transformational behavior.",
"holisticScale": 3,
"tutorFeedback": "tutor_SA",
"rubricName": "Principles of Management: Type of Leadership_ShortAnswer",
"rubricDimensions": [
{
"label": "Identification of type of leadership",
"information": "No additional information is available.",
"sequence": 1,
"performanceLevels": [
{
"label": "3 - Satisfactory",
"scale": 3,
"score": 3,
"description": "Demonstration, or lack thereof, of transformational leadership is correctly specified."
},
{
"label": "2 - Needs Improvement",
"scale": 3,
"score": 2,
"description": "A clear position has not been taken."
},
{
"label": "1 - Unsatisfactory",
"scale": 3,
"score": 1,
"description": "Demonstration, or lack thereof, of transformational leadership is not correctly specified."
}
]
},
{
"label": "Identification of specific types of behavior",
"information": "No additional information is available.",
"sequence": 2,
"performanceLevels": [
{
"label": "3 - Satisfactory",
"scale": 3,
"score": 3,
"description": "Two specific types of transformational behavior are identified."
},
{
"label": "2 - Needs Improvement",
"scale": 3,
"score": 2,
"description": "One specific type of transformational behavior is identified."
},
{
"label": "1 - Unsatisfactory",
"scale": 3,
"score": 1,
"description": "No specific type of transformational behavior has been identified."
}
]
}
]
}
}
{
"timestamp": "Thu Feb 13 16:17:06 UTC 2020",
"totalProcessTimeMs": 5,
"completed": true,
"failCode": null,
"failMessage": null,
"modelDetails": {
"modelName": "UniqueModelName",
"modelType": "SHORT_ANSWER",
"description": "Principles of Management Module: Leadership",
"promptContent": "Emma is the team lead at a data analytics firm. She believes in encouraging her team members to fulfill their job responsibilities by rewarding them when they achieve their goals and punishing them when they dont. Based on her leadership style, her team consistently meets company expectations. Based on the scenario, is Emma exhibiting transformational leadership? If you think she is, explain why by including and describing two specific types of transformational behavior based on the scenario. If not, explain how she can exhibit transformational leadership by including and describing two specific types of transformational behavior.",
"holisticScale": 3,
"tutorFeedback": "tutor_SA",
"rubricName": "Principles of Management: Type of Leadership_ShortAnswer",
"rubricDimensions": [
{
"label": "Identification of type of leadership",
"information": "No additional information is available.",
"sequence": 1,
"performanceLevels": [
{
"label": "3 - Satisfactory",
"scale": 3,
"score": 3,
"description": "Demonstration, or lack thereof, of transformational leadership is correctly specified."
},
{
"label": "2 - Needs Improvement",
"scale": 3,
"score": 2,
"description": "A clear position has not been taken."
},
{
"label": "1 - Unsatisfactory",
"scale": 3,
"score": 1,
"description": "Demonstration, or lack thereof, of transformational leadership is not correctly specified."
}
]
},
{
"label": "Identification of specific types of behavior",
"information": "No additional information is available.",
"sequence": 2,
"performanceLevels": [
{
"label": "3 - Satisfactory",
"scale": 3,
"score": 3,
"description": "Two specific types of transformational behavior are identified."
},
{
"label": "2 - Needs Improvement",
"scale": 3,
"score": 2,
"description": "One specific type of transformational behavior is identified."
},
{
"label": "1 - Unsatisfactory",
"scale": 3,
"score": 1,
"description": "No specific type of transformational behavior has been identified."
}
]
}
]
}
}
modelDetails
Field | Type | Description |
---|---|---|
modelName | String | Name of the model |
modelType | String | Type of the model example (ESSAY / SHORT_ANSWER) |
description | String | Detailed description regarding the model |
promptContent | String | Prompt text for the model |
holisticScale | Integer | Overall scoring scale for the model |
tutorFeedback | String | Tutor feedback name for the model |
rubricName | String | Name of the rubric for the model |
rubricDimensions | List of Objects | Contains the rubric for the model |
rubricDimensions
Field | Type | Description |
---|---|---|
label | String | For models with multiple dimensions, the label describes the meaning of each dimension. |
information | String | Information regarding the specific dimension |
sequence | Integer | The sequence of the specific dimension in the rubric table. |
performanceLevels | List of Objects | Contains the list of objects for each scale in the specific rubric dimension |
performanceLevels
Field | Type | Description |
---|---|---|
label | String | The label describes the scoring scale for each level |
scale | Integer | overall scoring scale for the model |
score | Integer | score the specific performance level |
description | String | Contains the description about the scoring dimension |
GET Access Token
GET https://api.writeshift.com/model/v1/getAccessToken
Request Parameters
Request
https://api.writeshift.com/model/v1/getAccessToken?docId={docId}
curl --location --request GET 'https://api.writeshift.com/model/v1/getAccessToken?docId=a55501b1-1122-ffff-0010-30495abaaa33&' \
--header 'apiKey: xxxxx' \
--header 'clientId: myClientId' \
--header 'Content-Type: application/json'
Parameter | Description |
---|---|
docId | The Document ID that you want to generate a temporary access token for. |
Response
Response
{
"accessToken": "cccc5050-123a-ff12-ba11-feee000bb216",
"docId": "a55501b1-1122-ffff-0010-30495abaaa33",
"expiresAt": "2020-07-14T21:57:34.606+0000",
"failCode": null
}
{
"accessToken": "cccc5050-123a-ff12-ba11-feee000bb216",
"docId": "a55501b1-1122-ffff-0010-30495abaaa33",
"expiresAt": "2020-07-14T21:57:34.606+0000",
"failCode": null
}
Field | Type | Description |
---|---|---|
accessToken | String | The accessToken. |
docId | String | The docId that the access token was generated for. |
expiresAt | Timestamp | The time when the accessToken will expire and no longer be valid. |
failCode | String | A fail message that is only populated if an error occurs during the accessToken generation. |
GET Document Text
Request Endpoint
GET https://api.writeshift.com/model/v1/getDocumentText
Alternative Credentials
Header | Type | Description |
---|---|---|
accessToken | String | A temporary access token generated with /model/v1/getAccessToken. |
Request Parameters
Request
https://api.writeshift.com/model/v1/getDocumentText?docId={docId}(&removeHtml={true|false})
curl --location --request GET 'https://api.writeshift.com/model/v1/getInfo?docId=a55501b1-1122-ffff-0010-30495abaaa33&removeHtml=true' \
--header 'apiKey: xxxxx' \
--header 'clientId: myClientId' \
--header 'Content-Type: application/json'
Parameter | Description |
---|---|
docId | The Document ID for the text you want to return. (For example, from the plagiarism response.) |
removeHtml | Optional. If true, HTML tags will be removed from the response. Otherwise the text is returned as-is. |
Response
Response
{
"documentText": "This is the original text of the document that was submitted to writeSHIFT.",
"failCode": null
}
{
"documentText": "This is the original text of the document that was submitted to writeSHIFT.",
"failCode": null
}
Field | Type | Description |
---|---|---|
documentText | String | The text body of the document. |
failCode | String | If not successful, this provides an error code to explain why. |
GET Model Health
Request Endpoint
GET https://api.writeshift.com/model/v1/health
Request
https://api.writeshift.com/model/v1/health
curl https://api.writeshift.com/model/v1/health
No headers or parameters are neccesary.
Response Information
Success Response
{
"status": "UP"
}
{
"status": "UP"
}
Fail Response
{
"status": "DOWN"
}
{
"status": "DOWN"
}
Status Code | Response Body | Description |
---|---|---|
200 | {"status": "UP"} | The service is running successfully. |
503 | {"status": "DOWN"} | There is a problem with the service. |
Paraphrase
POST Paraphrase Score
Request Endpoint
POST https://api.writeshift.com/paraphrase/v1/score
Request Objects
Request
{
"appId": "myApplicationId",
"authorId": "myAuthorId",
"metaData" : "Paraphrase Test",
"optIn": true,
"scoreSettings": {
"modelName": "paraTest",
"question": "Do you see another important finding?",
"expectedAnswers": [
"sample 1",
"sample 2",
"sample 3",
"sample 4",
"sample 5",
"sample 6",
"nothing else"
]
},
"scoreType": "PARAPHRASE",
"textData": "sample 1 and sample 2"
}
curl --location --request POST 'https://api.writeshift.com/paraphrase/v1/score' \
--header 'apiKey: xxxxx' \
--header 'clientId: myClientId' \
--header 'Content-Type: application/json' \
--data-raw '{
"appId": "myApplicationId",
"authorId": "myAuthorId",
"metaData" : "Paraphrase Test",
"optIn": true,
"scoreSettings": {
"modelName": "paraTest",
"question": "Do you see another important finding?",
"expectedAnswers": [
"sample 1",
"sample 2",
"sample 3",
"sample 4",
"sample 5",
"sample 6",
"nothing else"
]
},
"scoreType": "PARAPHRASE",
"textData": "sample 1 and sample 2"
}'
scoreSettings
Parameter | Type | Required | Description |
---|---|---|---|
question | String | Optional | Question asked. |
modelName | String | Yes | Name of the model to be used for the paraphrase check. The name "paraTest" can be used as a simulated model for testing purposes. |
expectedAnswers | List of strings | Yes | This is a list of distinct answers that would be expected in response to the given question. It should only contain distinct answers and not every possible permutation of the same answer. The paraphrase service will attempt to classify the given user input (provided as textData) with one (or more) of these expected answers. |
textData | String | Yes | The text content being submitted for a check. |
Response Objects
Successful Responses
Possible Response
{
"score": {
"matchQuality": "POSSIBLE",
"matchAnswers": [
"sample 1",
"sample 2"
]
}
}
{
"score": {
"matchQuality": "POSSIBLE",
"matchAnswers": [
"sample 1",
"sample 2"
]
}
}
Exact Response
{
"score": {
"matchQuality": "EXACT",
"matchAnswers": [
"sample 1"
]
}
}
{
"score": {
"matchQuality": "EXACT",
"matchAnswers": [
"sample 1"
]
}
}
None Response
{
"score": {
"matchQuality": "NONE",
"matchAnswers": []
}
}
{
"score": {
"matchQuality": "NONE",
"matchAnswers": []
}
}
matchAnswers
matchAnswers - a list of strings indicating expected answers that were found to be a match. this list will be empty for matchQuality NONE, contain one value for matchQuality EXACT, and one or more values for matchQuality POSSIBLE. The values will match what was provided in the expectedAnswers from the request.
matchQuality
matchQuality - indicates to what extent the paraphrase service was able to match the user input (textData) with one or more of the expected answers.
matchQuality | Description |
---|---|
EXACT | Exactly one match was found with high confidence. |
POSSIBLE | One or more matches were found with moderate confidence. |
NONE | No suitable matches were found. |
GET Paraphrase Health
Request Endpoint
GET https://api.writeshift.com/paraphrase/v1/health
Request
https://api.writeshift.com/paraphrase/v1/health
curl https://api.writeshift.com/paraphrase/v1/health
No headers or parameters are neccesary.
Response Information
Success Response
{
"status": "UP"
}
{
"status": "UP"
}
Fail Response
{
"status": "DOWN"
}
{
"status": "DOWN"
}
Status Code | Response Body | Description |
---|---|---|
200 | {"status": "UP"} | The service is running successfully. |
503 | {"status": "DOWN"} | There is a problem with the service. |