# Spell Checking

> Find misspelled words and get suggestions with proofing/check and proofing/suggestions: dictionary names, the spell checking quota, curl and the PHP SDK.

- **Product:** ReportingCloud
- **Section:** Documentation
- **Kind:** Topic
- **Path:** ReportingCloud > Document Processing > Spell Checking
- **2681 words**
- **Web URL:** https://docs.textcontrol.com/reporting-cloud/document-processing/spell-checking/
- **LLMs URL:** https://docs.textcontrol.com/reporting-cloud/document-processing/spell-checking/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/reporting-cloud/document-processing/spell-checking/llms-full.txt

---

Text that people type into your application, such as a comment that ends up in a merged invoice, can be checked for spelling before it is merged or saved. The proofing endpoints of the Web API check a text against a dictionary, suggest corrections for a misspelled word and list the dictionaries the service offers. They work on plain text, independently of templates and merging: the dictionaries are those the template editor of the portal checks spelling with, made available to your own application.

### How Spell Checking Works

The three proofing endpoints are `GET` requests whose parameters travel in the query string:

| Endpoint | Parameters | Returns | Quota |
|---|---|---|---|
| [proofing/availabledictionaries](https://docs.textcontrol.com/reporting-cloud/reference/web-api/proofing/availabledictionaries/get/llms-full.txt) | None | An array of dictionary names | None |
| [proofing/check](https://docs.textcontrol.com/reporting-cloud/reference/web-api/proofing/check/get/llms-full.txt) | `text`, `language` | An array of `IncorrectWord` objects | 1 per request |
| [proofing/suggestions](https://docs.textcontrol.com/reporting-cloud/reference/web-api/proofing/suggestions/get/llms-full.txt) | `word`, `language`, `max` | An array of suggested words | 1 per request |

All parameters are required: a request without one of them answers `404 Not Found`. `language` is not a culture name such as `en-US` but the name of a dictionary, such as `en_US.dic`, exactly as availabledictionaries returns it, in the same letter case. An empty text or word, a text of spaces only, an empty `language` or one that is not the name of an available dictionary answers `400 Bad Request` with the text `Spell checking failed`.

Requests to check and suggestions count against the spell checking quota: each one adds 1 to the proofing transactions of the current month, whatever the length of the text. A request answered with an error adds none. The plans allow from 10,000 transactions a month (Trial and Basic) to 500,000 (Extreme), as [Plans and Licensing](https://docs.textcontrol.com/reporting-cloud/overview/licensing/llms-full.txt) lists. When the month's transactions are used up, both endpoints answer `403 Forbidden`. [GET /v1/account/settings](https://docs.textcontrol.com/reporting-cloud/reference/web-api/account/settings/get/llms-full.txt) returns the transactions used so far in `proofingTransactions` and the limit in `maxProofingTransactions`.

Every request carries an `Authorization` header, as [Authentication](https://docs.textcontrol.com/reporting-cloud/document-processing/authentication/llms-full.txt) describes.

### List the Available Dictionaries

The names of the dictionaries are the values that `language` takes:

```bash
curl -H "Authorization: ReportingCloud-APIKey $REPORTINGCLOUD_API_KEY" \
  "https://api.reporting.cloud/v1/proofing/availabledictionaries"
```

The response is an array of names, shortened here:

```json
["af_ZA.dic", "de_AT_frami.dic", "de_CH_frami.dic", "de_DE_frami.dic", "en_GB.dic", "en_US.dic", "en_US_OpenMedSpel.dic", "es_ES.dic", "fr.dic", "it_IT.dic", "nl_NL.dic", "pt_BR.dic", "sv_SE.dic", "en_US_Legal.txd"]
```

Most names combine a language and a country, such as `en_GB.dic` or `pt_BR.dic`, and some name a language only, such as `fr.dic`. The reference shows 49 names: the `.dic` dictionaries in alphabetical order from `af_ZA.dic` to `vi_VN.dic`, followed by `en_US_Legal.txd`. Read the list from the endpoint when your application offers a choice of languages, rather than keeping a copy of it. `en_US_OpenMedSpel.dic` (medical terms) and `en_US_Legal.txd` (legal terms) are supplementary word lists, not complete dictionaries: a check with one of them reports common English words such as "the" and "house" as misspelled.

### Check a Text

`GET /v1/proofing/check` returns one object for each word it finds misspelled and for each word that repeats the word before it. Encode the text for the URL: `curl -G` with `--data-urlencode` does it and appends the parameters to the query string:

```bash
curl -G -H "Authorization: ReportingCloud-APIKey $REPORTINGCLOUD_API_KEY" \
  --data-urlencode "text=Thiss is a testt" \
  --data-urlencode "language=en_US.dic" \
  "https://api.reporting.cloud/v1/proofing/check"
```

```json
[
  { "length": 5, "start": 0, "text": "Thiss", "isDuplicate": false, "language": "en_US.dic" },
  { "length": 5, "start": 11, "text": "testt", "isDuplicate": false, "language": "en_US.dic" }
]
```

Each `IncorrectWord` object holds:

| Property | Content |
|---|---|
| `text` | The misspelled or repeated word |
| `start` | The position of its first character in the checked text, counted from 0 in UTF-16 code units: a character such as an emoji counts 2 |
| `length` | The length of the word in UTF-16 code units |
| `isDuplicate` | `true` when the word is marked because the word before it has the same text, as in "the the" |
| `language` | The dictionary the word was checked with |

`start` and `length` locate the word in the text you sent, so your application can underline it in an input field or replace it. A text without misspelled or repeated words returns an empty array. The query string may have at most 2,048 characters, URL-encoded: a longer one answers `404 Not Found`, so check a long text in parts.

### Get Suggestions for a Word

`GET /v1/proofing/suggestions` returns corrections for one word, at most as many as `max` asks for:

```bash
curl -G -H "Authorization: ReportingCloud-APIKey $REPORTINGCLOUD_API_KEY" \
  --data-urlencode "word=Thiss" \
  --data-urlencode "language=en_US.dic" \
  --data-urlencode "max=10" \
  "https://api.reporting.cloud/v1/proofing/suggestions"
```

```json
["This", "Hiss", "Thesis", "Thins", "Thurs", "Thirsts", "Thieu", "Thirds", "Theists", "Thais"]
```

Each call costs one proofing transaction, like a check of a whole text. Check a text in one request rather than word by word, and ask for suggestions only for the words a user wants to correct.

### Check Spelling With PHP

The PHP SDK `textcontrol/textcontrol-reportingcloud` has a method for each proofing endpoint. The following script checks a text and prints up to three suggestions for each misspelled word:

```php
<?php

declare(strict_types=1);

require_once __DIR__ . '/vendor/autoload.php';

use TextControl\ReportingCloud\ReportingCloud;

$reportingCloud = new ReportingCloud([
    'api_key' => (string) getenv('REPORTINGCLOUD_API_KEY'),
]);

$text = 'Thiss is a testt';

// One proofing transaction for the whole text
$incorrectWords = $reportingCloud->proofingCheck($text, 'en_US.dic');

foreach ($incorrectWords as $incorrectWord) {
    // One more proofing transaction for each word
    $suggestions = $reportingCloud->getProofingSuggestions($incorrectWord['text'], 'en_US.dic', 3);

    printf(
        "%s at position %d: %s\n",
        $incorrectWord['text'],
        $incorrectWord['start'],
        implode(', ', $suggestions)
    );
}
```

The code works as follows:

- `proofingCheck` calls `GET /v1/proofing/check` and returns the misspelled words as arrays. Their keys are those of `IncorrectWord` in snake case: `text`, `start`, `length`, `is_duplicate` and `language`.
- `getProofingSuggestions` calls `GET /v1/proofing/suggestions` with the word, the dictionary and the maximum number of suggestions, and returns an array of strings.
- Both methods check the dictionary name against a list built into the SDK before they send the request. A name that is not on the list throws an `InvalidArgumentException` with a message such as `"en-US" contains an unsupported language`, without a request and without a transaction.

`getAvailableDictionaries` returns the list of the service. The SDK encodes the text for the URL itself.

The .NET SDK has the methods `GetAvailableDictionaries`, `CheckText` and `GetSuggestions`. In version 1.205.500 of the NuGet package, `CheckText` and `GetSuggestions` add the text to the URL without encoding it, so a text with `&` arrives cut off, and a text with `#` loses the `language` parameter as well. Pass the text through `Uri.EscapeDataString`, as in `rc.CheckText(Uri.EscapeDataString(text), "en_US.dic")`.

### Next Steps

- [Plans and Licensing](https://docs.textcontrol.com/reporting-cloud/overview/licensing/llms-full.txt): the proofing transactions of each plan.
- [Template Editor](https://docs.textcontrol.com/reporting-cloud/portal/template-editor/llms-full.txt): design templates in the portal's editor.
- [Tracked Changes](https://docs.textcontrol.com/reporting-cloud/document-processing/tracked-changes/llms-full.txt): list and accept the changes reviewers made to a document.
- [Errors and Status Codes](https://docs.textcontrol.com/reporting-cloud/document-processing/errors/llms-full.txt): what a `403` answer of the proofing endpoints means.

---

## Nearby

- **Previous:** [Sharing Documents](https://docs.textcontrol.com/reporting-cloud/document-processing/sharing/llms-full.txt)
- **Next:** [Tracked Changes](https://docs.textcontrol.com/reporting-cloud/document-processing/tracked-changes/llms-full.txt)
