API Docs
EN
Concepts

Result structure

The result answers three questions: which values were calculated, which issues were found and which replacement or edit can be proposed for each occurrence.

An enabled metric is always evaluated, but output depends on its kind: measurements appear once; rules appear only when they find matches.

result.measurements[]

Measurements

Calculated numeric values. Each result.measurements entry is identified by metric_id; value is interpreted together with unit and implementation_version.

Metrics and rules →
result.recommendations[]

Recommendations

Issues grouped by rule. Each item explains the issue and groups every concrete appearance in occurrences.

Metrics and rules →

Structure of a recommendation and its edits

A recommendation describes the issue type; each occurrence identifies where it appears and whether arText has a concrete replacement or edit.

recommendations[].metric_idStable rule identifier. Its definition is available from GET /v1/metrics.
recommendations[].summaryExplanation of the issue found in this report.
recommendations[].guidance[]General review guidance; it is not necessarily a literal replacement.
recommendations[].examplesWorked examples illustrating the recommendation, as plain text with meaningful line breaks. They belong to the rule: they never quote the analysed text and do not vary between reports. null when the rule has no examples.
occurrences[].textFragment detected by the metric.
occurrences[].start / endRange in the original text measured in Unicode code points; start is inclusive and end exclusive.
occurrences[].replacementPreferred textual replacement when available. null means the rule provides no direct replacement.
occurrences[].alternatives[]Other reviewed replacements, excluding replacement. The array can be empty.
occurrences[].edits[]Safe changes normalized as {start, end, text}. Empty text deletes the range and start equal to end inserts text.

An occurrence remains a valid issue when replacement is null and edits is empty. In that case the explanation should be presented and the revision left to the user; the integration must not fabricate a change.

Offsets: how to slice the fragment

start and end refer to the EXACT text you sent in text: not normalised, not trimmed and not reordered. The report does not return that text, so the unit matters.

offset_unit is unicode_code_points, not UTF-16 units and not bytes. A single character outside the BMP — an emoji, some ideographs, some mathematical symbols — shifts every later offset in languages that index by UTF-16. This failure never shows up in tests, only with real documents.

Pythontexto[start:end] — correct as is: Python strings are already code points.
JavaScript[...texto].slice(start, end).join("") — text.slice(start, end) is NOT correct. The official SDK ships sliceByCodePoints and codePointToUtf16Index.
Java · C#texto.codePoints() / StringInfo — strings are UTF-16; convert before indexing.
Go[]rune(texto)[start:end] — strings are bytes; convert to runes.

Keep the analysed text yourself, keyed by report_id or by your external_id: it is the only place where the offsets mean anything, and the API does not retain it beyond the report's own retention window.

200 · Completed

{
  "error": null,
  "external_id": "document-123",
  "position_in_queue": null,
  "report_id": "rep_7f12a4c8",
  "result": {
    "genre": {
      "domain": {
        "name": "Plain language",
        "slug": "plain-language"
      },
      "text_type": {
        "name": "Legal-administrative text",
        "slug": "legal-administrative-text-addressed-to-citizens"
      }
    },
    "language": "en",
    "measurements": [
      {
        "implementation_version": "1.0",
        "metric_id": "word-count",
        "unit": "words",
        "value": 12
      }
    ],
    "offset_unit": "unicode_code_points",
    "recommendations": [
      {
        "category": "lexical",
        "explanation": null,
        "guidance": [
          "Remove the expression when the context allows it."
        ],
        "id": "rec_1",
        "implementation_version": "1.0",
        "metric_id": "redundant-expressions",
        "metric_title": "Removal of redundant expressions",
        "occurrences": [
          {
            "alternatives": [],
            "edits": [
              {
                "end": 19,
                "start": 0,
                "text": ""
              }
            ],
            "end": 19,
            "id": "occ_1",
            "paragraph_index": 0,
            "replacement": null,
            "sentence_index": 0,
            "start": 0,
            "text": "at the present time"
          }
        ],
        "summary": "Consider expressing this fragment more directly."
      }
    ],
    "schema_version": "2.0"
  },
  "status": "completed"
}
NextMetrics and rules