{"openapi":"3.1.0","info":{"title":"arText Reports API","description":"Envia un text, consulta l’informe asíncron i utilitza recomanacions lingüístiques estructurades en els teus productes.","version":"1.0.0"},"paths":{"/v1/reports":{"post":{"tags":["Reports"],"summary":"Crear un informe d’anàlisi","description":"Valida i posa un text a la cua. La resposta 202 inclou recursos d’estat i d’esdeveniments; no implica que l’anàlisi hagi acabat.","operationId":"create_public_report_v1_reports_post","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string","minLength":1,"maxLength":255},{"type":"null"}],"title":"Idempotency-Key"},"description":"Recommended unique key for safely retrying this creation request. It is scoped to the authenticated caller, retained for 24 hours, and must not be reused with a different payload.","example":"document-123-analysis-v1"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportRequest"},"examples":{"basic":{"summary":"Create a report","value":{"language":"ca","domain_slug":"llenguatge-clar","text_type_slug":"text-juridic-administratiu-dirigit-a-la-ciutadania","text":"En el dia d’avui es durà a terme la revisió de la sol·licitud.","external_id":"document-123"}}}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportAccepted"},"examples":{"queued":{"summary":"Report accepted and queued","value":{"report_id":"rep_7f12a4c8","external_id":"document-123","status":"queued","status_url":"/v1/reports/rep_7f12a4c8","events_url":"/v1/reports/rep_7f12a4c8/events"}}}}},"headers":{"Location":{"description":"Canonical status resource for the accepted report.","schema":{"type":"string","example":"/v1/reports/rep_7f12a4c8"}},"Retry-After":{"description":"Minimum number of seconds before the first status poll.","schema":{"type":"integer","minimum":1,"example":2}},"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}}}},"401":{"description":"Missing, invalid, inactive or revoked API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiProblem"}}},"headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}}}},"409":{"description":"Idempotency-Key was reused with a different payload.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiProblem"}}},"headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}}}},"413":{"description":"Text exceeds the configured word limit.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiProblem"}}},"headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}}}},"422":{"description":"Request validation failed: unknown genre, or a text_type_slug that names more than one genre and needs domain_slug.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiProblem"}}},"headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiProblem"}}},"headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}},"Retry-After":{"description":"Seconds to wait before a retry can be attempted.","schema":{"type":"integer","minimum":1,"example":2}}}},"503":{"description":"The analysis queue is unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiProblem"}}},"headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}},"Retry-After":{"description":"Seconds to wait before a retry can be attempted.","schema":{"type":"integer","minimum":1,"example":2}}}}},"security":[{"ApiKey":[]}]}},"/v1/reports/{report_id}":{"get":{"tags":["Reports"],"summary":"Consultar l’estat i el resultat","description":"Retorna l’estat actual. En queued/running cal respectar Retry-After; completed i failed són terminals.","operationId":"get_public_report_v1_reports__report_id__get","parameters":[{"name":"report_id","in":"path","required":true,"schema":{"type":"string","title":"Report Id"},"description":"Unique report identifier returned by POST /v1/reports."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Report"},"examples":{"queued":{"summary":"Report queued","value":{"report_id":"rep_7f12a4c8","external_id":"document-123","status":"queued","status_url":"/v1/reports/rep_7f12a4c8","events_url":"/v1/reports/rep_7f12a4c8/events"}},"completed":{"summary":"Report completed","value":{"report_id":"rep_7f12a4c8","external_id":"document-123","status":"completed","position_in_queue":null,"result":{"schema_version":"2.0","offset_unit":"unicode_code_points","language":"ca","genre":{"domain":{"slug":"llenguatge-clar","name":"Llenguatge clar"},"text_type":{"slug":"text-juridic-administratiu-dirigit-a-la-ciutadania","name":"Text juridicoadministratiu"}},"measurements":[{"metric_id":"word-count","value":12,"unit":"words","implementation_version":"1.0"}],"recommendations":[{"id":"rec_1","metric_id":"redundant-expressions","implementation_version":"1.0","metric_title":"Eliminació d’expressions redundants","category":"lexical","summary":"Convé formular el fragment d’una manera més directa.","explanation":null,"occurrences":[{"id":"occ_1","text":"En el dia d’avui","paragraph_index":0,"sentence_index":0,"start":0,"end":16,"replacement":null,"alternatives":[],"edits":[{"start":0,"end":16,"text":""}]}],"guidance":["Elimina l’expressió si el context ho permet."]}]},"error":null}},"failed":{"summary":"Report failed","value":{"report_id":"rep_7f12a4c8","external_id":"document-123","status":"failed","position_in_queue":null,"result":null,"error":{"code":"analysis_failed","message":"The analysis could not be completed."}}}}}},"headers":{"Retry-After":{"description":"Present for queued/running reports; wait at least this many seconds before polling again.","schema":{"type":"integer","minimum":1,"example":5}},"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}}}},"401":{"description":"Missing, invalid, inactive or revoked API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiProblem"}}},"headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}}}},"404":{"description":"Report not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiProblem"}}},"headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}}}},"429":{"description":"Status rate limit or minimum polling interval exceeded.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiProblem"}}},"headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}},"Retry-After":{"description":"Seconds to wait before a retry can be attempted.","schema":{"type":"integer","minimum":1,"example":2}}}},"503":{"description":"Request protection is temporarily unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiProblem"}}},"headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}},"Retry-After":{"description":"Seconds to wait before a retry can be attempted.","schema":{"type":"integer","minimum":1,"example":2}}}},"422":{"description":"Validation Error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiProblem"}}},"headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}}}}},"security":[{"ApiKey":[]}]}},"/v1/reports/{report_id}/events":{"get":{"tags":["Reports"],"summary":"Rebre transicions per SSE","description":"Canal SSE opcional amb l’estat inicial, canvis i heartbeats. Es tanca en acabar; el polling continua sent el mecanisme de reserva.","operationId":"stream_public_report_events_v1_reports__report_id__events_get","parameters":[{"name":"report_id","in":"path","required":true,"schema":{"type":"string","title":"Report Id"},"description":"Unique report identifier returned by POST /v1/reports."}],"responses":{"200":{"description":"SSE status stream.","content":{"text/event-stream":{"schema":{"type":"string"},"examples":{"transitions":{"summary":"A stream closes after completed or failed","value":"event: status\\ndata: {\"report_id\":\"rep_7f12a4c8\",\"status\":\"running\",\"updated_at\":\"2026-07-15T10:00:02Z\"}\\n\\nevent: status\\ndata: {\"report_id\":\"rep_7f12a4c8\",\"status\":\"completed\",\"updated_at\":\"2026-07-15T10:00:06Z\"}\\n\\n"}}}},"headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}}}},"401":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiProblem"}}},"description":"Unauthorized","headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}}}},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiProblem"}}},"description":"Not Found","headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}}}},"429":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiProblem"}}},"description":"Too Many Requests","headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}},"Retry-After":{"description":"Seconds to wait before a retry can be attempted.","schema":{"type":"integer","minimum":1,"example":2}}}},"503":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiProblem"}}},"description":"Service Unavailable","headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}},"Retry-After":{"description":"Seconds to wait before a retry can be attempted.","schema":{"type":"integer","minimum":1,"example":2}}}},"422":{"description":"Validation Error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiProblem"}}},"headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}}}}},"security":[{"ApiKey":[]}]}},"/v1/metrics":{"get":{"tags":["Metrics"],"summary":"List metric implementations","description":"Returns measurement and rule implementations, including inactive variants and localized documentation. Narrowing the request to a genre reports which metrics that genre actually evaluates.","operationId":"list_metrics_v1_metrics_get","parameters":[{"name":"analysis_language","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Analysis Language"},"description":"Language implementation to return: es, ca or en."},{"name":"documentation_language","in":"query","required":false,"schema":{"type":"string","default":"es","title":"Documentation Language"},"description":"Language used for titles and documentation: es, ca or en."},{"name":"kind","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(measurement|rule)$"},{"type":"null"}],"title":"Kind"},"description":"Filter by measurement or rule."},{"name":"enabled","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Enabled"},"description":"Filter by the current implementation status."},{"name":"domain_slug","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional genre filter. domain_slug and text_type_slug go together and must name a genre listed by GET /v1/text-types; each metric then reports whether that genre evaluates it and with which thresholds.","title":"Domain Slug"},"description":"Text domain of a genre, as listed by GET /v1/text-types."},{"name":"text_type_slug","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional genre filter. domain_slug and text_type_slug go together and must name a genre listed by GET /v1/text-types; each metric then reports whether that genre evaluates it and with which thresholds.","title":"Text Type Slug"},"description":"Text type (genre) inside domain_slug, as listed by GET /v1/text-types."}],"responses":{"200":{"description":"Metric implementations and their documentation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricCatalog"}}},"headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}}}},"401":{"description":"Missing, invalid, inactive or revoked API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiProblem"}}},"headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}}}},"422":{"description":"Incomplete or unknown genre filter.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiProblem"}}},"headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}}}}},"security":[{"ApiKey":[]}]}},"/v1/metrics/{metric_id}":{"get":{"tags":["Metrics"],"summary":"Get one metric implementation","description":"Returns the status, category and localized documentation for one language variant, optionally narrowed to a genre.","operationId":"get_metric_v1_metrics__metric_id__get","parameters":[{"name":"metric_id","in":"path","required":true,"schema":{"type":"string","title":"Metric Id"},"description":"Stable conceptual metric identifier."},{"name":"analysis_language","in":"query","required":true,"schema":{"type":"string","title":"Analysis Language"},"description":"Language implementation to return: es, ca or en."},{"name":"documentation_language","in":"query","required":false,"schema":{"type":"string","default":"es","title":"Documentation Language"},"description":"Language used for titles and documentation: es, ca or en."},{"name":"domain_slug","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional genre filter. domain_slug and text_type_slug go together and must name a genre listed by GET /v1/text-types; each metric then reports whether that genre evaluates it and with which thresholds.","title":"Domain Slug"},"description":"Text domain of a genre, as listed by GET /v1/text-types."},{"name":"text_type_slug","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional genre filter. domain_slug and text_type_slug go together and must name a genre listed by GET /v1/text-types; each metric then reports whether that genre evaluates it and with which thresholds.","title":"Text Type Slug"},"description":"Text type (genre) inside domain_slug, as listed by GET /v1/text-types."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Metric"}}},"headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}}}},"401":{"description":"Missing, invalid, inactive or revoked API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiProblem"}}},"headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}}}},"404":{"description":"Metric implementation not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiProblem"}}},"headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}}}},"422":{"description":"Incomplete or unknown genre filter.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiProblem"}}},"headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}}}}},"security":[{"ApiKey":[]}]}},"/v1/text-types":{"get":{"tags":["Text types"],"summary":"List text domains and genres","description":"Returns the domains (ámbitos) and the genres (text types) available for a language. The slug pair of a genre is what POST /v1/reports expects.","operationId":"list_public_text_types_v1_text_types_get","parameters":[{"name":"language","in":"query","required":false,"schema":{"type":"string","default":"es","title":"Language"},"description":"Catalog language: es, ca or en."}],"responses":{"200":{"description":"Editorial catalog for the requested language.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTextTypeCatalog"}}},"headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}}}},"401":{"description":"Missing, invalid, inactive or revoked API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiProblem"}}},"headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}}}},"422":{"description":"Unsupported language.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiProblem"}}},"headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}}}}},"security":[{"ApiKey":[]}]}},"/v1/text-types/{domain_slug}/{text_type_slug}":{"get":{"tags":["Text types"],"summary":"Get one genre","description":"Returns the sections and contents recommended for a genre, plus the exact report_defaults to forward to POST /v1/reports.","operationId":"get_public_text_type_v1_text_types__domain_slug___text_type_slug__get","parameters":[{"name":"domain_slug","in":"path","required":true,"schema":{"type":"string","title":"Domain Slug"},"description":"Text domain of a genre, as listed by GET /v1/text-types."},{"name":"text_type_slug","in":"path","required":true,"schema":{"type":"string","title":"Text Type Slug"},"description":"Text type (genre) inside domain_slug, as listed by GET /v1/text-types."},{"name":"language","in":"query","required":false,"schema":{"type":"string","default":"es","title":"Language"},"description":"Catalog language: es, ca or en."}],"responses":{"200":{"description":"Genre detail and its report defaults.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTextTypeDetail"}}},"headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}}}},"401":{"description":"Missing, invalid, inactive or revoked API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiProblem"}}},"headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}}}},"404":{"description":"Genre not found for this language.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiProblem"}}},"headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}}}},"422":{"description":"Unsupported language.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiProblem"}}},"headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}}}}},"security":[{"ApiKey":[]}]}},"/v1/text-types/{domain_slug}/{text_type_slug}/glossaries":{"get":{"tags":["Text types"],"summary":"List the glossaries a genre resolves","description":"Returns which glossaries apply to a genre, how many entries each one resolves and which cascade level (genre, domain or language-wide) those entries come from. Glossary contents are not exposed.","operationId":"get_genre_glossaries_v1_text_types__domain_slug___text_type_slug__glossaries_get","parameters":[{"name":"domain_slug","in":"path","required":true,"schema":{"type":"string","title":"Domain Slug"},"description":"Text domain of a genre, as listed by GET /v1/text-types."},{"name":"text_type_slug","in":"path","required":true,"schema":{"type":"string","title":"Text Type Slug"},"description":"Text type (genre) inside domain_slug, as listed by GET /v1/text-types."},{"name":"language","in":"query","required":false,"schema":{"type":"string","default":"es","title":"Language"},"description":"Catalog language: es, ca or en."}],"responses":{"200":{"description":"Glossary availability for the genre.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenreGlossaries"}}},"headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}}}},"401":{"description":"Missing, invalid, inactive or revoked API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiProblem"}}},"headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}}}},"404":{"description":"Genre not found for this language.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiProblem"}}},"headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}}}},"422":{"description":"Unsupported language.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiProblem"}}},"headers":{"X-Request-ID":{"description":"Identifier to retain for support and tracing.","schema":{"type":"string","example":"req_4adf8f2c"}}}}},"security":[{"ApiKey":[]}]}}},"components":{"schemas":{"ApiProblem":{"properties":{"type":{"type":"string","title":"Type","description":"URI reference identifying the problem type."},"title":{"type":"string","title":"Title","description":"Short, stable problem title."},"status":{"type":"integer","title":"Status","description":"HTTP status code."},"detail":{"type":"string","title":"Detail","description":"Human-readable explanation for this occurrence."},"instance":{"type":"string","title":"Instance","description":"Request path for this occurrence."},"code":{"type":"string","title":"Code","description":"Stable machine-readable arText error code."},"request_id":{"type":"string","title":"Request Id","description":"Identifier to retain for support and tracing."},"retry_after_seconds":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Retry After Seconds"},"errors":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Errors"}},"type":"object","required":["type","title","status","detail","instance","code","request_id"],"title":"ApiProblem"},"Genre":{"properties":{"domain":{"$ref":"#/components/schemas/TextDomain"},"text_type":{"$ref":"#/components/schemas/TextType"}},"type":"object","required":["domain","text_type"],"title":"Genre","description":"Genre the report was analyzed with.\n\nIt names both coordinates because a text type slug is only unique inside\nits domain, and the pair is what determined the rules, the thresholds and\nthe glossaries used. Resubmitting these two slugs reproduces the analysis."},"GenreGlossaries":{"properties":{"language":{"type":"string","title":"Language"},"domain_slug":{"type":"string","title":"Domain Slug"},"text_type_slug":{"type":"string","title":"Text Type Slug"},"glossaries":{"items":{"$ref":"#/components/schemas/Glossary"},"type":"array","title":"Glossaries"}},"type":"object","required":["language","domain_slug","text_type_slug","glossaries"],"title":"GenreGlossaries"},"Glossary":{"properties":{"key":{"type":"string","title":"Key","description":"Stable glossary identifier."},"title":{"type":"string","title":"Title","description":"Human-readable glossary name."},"entry_count":{"type":"integer","title":"Entry Count","description":"Entries resolved for this genre, active or not."},"active_entry_count":{"type":"integer","title":"Active Entry Count","description":"Entries actually applied; the rest are deliberately disabled."},"source_level":{"type":"string","enum":["text_type","domain","global"],"title":"Source Level","description":"Cascade level the entries come from. The most specific level holding rows wins: the genre's own list, the domain's, or the language-wide one."},"inherited":{"type":"boolean","title":"Inherited","description":"True when source_level is less specific than the requested genre."},"used_by_metrics":{"items":{"type":"string"},"type":"array","title":"Used By Metrics","description":"metric_id values enabled for this genre that read this glossary."}},"type":"object","required":["key","title","entry_count","active_entry_count","source_level","inherited"],"title":"Glossary","description":"Disponibilidad de un glosario para un género. Sin contenido."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"Measurement":{"properties":{"metric_id":{"type":"string","title":"Metric Id","description":"Stable metric identifier documented by GET /v1/metrics/{metric_id}."},"value":{"anyOf":[{"type":"integer"},{"type":"number"}],"title":"Value","description":"Calculated numeric value."},"unit":{"type":"string","title":"Unit","description":"Semantic unit defined by the metric catalog."},"implementation_version":{"type":"string","title":"Implementation Version","description":"Calculator version used for this report."}},"type":"object","required":["metric_id","value","unit","implementation_version"],"title":"Measurement"},"Metric":{"properties":{"id":{"type":"string","title":"Id"},"kind":{"type":"string","enum":["measurement","rule"],"title":"Kind"},"analysis_language":{"type":"string","title":"Analysis Language"},"enabled":{"type":"boolean","title":"Enabled","description":"Whether reports for analysis_language currently evaluate this variant."},"genre_scope":{"anyOf":[{"$ref":"#/components/schemas/MetricGenreScope"},{"type":"null"}],"description":"Genre-specific status, present only when the request selects a genre."},"available":{"type":"boolean","title":"Available","description":"False when the variant can never produce output for analysis_language with the current linguistic runtime; see availability_note.","default":true},"availability_note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Availability Note","description":"Localized explanation present only when available is false."},"implementation_version":{"type":"string","title":"Implementation Version"},"category":{"type":"string","title":"Category"},"unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Unit"},"documentation_language":{"type":"string","title":"Documentation Language","description":"Language actually used by the returned documentation."},"documentation":{"$ref":"#/components/schemas/MetricDocumentation"},"references":{"items":{"type":"string"},"type":"array","title":"References"},"example":{"additionalProperties":true,"type":"object","title":"Example","description":"Example conforming to the public report contract."}},"type":"object","required":["id","kind","analysis_language","enabled","implementation_version","category","documentation_language","documentation"],"title":"Metric"},"MetricCatalog":{"properties":{"genre":{"anyOf":[{"$ref":"#/components/schemas/Genre"},{"type":"null"}],"description":"Genre the genre_scope of every metric refers to, when one was requested."},"metrics":{"items":{"$ref":"#/components/schemas/Metric"},"type":"array","title":"Metrics"}},"type":"object","required":["metrics"],"title":"MetricCatalog"},"MetricDocumentation":{"properties":{"title":{"type":"string","title":"Title","default":""},"summary":{"type":"string","title":"Summary","default":""},"methodology":{"type":"string","title":"Methodology","default":""},"limitations":{"type":"string","title":"Limitations","default":""},"interpretation":{"type":"string","title":"Interpretation","default":""}},"type":"object","title":"MetricDocumentation"},"MetricGenreScope":{"properties":{"enabled":{"type":"boolean","title":"Enabled","description":"Whether reports for this genre evaluate the metric."},"params":{"additionalProperties":true,"type":"object","title":"Params","description":"Thresholds this genre configures for the metric; empty means the defaults."}},"type":"object","required":["enabled"],"title":"MetricGenreScope","description":"How a metric behaves for one genre.\n\nPresent only when the request narrows the catalog with domain_slug and\ntext_type_slug. `enabled` is the intersection of the language variant and\nthe genre configuration: a variant enabled for the language still does not\nrun unless the genre opts into it."},"Occurrence":{"properties":{"id":{"type":"string","title":"Id","description":"Identifier unique within its parent recommendation."},"text":{"type":"string","title":"Text","description":"Fragment identified by the metric."},"paragraph_index":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Paragraph Index","description":"Zero-based paragraph index when available."},"sentence_index":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Sentence Index","description":"Zero-based sentence index when available."},"start":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Start","description":"Inclusive offset in the original input text."},"end":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"End","description":"Exclusive offset in the original input text."},"spans":{"items":{"$ref":"#/components/schemas/TextSpanBase"},"type":"array","title":"Spans","description":"Every appearance of this occurrence in the text, in reading order, when the metric identifies a unit rather than a single fragment: a repeated word or connector, or a glossary entry found in several places. The first entry is the one published in start/end. Empty when the occurrence appears only once."},"connectors":{"items":{"$ref":"#/components/schemas/SentenceConnectorBase"},"type":"array","title":"Connectors","description":"Discourse connectors found inside this occurrence, in reading order, with the alternatives that would fit if the sentence were split there. Only long sentences fill this; every other metric leaves it empty."},"replacement":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Replacement","description":"Preferred direct replacement, or null when none is available."},"alternatives":{"items":{"type":"string"},"type":"array","title":"Alternatives","description":"Additional reviewed replacement candidates, excluding replacement."},"edits":{"items":{"$ref":"#/components/schemas/TextEdit"},"type":"array","title":"Edits","description":"Validated edits for the preferred deterministic change, ordered from the highest offset to the lowest."}},"type":"object","required":["id","text"],"title":"Occurrence"},"PublicPhraseology":{"properties":{"value":{"type":"string","title":"Value","description":"Suggested wording for the content it belongs to."}},"type":"object","required":["value"],"title":"PublicPhraseology"},"PublicTextContent":{"properties":{"name":{"type":"string","title":"Name","description":"Content the section is expected to cover."},"occurrence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Occurrence","description":"How many times the content usually appears in the section, when the catalog states it."},"phraseology":{"items":{"$ref":"#/components/schemas/PublicPhraseology"},"type":"array","title":"Phraseology","description":"Wordings the editorial team proposes for this content."}},"type":"object","required":["name"],"title":"PublicTextContent"},"PublicTextDomain":{"properties":{"slug":{"type":"string","title":"Slug","description":"Domain identifier. Send it as domain_slug in POST /v1/reports."},"name":{"type":"string","title":"Name","description":"Domain name in the requested language."},"clear_language":{"type":"boolean","title":"Clear Language","description":"True when the whole domain is plain-language.","default":false},"text_types":{"items":{"$ref":"#/components/schemas/PublicTextType"},"type":"array","title":"Text Types","description":"Genres available inside this domain."}},"type":"object","required":["slug","name"],"title":"PublicTextDomain"},"PublicTextSection":{"properties":{"name":{"type":"string","title":"Name","description":"Section of the document, in reading order."},"contents":{"items":{"$ref":"#/components/schemas/PublicTextContent"},"type":"array","title":"Contents"}},"type":"object","required":["name"],"title":"PublicTextSection"},"PublicTextType":{"properties":{"slug":{"type":"string","title":"Slug","description":"Genre identifier. Send it as text_type_slug in POST /v1/reports."},"name":{"type":"string","title":"Name","description":"Genre name in the requested language."},"clear_language":{"type":"boolean","title":"Clear Language","description":"True when the genre is written in plain language for the general public.","default":false}},"type":"object","required":["slug","name"],"title":"PublicTextType"},"PublicTextTypeCatalog":{"properties":{"language":{"type":"string","title":"Language","description":"Language the catalog is returned in."},"domains":{"items":{"$ref":"#/components/schemas/PublicTextDomain"},"type":"array","title":"Domains"}},"type":"object","required":["language","domains"],"title":"PublicTextTypeCatalog"},"PublicTextTypeDetail":{"properties":{"language":{"type":"string","title":"Language"},"domain":{"$ref":"#/components/schemas/PublicTextDomain","description":"Domain the genre belongs to, without its sibling genres."},"text_type":{"$ref":"#/components/schemas/PublicTextType"},"structure":{"items":{"$ref":"#/components/schemas/PublicTextSection"},"type":"array","title":"Structure","description":"Sections and contents the editorial team recommends for this genre."},"report_defaults":{"$ref":"#/components/schemas/ReportDefaults","description":"Exact payload fragment to forward to POST /v1/reports."}},"type":"object","required":["language","domain","text_type","report_defaults"],"title":"PublicTextTypeDetail"},"Recommendation":{"properties":{"id":{"type":"string","title":"Id","description":"Identifier unique within this report."},"metric_id":{"type":"string","title":"Metric Id","description":"Stable metric identifier documented by GET /v1/metrics/{metric_id}."},"implementation_version":{"type":"string","title":"Implementation Version","description":"Detector version used for this report."},"metric_title":{"type":"string","title":"Metric Title","description":"Localized human-readable metric title captured for this report."},"category":{"type":"string","title":"Category","description":"Stable linguistic category used by the metric catalog."},"summary":{"type":"string","title":"Summary","description":"Explanation of the issue found in this report."},"explanation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Explanation","description":"Optional extended contextual explanation."},"guidance":{"items":{"type":"string"},"type":"array","title":"Guidance","description":"Human-readable review guidance written by the editorial team."},"examples":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Examples","description":"Optional worked examples illustrating the recommendation, as plain text with meaningful line breaks. Editorial copy attached to the metric: it never quotes the analysed text and does not vary between reports. Null when the metric's copy has no examples."},"occurrences":{"items":{"$ref":"#/components/schemas/Occurrence"},"type":"array","title":"Occurrences","description":"Concrete appearances of this issue in the submitted text, in reading order: sorted by `start`, with occurrences that could not be located last. The order of the recommendations themselves is linguistic, not positional."}},"type":"object","required":["id","metric_id","implementation_version","metric_title","category","summary"],"title":"Recommendation","description":"Un problema encontrado por una regla, con todas sus apariciones.\n\nEl contrato público la llama `Recommendation` y no `Suggestion` porque es\nel término que usa el producto de cara a quien lo lee. El modelo interno\n(`app.domain.models.Suggestion`) conserva su nombre: el renombrado es de la\nproyección pública, no de la nomenclatura del motor."},"Report":{"properties":{"report_id":{"type":"string","title":"Report Id"},"external_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"External Id"},"status":{"$ref":"#/components/schemas/ReportStatus"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At","description":"UTC acceptance timestamp."},"updated_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updated At","description":"UTC last-transition timestamp."},"started_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Started At","description":"UTC processing start timestamp."},"finished_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Finished At","description":"UTC terminal timestamp."},"position_in_queue":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Position In Queue","description":"Approximate queue position while waiting."},"phase":{"anyOf":[{"$ref":"#/components/schemas/ReportPhase"},{"type":"null"}],"description":"Pipeline stage while the report is running: `analyzing` (linguistic analysis, by far the longest part) or `building` (applying rules). Not a percentage: it marks what the server is doing, not how far along it is."},"estimated_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Estimated Seconds","description":"Rough estimate of the analysis duration, derived from the text length when the report was accepted. Indicative only: it excludes queue wait and does not react to server load."},"result":{"anyOf":[{"$ref":"#/components/schemas/ReportResult"},{"type":"null"}],"description":"Analysis result, present only when completed."},"error":{"anyOf":[{"$ref":"#/components/schemas/ReportFailure"},{"type":"null"}],"description":"Safe failure information, present only when failed."}},"type":"object","required":["report_id","status"],"title":"Report"},"ReportAccepted":{"properties":{"report_id":{"type":"string","title":"Report Id","description":"Unique arText report identifier."},"external_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"External Id","description":"Caller-provided correlation identifier."},"status":{"$ref":"#/components/schemas/ReportStatus","description":"Initial queue status; always queued for a newly accepted report."},"status_url":{"type":"string","title":"Status Url","description":"Relative URL of the report status resource."},"events_url":{"type":"string","title":"Events Url","description":"Relative URL of the optional SSE status stream."},"estimated_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Estimated Seconds","description":"Rough estimate of how long the analysis will take, derived from the length of the submitted text. Indicative only: it excludes queue wait and does not react to server load."}},"type":"object","required":["report_id","status","status_url","events_url"],"title":"ReportAccepted"},"ReportDefaults":{"properties":{"language":{"type":"string","title":"Language","description":"Analysis language the slugs below belong to."},"domain_slug":{"type":"string","title":"Domain Slug","description":"Value for the domain_slug field of a report request."},"text_type_slug":{"type":"string","title":"Text Type Slug","description":"Value for the text_type_slug field of a report request."}},"type":"object","required":["language","domain_slug","text_type_slug"],"title":"ReportDefaults","description":"Exact fields to forward to POST /v1/reports for this genre."},"ReportFailure":{"properties":{"code":{"type":"string","const":"analysis_failed","title":"Code","default":"analysis_failed"},"message":{"type":"string","title":"Message","description":"Safe failure description suitable for API clients."}},"type":"object","required":["message"],"title":"ReportFailure"},"ReportPhase":{"type":"string","enum":["analyzing","building"],"title":"ReportPhase","description":"Punto de la tubería mientras el estado es `running`.\n\nNo es un porcentaje y no debe presentarse como tal: `analyzing` se lleva el\n94 % del tiempo (una única llamada a FreeLing, que no informa de su avance),\nasí que una barra basada en esto se quedaría clavada casi todo el rato. Sirve\npara decir qué está pasando y que sigue vivo; para «cuánto queda» está\n`estimated_seconds`."},"ReportRequest":{"properties":{"language":{"type":"string","title":"Language","description":"Language used for analysis: es, ca or en.","default":"es"},"domain_slug":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"title":"Domain Slug","description":"Optional text domain (ámbito) the genre belongs to, as listed by GET /v1/text-types. Omit it to name the genre by text_type_slug alone; send it only to disambiguate after a 422 with code ambiguous-genre.","examples":["lenguaje-claro"]},"text_type_slug":{"type":"string","minLength":1,"title":"Text Type Slug","description":"Text type (genre) inside domain_slug, as listed by GET /v1/text-types. The pair selects the rules, thresholds and glossaries applied to the text.","examples":["texto-juridico-administrativo-dirigido-a-la-ciudadania"]},"text":{"type":"string","minLength":1,"title":"Text","description":"Plain text to analyze."},"external_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"External Id","description":"Optional caller-owned correlation identifier returned unchanged."}},"additionalProperties":false,"type":"object","required":["text_type_slug","text"],"title":"ReportRequest","description":"Stable input accepted from API integrations."},"ReportResult":{"properties":{"schema_version":{"type":"string","const":"2.0","title":"Schema Version","description":"Version of this public result contract.","default":"2.0"},"language":{"type":"string","title":"Language","description":"Language actually used for analysis."},"genre":{"$ref":"#/components/schemas/Genre"},"measurements":{"items":{"$ref":"#/components/schemas/Measurement"},"type":"array","title":"Measurements"},"recommendations":{"items":{"$ref":"#/components/schemas/Recommendation"},"type":"array","title":"Recommendations","description":"Issues found by the suggestion rules, one item per rule that matched."},"applied_thresholds":{"additionalProperties":{"additionalProperties":true,"type":"object"},"type":"object","title":"Applied Thresholds","description":"Thresholds each rule actually read while evaluating this report, keyed by metric_id. Rules disabled for the genre never run and are absent. Values are the effective ones, whether configured for the genre or inherited from the language defaults."},"offset_unit":{"type":"string","const":"unicode_code_points","title":"Offset Unit","description":"Unit used by every start and end offset in the result.","default":"unicode_code_points"}},"type":"object","required":["language","genre"],"title":"ReportResult"},"ReportStatus":{"type":"string","enum":["queued","running","completed","failed"],"title":"ReportStatus"},"SentenceConnectorBase":{"properties":{"start":{"type":"integer","minimum":0.0,"title":"Start","description":"Inclusive offset in the original input text."},"end":{"type":"integer","minimum":0.0,"title":"End","description":"Exclusive offset in the original input text."},"text":{"type":"string","title":"Text","description":"Fragment found in this range."},"relation":{"type":"string","title":"Relation","description":"Semantic relation the connector expresses (cause, antithesis, concession…), as named by the discourse connector model."},"scope":{"type":"string","pattern":"^(intra|inter)$","title":"Scope","description":"Whether the connector joins clauses inside one sentence (intra) or links separate sentences (inter). The ones found inside a long sentence are intra; their alternatives are inter, because splitting turns the parts into sentences."},"alternatives":{"items":{"type":"string"},"type":"array","title":"Alternatives","description":"Inter-sentence connectors of the same relation, capitalised and in alphabetical order: what to write instead if the sentence is split at this point."}},"type":"object","required":["start","end","text","relation","scope"],"title":"SentenceConnectorBase","description":"A discourse connector found inside a long sentence, with its position.\n\nIt is not another appearance of the occurrence —that is what `spans` is for—\nbut something that lives inside it: the connector joining two clauses of a\nsentence the report proposes to split. Splitting turns those clauses into\nseparate sentences, so the connector would have to change with them, and\nthat is why it travels with its own alternatives."},"TextDomain":{"properties":{"slug":{"type":"string","title":"Slug","description":"Stable text domain identifier accepted by POST /v1/reports."},"name":{"type":"string","title":"Name","description":"Localized text domain name."}},"type":"object","required":["slug","name"],"title":"TextDomain"},"TextEdit":{"properties":{"start":{"type":"integer","minimum":0.0,"title":"Start","description":"Inclusive offset in the original input text."},"end":{"type":"integer","minimum":0.0,"title":"End","description":"Exclusive offset in the original input text."},"text":{"type":"string","title":"Text","description":"Text to splice into the range. Empty text deletes it; start == end inserts text."}},"type":"object","required":["start","end","text"],"title":"TextEdit"},"TextSpanBase":{"properties":{"start":{"type":"integer","minimum":0.0,"title":"Start","description":"Inclusive offset in the original input text."},"end":{"type":"integer","minimum":0.0,"title":"End","description":"Exclusive offset in the original input text."},"text":{"type":"string","title":"Text","description":"Fragment found in this range."}},"type":"object","required":["start","end","text"],"title":"TextSpanBase","description":"Un tramo del texto original, con lo que hay escrito en él."},"TextType":{"properties":{"slug":{"type":"string","title":"Slug","description":"Stable text type identifier accepted by POST /v1/reports."},"name":{"type":"string","title":"Name","description":"Localized text type name."}},"type":"object","required":["slug","name"],"title":"TextType"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}},"securitySchemes":{"ApiKey":{"type":"http","scheme":"bearer","bearerFormat":"art_live_…"}}},"servers":[{"url":"http://demo.sistema-artext.com"}],"x-artext-metrics":[{"id":"average-sentence-words","kind":"measurement","analysis_language":"ca","enabled":true,"genre_scope":null,"available":true,"availability_note":null,"implementation_version":"1.0","category":"readability","unit":"words","documentation_language":"ca","documentation":{"title":"Average sentence words","summary":"Mitjana de paraules per oració.","methodology":"Divideix word-count per sentence-count i arrodoneix a dos decimals; retorna 0 si no hi ha oracions.","limitations":"El valor depèn de la normalització i segmentació de l'analitzador; cal interpretar-lo juntament amb les altres mètriques i el gènere textual.","interpretation":"`value` conté el resultat numèric i `unit` és `words`. L'absència indica que la variant estava desactivada."},"references":[],"example":{"metric_id":"average-sentence-words","value":24,"unit":"words","implementation_version":"1.0"}},{"id":"maximum-paragraph-words","kind":"measurement","analysis_language":"ca","enabled":true,"genre_scope":null,"available":true,"availability_note":null,"implementation_version":"1.0","category":"readability","unit":"words","documentation_language":"ca","documentation":{"title":"Maximum paragraph words","summary":"Longitud, en paraules, del paràgraf més extens.","methodology":"Obté el màxim de word_count entre els paràgrafs detectats; retorna 0 si no n'hi ha cap.","limitations":"El valor depèn de la normalització i segmentació de l'analitzador; cal interpretar-lo juntament amb les altres mètriques i el gènere textual.","interpretation":"`value` conté el resultat numèric i `unit` és `words`. L'absència indica que la variant estava desactivada."},"references":[],"example":{"metric_id":"maximum-paragraph-words","value":24,"unit":"words","implementation_version":"1.0"}},{"id":"maximum-sentence-words","kind":"measurement","analysis_language":"ca","enabled":true,"genre_scope":null,"available":true,"availability_note":null,"implementation_version":"1.0","category":"readability","unit":"words","documentation_language":"ca","documentation":{"title":"Maximum sentence words","summary":"Longitud, en paraules, de l'oració més extensa.","methodology":"Obté el màxim de word_count entre les oracions segmentades; retorna 0 si no n'hi ha cap.","limitations":"El valor depèn de la normalització i segmentació de l'analitzador; cal interpretar-lo juntament amb les altres mètriques i el gènere textual.","interpretation":"`value` conté el resultat numèric i `unit` és `words`. L'absència indica que la variant estava desactivada."},"references":[],"example":{"metric_id":"maximum-sentence-words","value":24,"unit":"words","implementation_version":"1.0"}},{"id":"paragraph-count","kind":"measurement","analysis_language":"ca","enabled":true,"genre_scope":null,"available":true,"availability_note":null,"implementation_version":"1.0","category":"document","unit":"count","documentation_language":"ca","documentation":{"title":"Paragraph count","summary":"Nombre de paràgrafs no buits detectats.","methodology":"Segmenta el text en paràgrafs i compta les unitats amb contingut analitzable.","limitations":"El valor depèn de la normalització i segmentació de l'analitzador; cal interpretar-lo juntament amb les altres mètriques i el gènere textual.","interpretation":"`value` conté el resultat numèric i `unit` és `count`. L'absència indica que la variant estava desactivada."},"references":[],"example":{"metric_id":"paragraph-count","value":24,"unit":"count","implementation_version":"1.0"}},{"id":"segment-count","kind":"measurement","analysis_language":"ca","enabled":true,"genre_scope":null,"available":true,"availability_note":null,"implementation_version":"1.0","category":"document","unit":"count","documentation_language":"ca","documentation":{"title":"Segment count","summary":"Nombre de segments interns d'oració reconeguts.","methodology":"Suma els segments sintacticodiscursius produïts per DiSeg per a totes les oracions.","limitations":"El valor depèn de la normalització i segmentació de l'analitzador; cal interpretar-lo juntament amb les altres mètriques i el gènere textual.","interpretation":"`value` conté el resultat numèric i `unit` és `count`. L'absència indica que la variant estava desactivada."},"references":[],"example":{"metric_id":"segment-count","value":24,"unit":"count","implementation_version":"1.0"}},{"id":"sentence-count","kind":"measurement","analysis_language":"ca","enabled":true,"genre_scope":null,"available":true,"availability_note":null,"implementation_version":"1.0","category":"document","unit":"count","documentation_language":"ca","documentation":{"title":"Sentence count","summary":"Nombre d'oracions segmentades per l'analitzador.","methodology":"Compta les oracions reconegudes per FreeLing/DiSeg, no només els punts del text.","limitations":"El valor depèn de la normalització i segmentació de l'analitzador; cal interpretar-lo juntament amb les altres mètriques i el gènere textual.","interpretation":"`value` conté el resultat numèric i `unit` és `count`. L'absència indica que la variant estava desactivada."},"references":[],"example":{"metric_id":"sentence-count","value":24,"unit":"count","implementation_version":"1.0"}},{"id":"token-count","kind":"measurement","analysis_language":"ca","enabled":true,"genre_scope":null,"available":true,"availability_note":null,"implementation_version":"1.0","category":"document","unit":"count","documentation_language":"ca","documentation":{"title":"Token count","summary":"Nombre d'unitats lèxiques produïdes per l'analitzador.","methodology":"Compta els tokens de FreeLing/DiSeg; la puntuació i les contraccions poden fer que difereixi de word-count.","limitations":"El valor depèn de la normalització i segmentació de l'analitzador; cal interpretar-lo juntament amb les altres mètriques i el gènere textual.","interpretation":"`value` conté el resultat numèric i `unit` és `count`. L'absència indica que la variant estava desactivada."},"references":[],"example":{"metric_id":"token-count","value":24,"unit":"count","implementation_version":"1.0"}},{"id":"word-count","kind":"measurement","analysis_language":"ca","enabled":true,"genre_scope":null,"available":true,"availability_note":null,"implementation_version":"1.0","category":"document","unit":"count","documentation_language":"ca","documentation":{"title":"Word count","summary":"Nombre de paraules del text normalitzat.","methodology":"Normalitza els espais del text i compta cada element no buit separat per espais.","limitations":"El valor depèn de la normalització i segmentació de l'analitzador; cal interpretar-lo juntament amb les altres mètriques i el gènere textual.","interpretation":"`value` conté el resultat numèric i `unit` és `count`. L'absència indica que la variant estava desactivada."},"references":[],"example":{"metric_id":"word-count","value":24,"unit":"count","implementation_version":"1.0"}},{"id":"acronym-consistency","kind":"rule","analysis_language":"ca","enabled":true,"genre_scope":null,"available":true,"availability_note":null,"implementation_version":"1.2","category":"lexical","unit":null,"documentation_language":"ca","documentation":{"title":"Sistematicitat en l'ús de sigles","summary":"Detecta repeticions del terme desenvolupat després que ja s'hagi introduït la sigla.","methodology":"Després d'identificar sigla i desenvolupament a la primera aparició, cerca si el desenvolupament complet torna a aparèixer més endavant.","limitations":"És un senyal de revisió, no una correcció automàtica ni una avaluació completa de la qualitat del text.","interpretation":"Cada element d'`occurrences` identifica un fragment afectat. `start` és inclusiu i `end` exclusiu, tots dos mesurats en punts de codi Unicode sobre el text enviat. `replacement`, `alternatives` i `edits` només contenen valors quan hi ha un canvi segur; l'absència del suggeriment significa que no hi ha coincidències, no que el text sigui necessàriament correcte."},"references":[],"example":{"id":"rec_1","metric_id":"acronym-consistency","implementation_version":"1.2","metric_title":"Sistematicitat en l'ús de sigles","category":"lexical","summary":"Example detection returned by this metric.","explanation":null,"guidance":["Review the detected fragment in context."],"examples":null,"occurrences":[{"id":"occ_1","text":"example","paragraph_index":0,"sentence_index":0,"start":18,"end":25,"spans":[],"connectors":[],"replacement":null,"alternatives":[],"edits":[]}]}},{"id":"acronym-introduction","kind":"rule","analysis_language":"ca","enabled":true,"genre_scope":null,"available":true,"availability_note":null,"implementation_version":"1.2","category":"lexical","unit":null,"documentation_language":"ca","documentation":{"title":"Introducció de sigles","summary":"Detecta la primera aparició de sigles en majúscules que no semblen acompanyades pel seu desenvolupament.","methodology":"Extreu candidats en majúscules, ignora paraules buides, conserva la primera aparició i cerca un desenvolupament adjacent abans o després.","limitations":"És un senyal de revisió, no una correcció automàtica ni una avaluació completa de la qualitat del text.","interpretation":"Cada element d'`occurrences` identifica un fragment afectat. `start` és inclusiu i `end` exclusiu, tots dos mesurats en punts de codi Unicode sobre el text enviat. `replacement`, `alternatives` i `edits` només contenen valors quan hi ha un canvi segur; l'absència del suggeriment significa que no hi ha coincidències, no que el text sigui necessàriament correcte."},"references":[],"example":{"id":"rec_1","metric_id":"acronym-introduction","implementation_version":"1.2","metric_title":"Introducció de sigles","category":"lexical","summary":"Example detection returned by this metric.","explanation":null,"guidance":["Review the detected fragment in context."],"examples":null,"occurrences":[{"id":"occ_1","text":"example","paragraph_index":0,"sentence_index":0,"start":18,"end":25,"spans":[],"connectors":[],"replacement":null,"alternatives":[],"edits":[]}]}},{"id":"archaic-verb-forms","kind":"rule","analysis_language":"ca","enabled":true,"genre_scope":null,"available":true,"availability_note":null,"implementation_version":"1.2","category":"morphosyntax","unit":null,"documentation_language":"ca","documentation":{"title":"Eliminació de formes verbals arcaiques","summary":"Detecta formes etiquetades com a futur de subjuntiu, considerades arcaiques en l'ús general actual.","methodology":"Cerca etiquetes FreeLing que comencen per VSSF, VASF o VMSF, també a vaux-cat, excloent auxiliars.","limitations":"Depèn de l'etiquetatge de FreeLing/DiSeg i pot produir falsos positius o perdre construccions ambigües.","interpretation":"Cada element d'`occurrences` identifica un fragment afectat. `start` és inclusiu i `end` exclusiu, tots dos mesurats en punts de codi Unicode sobre el text enviat. `replacement`, `alternatives` i `edits` només contenen valors quan hi ha un canvi segur; l'absència del suggeriment significa que no hi ha coincidències, no que el text sigui necessàriament correcte."},"references":[],"example":{"id":"rec_1","metric_id":"archaic-verb-forms","implementation_version":"1.2","metric_title":"Eliminació de formes verbals arcaiques","category":"morphosyntax","summary":"Example detection returned by this metric.","explanation":null,"guidance":["Review the detected fragment in context."],"examples":null,"occurrences":[{"id":"occ_1","text":"example","paragraph_index":0,"sentence_index":0,"start":18,"end":25,"spans":[],"connectors":[],"replacement":null,"alternatives":[],"edits":[]}]}},{"id":"connector-variety","kind":"rule","analysis_language":"ca","enabled":true,"genre_scope":null,"available":true,"availability_note":null,"implementation_version":"1.2","category":"discourse","unit":null,"documentation_language":"ca","documentation":{"title":"Variació de connectors","summary":"Detecta connectors discursius repetits per sobre del llindar i ofereix alternatives de la mateixa relació.","methodology":"Compta nodes disc_mk de l'XML, en normalitza les formes i assenyala connectors del model amb freqüència superior a n_variacion_conectores. La detecció utilitza el catàleg editorial actiu per a l'idioma.","limitations":"Depèn de la cobertura i la qualitat del catàleg actiu per a l'idioma; cada coincidència requereix revisió contextual.","interpretation":"Cada element d'`occurrences` identifica un fragment afectat. `start` és inclusiu i `end` exclusiu, tots dos mesurats en punts de codi Unicode sobre el text enviat. `replacement`, `alternatives` i `edits` només contenen valors quan hi ha un canvi segur; l'absència del suggeriment significa que no hi ha coincidències, no que el text sigui necessàriament correcte."},"references":[],"example":{"id":"rec_1","metric_id":"connector-variety","implementation_version":"1.2","metric_title":"Variació de connectors","category":"discourse","summary":"Example detection returned by this metric.","explanation":null,"guidance":["Review the detected fragment in context."],"examples":null,"occurrences":[{"id":"occ_1","text":"example","paragraph_index":0,"sentence_index":0,"start":18,"end":25,"spans":[],"connectors":[],"replacement":null,"alternatives":[],"edits":[]}]}},{"id":"definition-usage","kind":"rule","analysis_language":"ca","enabled":true,"genre_scope":null,"available":true,"availability_note":null,"implementation_version":"1.2","category":"lexical","unit":null,"documentation_language":"ca","documentation":{"title":"Ús de definicions","summary":"Compara el nombre d'indicadors de definició del text amb el valor de referència del gènere textual.","methodology":"Compta els marcadors de definició del text i els compara amb el valor de referència del gènere; el paràmetre de mode decideix si l'avís s'emet per excés o per defecte. La detecció utilitza el catàleg editorial actiu per a l'idioma.","limitations":"Depèn de la cobertura i la qualitat del catàleg actiu per a l'idioma; cada coincidència requereix revisió contextual.","interpretation":"Cada element d'`occurrences` identifica un fragment afectat. `start` és inclusiu i `end` exclusiu, tots dos mesurats en punts de codi Unicode sobre el text enviat. `replacement`, `alternatives` i `edits` només contenen valors quan hi ha un canvi segur; l'absència del suggeriment significa que no hi ha coincidències, no que el text sigui necessàriament correcte."},"references":[],"example":{"id":"rec_1","metric_id":"definition-usage","implementation_version":"1.2","metric_title":"Ús de definicions","category":"lexical","summary":"Example detection returned by this metric.","explanation":null,"guidance":["Review the detected fragment in context."],"examples":null,"occurrences":[{"id":"occ_1","text":"example","paragraph_index":0,"sentence_index":0,"start":18,"end":25,"spans":[],"connectors":[],"replacement":null,"alternatives":[],"edits":[]}]}},{"id":"difficult-expressions","kind":"rule","analysis_language":"ca","enabled":true,"genre_scope":null,"available":true,"availability_note":null,"implementation_version":"1.2","category":"lexical","unit":null,"documentation_language":"ca","documentation":{"title":"Substitució d'expressions difícils d'entendre","summary":"Localitza expressions difícils d'entendre incloses al catàleg i retorna alternatives quan n'hi ha.","methodology":"Cerca expressions completes directament sobre el text, sense distingir majúscules ni accents i respectant límits de paraula. La detecció utilitza el catàleg editorial actiu per a l'idioma.","limitations":"Depèn de la cobertura i la qualitat del catàleg actiu per a l'idioma; cada coincidència requereix revisió contextual.","interpretation":"Cada element d'`occurrences` identifica un fragment afectat. `start` és inclusiu i `end` exclusiu, tots dos mesurats en punts de codi Unicode sobre el text enviat. `replacement`, `alternatives` i `edits` només contenen valors quan hi ha un canvi segur; l'absència del suggeriment significa que no hi ha coincidències, no que el text sigui necessàriament correcte."},"references":[],"example":{"id":"rec_1","metric_id":"difficult-expressions","implementation_version":"1.2","metric_title":"Substitució d'expressions difícils d'entendre","category":"lexical","summary":"Example detection returned by this metric.","explanation":null,"guidance":["Review the detected fragment in context."],"examples":null,"occurrences":[{"id":"occ_1","text":"example","paragraph_index":0,"sentence_index":0,"start":18,"end":25,"spans":[],"connectors":[],"replacement":null,"alternatives":[],"edits":[]}]}},{"id":"gerunds","kind":"rule","analysis_language":"ca","enabled":true,"genre_scope":null,"available":true,"availability_note":null,"implementation_version":"1.2","category":"morphosyntax","unit":null,"documentation_language":"ca","documentation":{"title":"Revisió de gerundis","summary":"Localitza gerundis independents que convé revisar, excloent auxiliars i construccions compostes reconegudes.","methodology":"Usa etiquetes verbals de gerundi (VBG en EN) i atributs auxiliars per excloure perífrasis ja reconegudes.","limitations":"Depèn de l'etiquetatge de FreeLing/DiSeg i pot produir falsos positius o perdre construccions ambigües.","interpretation":"Cada element d'`occurrences` identifica un fragment afectat. `start` és inclusiu i `end` exclusiu, tots dos mesurats en punts de codi Unicode sobre el text enviat. `replacement`, `alternatives` i `edits` només contenen valors quan hi ha un canvi segur; l'absència del suggeriment significa que no hi ha coincidències, no que el text sigui necessàriament correcte."},"references":[],"example":{"id":"rec_1","metric_id":"gerunds","implementation_version":"1.2","metric_title":"Revisió de gerundis","category":"morphosyntax","summary":"Example detection returned by this metric.","explanation":null,"guidance":["Review the detected fragment in context."],"examples":null,"occurrences":[{"id":"occ_1","text":"example","paragraph_index":0,"sentence_index":0,"start":18,"end":25,"spans":[],"connectors":[],"replacement":null,"alternatives":[],"edits":[]}]}},{"id":"imprecise-words","kind":"rule","analysis_language":"ca","enabled":true,"genre_scope":null,"available":true,"availability_note":null,"implementation_version":"1.2","category":"lexical","unit":null,"documentation_language":"ca","documentation":{"title":"Substitució de paraules poc precises","summary":"Localitza paraules o seqüències poc precises incloses al catàleg editable i n'ofereix alternatives.","methodology":"Normalitza els lemes dels tokens i cerca seqüències completes del catàleg actiu; retorna terme, alternativa i posicions de text quan estan disponibles. La detecció utilitza el catàleg editorial actiu per a l'idioma.","limitations":"Depèn de la cobertura i la qualitat del catàleg actiu per a l'idioma; cada coincidència requereix revisió contextual.","interpretation":"Cada element d'`occurrences` identifica un fragment afectat. `start` és inclusiu i `end` exclusiu, tots dos mesurats en punts de codi Unicode sobre el text enviat. `replacement`, `alternatives` i `edits` només contenen valors quan hi ha un canvi segur; l'absència del suggeriment significa que no hi ha coincidències, no que el text sigui necessàriament correcte."},"references":[],"example":{"id":"rec_1","metric_id":"imprecise-words","implementation_version":"1.2","metric_title":"Substitució de paraules poc precises","category":"lexical","summary":"Example detection returned by this metric.","explanation":null,"guidance":["Review the detected fragment in context."],"examples":null,"occurrences":[{"id":"occ_1","text":"example","paragraph_index":0,"sentence_index":0,"start":18,"end":25,"spans":[],"connectors":[],"replacement":null,"alternatives":[],"edits":[]}]}},{"id":"list-usage","kind":"rule","analysis_language":"ca","enabled":true,"genre_scope":null,"available":true,"availability_note":null,"implementation_version":"1.2","category":"discourse","unit":null,"documentation_language":"ca","documentation":{"title":"Inclusió de llistes","summary":"Avisa, sense assenyalar cap fragment, quan no s'ha reconegut cap llista estructurada al text.","methodology":"Retorna un únic suggeriment de document, sense posicions de text, quan has_list és fals; has_list s'obté del text i de l'HTML estructurat.","limitations":"Depèn de la segmentació del text pla i que els marcadors estructurals siguin recognoscibles; no implica per si sola un error de redacció.","interpretation":"Cada element d'`occurrences` identifica un fragment afectat. `start` és inclusiu i `end` exclusiu, tots dos mesurats en punts de codi Unicode sobre el text enviat. `replacement`, `alternatives` i `edits` només contenen valors quan hi ha un canvi segur; l'absència del suggeriment significa que no hi ha coincidències, no que el text sigui necessàriament correcte."},"references":[],"example":{"id":"rec_1","metric_id":"list-usage","implementation_version":"1.2","metric_title":"Inclusió de llistes","category":"discourse","summary":"Example detection returned by this metric.","explanation":null,"guidance":["Review the detected fragment in context."],"examples":null,"occurrences":[{"id":"occ_1","text":"example","paragraph_index":0,"sentence_index":0,"start":18,"end":25,"spans":[],"connectors":[],"replacement":null,"alternatives":[],"edits":[]}]}},{"id":"long-paragraphs","kind":"rule","analysis_language":"ca","enabled":true,"genre_scope":null,"available":true,"availability_note":null,"implementation_version":"1.2","category":"discourse","unit":null,"documentation_language":"ca","documentation":{"title":"Revisió de paràgrafs llargs","summary":"Assenyala paràgrafs que superen el límit de paraules configurat per al gènere textual.","methodology":"Compara word_count de cada paràgraf amb n_palabras_por_parrafo del gènere; només informa valors estrictament superiors.","limitations":"Depèn de la segmentació del text pla i que els marcadors estructurals siguin recognoscibles; no implica per si sola un error de redacció.","interpretation":"Cada element d'`occurrences` identifica un fragment afectat. `start` és inclusiu i `end` exclusiu, tots dos mesurats en punts de codi Unicode sobre el text enviat. `replacement`, `alternatives` i `edits` només contenen valors quan hi ha un canvi segur; l'absència del suggeriment significa que no hi ha coincidències, no que el text sigui necessàriament correcte."},"references":[],"example":{"id":"rec_1","metric_id":"long-paragraphs","implementation_version":"1.2","metric_title":"Revisió de paràgrafs llargs","category":"discourse","summary":"Example detection returned by this metric.","explanation":null,"guidance":["Review the detected fragment in context."],"examples":null,"occurrences":[{"id":"occ_1","text":"example","paragraph_index":0,"sentence_index":0,"start":18,"end":25,"spans":[],"connectors":[],"replacement":null,"alternatives":[],"edits":[]}]}},{"id":"long-sentences","kind":"rule","analysis_language":"ca","enabled":true,"genre_scope":null,"available":true,"availability_note":null,"implementation_version":"1.2","category":"discourse","unit":null,"documentation_language":"ca","documentation":{"title":"Revisió d'oracions llargues","summary":"Assenyala oracions que superen el límit de paraules configurat per al gènere textual i, quan l'oració admet divisió, els punts on es podria partir.","methodology":"Selecciona oracions amb més de n_division_oraciones paraules; en les que tenen diversos segments retorna a més segments, connectors i possibles límits de divisió.","limitations":"Depèn de la segmentació del text pla i que els marcadors estructurals siguin recognoscibles; no implica per si sola un error de redacció.","interpretation":"Cada element d'`occurrences` identifica un fragment afectat. `start` és inclusiu i `end` exclusiu, tots dos mesurats en punts de codi Unicode sobre el text enviat. `replacement`, `alternatives` i `edits` només contenen valors quan hi ha un canvi segur; l'absència del suggeriment significa que no hi ha coincidències, no que el text sigui necessàriament correcte."},"references":[],"example":{"id":"rec_1","metric_id":"long-sentences","implementation_version":"1.2","metric_title":"Revisió d'oracions llargues","category":"discourse","summary":"Example detection returned by this metric.","explanation":null,"guidance":["Review the detected fragment in context."],"examples":null,"occurrences":[{"id":"occ_1","text":"example","paragraph_index":0,"sentence_index":0,"start":18,"end":25,"spans":[],"connectors":[],"replacement":null,"alternatives":[],"edits":[]}]}},{"id":"long-words","kind":"rule","analysis_language":"ca","enabled":true,"genre_scope":null,"available":true,"availability_note":null,"implementation_version":"1.2","category":"lexical","unit":null,"documentation_language":"ca","documentation":{"title":"Revisió de paraules llargues","summary":"Localitza paraules llargues incloses al catàleg editorial i proposa alternatives més breus quan n'hi ha.","methodology":"Normalitza els lemes dels tokens i cerca seqüències completes del catàleg actiu; retorna terme, alternativa i posicions de text quan estan disponibles. La detecció utilitza el catàleg editorial actiu per a l'idioma.","limitations":"Depèn de la cobertura i la qualitat del catàleg actiu per a l'idioma; cada coincidència requereix revisió contextual.","interpretation":"Cada element d'`occurrences` identifica un fragment afectat. `start` és inclusiu i `end` exclusiu, tots dos mesurats en punts de codi Unicode sobre el text enviat. `replacement`, `alternatives` i `edits` només contenen valors quan hi ha un canvi segur; l'absència del suggeriment significa que no hi ha coincidències, no que el text sigui necessàriament correcte."},"references":[],"example":{"id":"rec_1","metric_id":"long-words","implementation_version":"1.2","metric_title":"Revisió de paraules llargues","category":"lexical","summary":"Example detection returned by this metric.","explanation":null,"guidance":["Review the detected fragment in context."],"examples":null,"occurrences":[{"id":"occ_1","text":"example","paragraph_index":0,"sentence_index":0,"start":18,"end":25,"spans":[],"connectors":[],"replacement":null,"alternatives":[],"edits":[]}]}},{"id":"missing-definitions","kind":"rule","analysis_language":"ca","enabled":true,"genre_scope":null,"available":true,"availability_note":null,"implementation_version":"1.2","category":"lexical","unit":null,"documentation_language":"ca","documentation":{"title":"Manca de definicions","summary":"Avisa quan el text no conté cap indicador de definició i el gènere textual acostuma a incloure definicions.","methodology":"Cerca marcadors de definició (un verb definitori al costat d'una paraula de contorn) i retorna un avís documental si el text no en conté cap. La detecció utilitza el catàleg editorial actiu per a l'idioma.","limitations":"Depèn de la cobertura i la qualitat del catàleg actiu per a l'idioma; cada coincidència requereix revisió contextual.","interpretation":"Cada element d'`occurrences` identifica un fragment afectat. `start` és inclusiu i `end` exclusiu, tots dos mesurats en punts de codi Unicode sobre el text enviat. `replacement`, `alternatives` i `edits` només contenen valors quan hi ha un canvi segur; l'absència del suggeriment significa que no hi ha coincidències, no que el text sigui necessàriament correcte."},"references":[],"example":{"id":"rec_1","metric_id":"missing-definitions","implementation_version":"1.2","metric_title":"Manca de definicions","category":"lexical","summary":"Example detection returned by this metric.","explanation":null,"guidance":["Review the detected fragment in context."],"examples":null,"occurrences":[{"id":"occ_1","text":"example","paragraph_index":0,"sentence_index":0,"start":18,"end":25,"spans":[],"connectors":[],"replacement":null,"alternatives":[],"edits":[]}]}},{"id":"negative-formulations","kind":"rule","analysis_language":"ca","enabled":true,"genre_scope":null,"available":true,"availability_note":null,"implementation_version":"1.2","category":"morphosyntax","unit":null,"documentation_language":"ca","documentation":{"title":"Reformulació d'idees expressades en negatiu","summary":"Localitza paraules o seqüències negatives catalogades per afavorir formulacions afirmatives i directes.","methodology":"Normalitza els lemes dels tokens i cerca seqüències completes del catàleg actiu; retorna terme, alternativa i posicions de text quan estan disponibles. La detecció utilitza el catàleg editorial actiu per a l'idioma.","limitations":"Depèn de la cobertura i la qualitat del catàleg actiu per a l'idioma; cada coincidència requereix revisió contextual.","interpretation":"Cada element d'`occurrences` identifica un fragment afectat. `start` és inclusiu i `end` exclusiu, tots dos mesurats en punts de codi Unicode sobre el text enviat. `replacement`, `alternatives` i `edits` només contenen valors quan hi ha un canvi segur; l'absència del suggeriment significa que no hi ha coincidències, no que el text sigui necessàriament correcte."},"references":[],"example":{"id":"rec_1","metric_id":"negative-formulations","implementation_version":"1.2","metric_title":"Reformulació d'idees expressades en negatiu","category":"morphosyntax","summary":"Example detection returned by this metric.","explanation":null,"guidance":["Review the detected fragment in context."],"examples":null,"occurrences":[{"id":"occ_1","text":"example","paragraph_index":0,"sentence_index":0,"start":18,"end":25,"spans":[],"connectors":[],"replacement":null,"alternatives":[],"edits":[]}]}},{"id":"paragraph-initial-connectors","kind":"rule","analysis_language":"ca","enabled":true,"genre_scope":null,"available":true,"availability_note":null,"implementation_version":"1.2","category":"discourse","unit":null,"documentation_language":"ca","documentation":{"title":"Introducció de connectors a l'inici de paràgrafs","summary":"Detecta paràgrafs que no comencen amb un connector discursiu reconegut.","methodology":"Descarta paràgrafs buits o amb has_initial_connector; per a la resta retorna el paràgraf i els grups de connectors editables. La detecció utilitza el catàleg editorial actiu per a l'idioma.","limitations":"Depèn de la cobertura i la qualitat del catàleg actiu per a l'idioma; cada coincidència requereix revisió contextual.","interpretation":"Cada element d'`occurrences` identifica un fragment afectat. `start` és inclusiu i `end` exclusiu, tots dos mesurats en punts de codi Unicode sobre el text enviat. `replacement`, `alternatives` i `edits` només contenen valors quan hi ha un canvi segur; l'absència del suggeriment significa que no hi ha coincidències, no que el text sigui necessàriament correcte."},"references":[],"example":{"id":"rec_1","metric_id":"paragraph-initial-connectors","implementation_version":"1.2","metric_title":"Introducció de connectors a l'inici de paràgrafs","category":"discourse","summary":"Example detection returned by this metric.","explanation":null,"guidance":["Review the detected fragment in context."],"examples":null,"occurrences":[{"id":"occ_1","text":"example","paragraph_index":0,"sentence_index":0,"start":18,"end":25,"spans":[],"connectors":[],"replacement":null,"alternatives":[],"edits":[]}]}},{"id":"participles","kind":"rule","analysis_language":"ca","enabled":true,"genre_scope":null,"available":true,"availability_note":null,"implementation_version":"1.2","category":"morphosyntax","unit":null,"documentation_language":"ca","documentation":{"title":"Revisió de participis","summary":"Localitza participis independents i evita els que formen temps compostos o passives reconegudes.","methodology":"Usa etiquetes de participi (VBN en EN) i exclou auxiliars, temps compostos, passives i lemes auxiliars.","limitations":"Depèn de l'etiquetatge de FreeLing/DiSeg i pot produir falsos positius o perdre construccions ambigües.","interpretation":"Cada element d'`occurrences` identifica un fragment afectat. `start` és inclusiu i `end` exclusiu, tots dos mesurats en punts de codi Unicode sobre el text enviat. `replacement`, `alternatives` i `edits` només contenen valors quan hi ha un canvi segur; l'absència del suggeriment significa que no hi ha coincidències, no que el text sigui necessàriament correcte."},"references":[],"example":{"id":"rec_1","metric_id":"participles","implementation_version":"1.2","metric_title":"Revisió de participis","category":"morphosyntax","summary":"Example detection returned by this metric.","explanation":null,"guidance":["Review the detected fragment in context."],"examples":null,"occurrences":[{"id":"occ_1","text":"example","paragraph_index":0,"sentence_index":0,"start":18,"end":25,"spans":[],"connectors":[],"replacement":null,"alternatives":[],"edits":[]}]}},{"id":"passive-voice","kind":"rule","analysis_language":"ca","enabled":true,"genre_scope":null,"available":true,"availability_note":null,"implementation_version":"1.2","category":"morphosyntax","unit":null,"documentation_language":"ca","documentation":{"title":"Ús de la veu passiva","summary":"Localitza construccions que l'anàlisi morfosintàctica identifica com a possibles veus passives.","methodology":"En ES/CA usa nodes verb_pass o ger_pas i, com a suport, seqüències ser/ésser + participi. En EN cerca be + VBN a vb_chunk i després als tokens.","limitations":"Depèn de l'etiquetatge de FreeLing/DiSeg i pot produir falsos positius o perdre construccions ambigües.","interpretation":"Cada element d'`occurrences` identifica un fragment afectat. `start` és inclusiu i `end` exclusiu, tots dos mesurats en punts de codi Unicode sobre el text enviat. `replacement`, `alternatives` i `edits` només contenen valors quan hi ha un canvi segur; l'absència del suggeriment significa que no hi ha coincidències, no que el text sigui necessàriament correcte."},"references":[],"example":{"id":"rec_1","metric_id":"passive-voice","implementation_version":"1.2","metric_title":"Ús de la veu passiva","category":"morphosyntax","summary":"Example detection returned by this metric.","explanation":null,"guidance":["Review the detected fragment in context."],"examples":null,"occurrences":[{"id":"occ_1","text":"example","paragraph_index":0,"sentence_index":0,"start":18,"end":25,"spans":[],"connectors":[],"replacement":null,"alternatives":[],"edits":[]}]}},{"id":"redundant-expressions","kind":"rule","analysis_language":"ca","enabled":true,"genre_scope":null,"available":true,"availability_note":null,"implementation_version":"1.2","category":"lexical","unit":null,"documentation_language":"ca","documentation":{"title":"Eliminació d'expressions redundants","summary":"Localitza expressions redundants del catàleg per eliminar-les o reformular-les.","methodology":"Cerca expressions completes directament sobre el text, sense distingir majúscules ni accents i respectant límits de paraula. La detecció utilitza el catàleg editorial actiu per a l'idioma.","limitations":"Depèn de la cobertura i la qualitat del catàleg actiu per a l'idioma; cada coincidència requereix revisió contextual.","interpretation":"Cada element d'`occurrences` identifica un fragment afectat. `start` és inclusiu i `end` exclusiu, tots dos mesurats en punts de codi Unicode sobre el text enviat. `replacement`, `alternatives` i `edits` només contenen valors quan hi ha un canvi segur; l'absència del suggeriment significa que no hi ha coincidències, no que el text sigui necessàriament correcte."},"references":[],"example":{"id":"rec_1","metric_id":"redundant-expressions","implementation_version":"1.2","metric_title":"Eliminació d'expressions redundants","category":"lexical","summary":"Example detection returned by this metric.","explanation":null,"guidance":["Review the detected fragment in context."],"examples":null,"occurrences":[{"id":"occ_1","text":"example","paragraph_index":0,"sentence_index":0,"start":18,"end":25,"spans":[],"connectors":[],"replacement":null,"alternatives":[],"edits":[]}]}},{"id":"single-sentence-paragraphs","kind":"rule","analysis_language":"ca","enabled":true,"genre_scope":null,"available":true,"availability_note":null,"implementation_version":"1.2","category":"discourse","unit":null,"documentation_language":"ca","documentation":{"title":"Revisió de paràgrafs-oració","summary":"Localitza paràgrafs formats per una sola oració per revisar si concentren massa informació o necessiten desenvolupament.","methodology":"Selecciona cada paràgraf que contingui exactament una oració tancada i arribi al mínim de paraules del gènere; els fragments sense puntuació final (línies de capçalera) no compten com a oració.","limitations":"Depèn de la segmentació del text pla i que els marcadors estructurals siguin recognoscibles; no implica per si sola un error de redacció.","interpretation":"Cada element d'`occurrences` identifica un fragment afectat. `start` és inclusiu i `end` exclusiu, tots dos mesurats en punts de codi Unicode sobre el text enviat. `replacement`, `alternatives` i `edits` només contenen valors quan hi ha un canvi segur; l'absència del suggeriment significa que no hi ha coincidències, no que el text sigui necessàriament correcte."},"references":[],"example":{"id":"rec_1","metric_id":"single-sentence-paragraphs","implementation_version":"1.2","metric_title":"Revisió de paràgrafs-oració","category":"discourse","summary":"Example detection returned by this metric.","explanation":null,"guidance":["Review the detected fragment in context."],"examples":null,"occurrences":[{"id":"occ_1","text":"example","paragraph_index":0,"sentence_index":0,"start":18,"end":25,"spans":[],"connectors":[],"replacement":null,"alternatives":[],"edits":[]}]}},{"id":"subjectivity-markers","kind":"rule","analysis_language":"ca","enabled":true,"genre_scope":null,"available":true,"availability_note":null,"implementation_version":"1.2","category":"lexical","unit":null,"documentation_language":"ca","documentation":{"title":"Ús d'indicadors de subjectivitat","summary":"Combina lèxic, seqüències, categories morfològiques i exclamacions per localitzar possibles marques de subjectivitat.","methodology":"Uneix coincidències de lemes simples, seqüències compostes, categories morfològiques configurades i fragments entre signes d'exclamació; després elimina duplicats.","limitations":"Depèn de la cobertura i la qualitat del catàleg actiu per a l'idioma; cada coincidència requereix revisió contextual.","interpretation":"Cada element d'`occurrences` identifica un fragment afectat. `start` és inclusiu i `end` exclusiu, tots dos mesurats en punts de codi Unicode sobre el text enviat. `replacement`, `alternatives` i `edits` només contenen valors quan hi ha un canvi segur; l'absència del suggeriment significa que no hi ha coincidències, no que el text sigui necessàriament correcte."},"references":[],"example":{"id":"rec_1","metric_id":"subjectivity-markers","implementation_version":"1.2","metric_title":"Ús d'indicadors de subjectivitat","category":"lexical","summary":"Example detection returned by this metric.","explanation":null,"guidance":["Review the detected fragment in context."],"examples":null,"occurrences":[{"id":"occ_1","text":"example","paragraph_index":0,"sentence_index":0,"start":18,"end":25,"spans":[],"connectors":[],"replacement":null,"alternatives":[],"edits":[]}]}},{"id":"transparent-terms","kind":"rule","analysis_language":"ca","enabled":true,"genre_scope":null,"available":true,"availability_note":null,"implementation_version":"1.2","category":"lexical","unit":null,"documentation_language":"ca","documentation":{"title":"Utilització de termes més transparents","summary":"Detecta termes difícils catalogats i proposa denominacions més transparents.","methodology":"Normalitza els lemes dels tokens i cerca seqüències completes del catàleg actiu; retorna terme, alternativa i posicions de text quan estan disponibles. La detecció utilitza el catàleg editorial actiu per a l'idioma.","limitations":"Depèn de la cobertura i la qualitat del catàleg actiu per a l'idioma; cada coincidència requereix revisió contextual.","interpretation":"Cada element d'`occurrences` identifica un fragment afectat. `start` és inclusiu i `end` exclusiu, tots dos mesurats en punts de codi Unicode sobre el text enviat. `replacement`, `alternatives` i `edits` només contenen valors quan hi ha un canvi segur; l'absència del suggeriment significa que no hi ha coincidències, no que el text sigui necessàriament correcte."},"references":[],"example":{"id":"rec_1","metric_id":"transparent-terms","implementation_version":"1.2","metric_title":"Utilització de termes més transparents","category":"lexical","summary":"Example detection returned by this metric.","explanation":null,"guidance":["Review the detected fragment in context."],"examples":null,"occurrences":[{"id":"occ_1","text":"example","paragraph_index":0,"sentence_index":0,"start":18,"end":25,"spans":[],"connectors":[],"replacement":null,"alternatives":[],"edits":[]}]}},{"id":"verb-person-consistency","kind":"rule","analysis_language":"ca","enabled":true,"genre_scope":null,"available":true,"availability_note":null,"implementation_version":"1.2","category":"morphosyntax","unit":null,"documentation_language":"ca","documentation":{"title":"Sistematicitat en l'ús de verbs","summary":"Avisa quan conviuen verbs en primera persona singular i plural al mateix document.","methodology":"Extreu persona i nombre de les etiquetes verbals; només genera resultat si troba almenys una forma 1S i una 1P.","limitations":"Depèn de l'etiquetatge de FreeLing/DiSeg i pot produir falsos positius o perdre construccions ambigües.","interpretation":"Cada element d'`occurrences` identifica un fragment afectat. `start` és inclusiu i `end` exclusiu, tots dos mesurats en punts de codi Unicode sobre el text enviat. `replacement`, `alternatives` i `edits` només contenen valors quan hi ha un canvi segur; l'absència del suggeriment significa que no hi ha coincidències, no que el text sigui necessàriament correcte."},"references":[],"example":{"id":"rec_1","metric_id":"verb-person-consistency","implementation_version":"1.2","metric_title":"Sistematicitat en l'ús de verbs","category":"morphosyntax","summary":"Example detection returned by this metric.","explanation":null,"guidance":["Review the detected fragment in context."],"examples":null,"occurrences":[{"id":"occ_1","text":"example","paragraph_index":0,"sentence_index":0,"start":18,"end":25,"spans":[],"connectors":[],"replacement":null,"alternatives":[],"edits":[]}]}},{"id":"verbal-nominalizations","kind":"rule","analysis_language":"ca","enabled":true,"genre_scope":null,"available":true,"availability_note":null,"implementation_version":"1.2","category":"morphosyntax","unit":null,"documentation_language":"ca","documentation":{"title":"Revisió de nominalitzacions verbals","summary":"Detecta substantius amb patrons productius de nominalització verbal i exclou les excepcions catalogades.","methodology":"Filtra substantius en minúscula: -ción/-ciones en ES, -ció/-cions en CA i -tion/-tions en EN; elimina entrades del catàleg d'excepcions.","limitations":"Depèn de l'etiquetatge de FreeLing/DiSeg i pot produir falsos positius o perdre construccions ambigües.","interpretation":"Cada element d'`occurrences` identifica un fragment afectat. `start` és inclusiu i `end` exclusiu, tots dos mesurats en punts de codi Unicode sobre el text enviat. `replacement`, `alternatives` i `edits` només contenen valors quan hi ha un canvi segur; l'absència del suggeriment significa que no hi ha coincidències, no que el text sigui necessàriament correcte."},"references":[],"example":{"id":"rec_1","metric_id":"verbal-nominalizations","implementation_version":"1.2","metric_title":"Revisió de nominalitzacions verbals","category":"morphosyntax","summary":"Example detection returned by this metric.","explanation":null,"guidance":["Review the detected fragment in context."],"examples":null,"occurrences":[{"id":"occ_1","text":"example","paragraph_index":0,"sentence_index":0,"start":18,"end":25,"spans":[],"connectors":[],"replacement":null,"alternatives":[],"edits":[]}]}},{"id":"word-repetition","kind":"rule","analysis_language":"ca","enabled":true,"genre_scope":null,"available":true,"availability_note":null,"implementation_version":"1.2","category":"lexical","unit":null,"documentation_language":"ca","documentation":{"title":"Repetició de paraules","summary":"Assenyala les paraules amb contingut lèxic que es repeteixen al text per sobre del llindar configurat per al gènere.","methodology":"Compta quantes vegades apareix cada lema, descartant els lemes auxiliars i copulatius, i assenyala els lemes de nom, adjectiu, adverbi o verb amb una freqüència superior al llindar del gènere.","limitations":"És un senyal de revisió, no una correcció automàtica ni una avaluació completa de la qualitat del text.","interpretation":"Cada element d'`occurrences` identifica un fragment afectat. `start` és inclusiu i `end` exclusiu, tots dos mesurats en punts de codi Unicode sobre el text enviat. `replacement`, `alternatives` i `edits` només contenen valors quan hi ha un canvi segur; l'absència del suggeriment significa que no hi ha coincidències, no que el text sigui necessàriament correcte."},"references":[],"example":{"id":"rec_1","metric_id":"word-repetition","implementation_version":"1.2","metric_title":"Repetició de paraules","category":"lexical","summary":"Example detection returned by this metric.","explanation":null,"guidance":["Review the detected fragment in context."],"examples":null,"occurrences":[{"id":"occ_1","text":"example","paragraph_index":0,"sentence_index":0,"start":18,"end":25,"spans":[],"connectors":[],"replacement":null,"alternatives":[],"edits":[]}]}}],"x-artext-guides":{"language":"ca","examples":{"curl":"# Desa la clau fora del codi i carrega-la des de l’entorn.\n# Requereix curl i jq.\n# export ARTEXT_API_KEY='art_live_...'\nset -euo pipefail\nAPI_BASE='http://demo.sistema-artext.com'\nIDEMPOTENCY_KEY=\"report-$(date +%s)-$RANDOM\"\nheaders_file=$(mktemp)\ntrap 'rm -f \"$headers_file\"' EXIT\n\n# Crea l’informe una sola vegada. Idempotency-Key permet repetir el POST amb seguretat després d’un error de xarxa.\ncreated=$(curl --fail-with-body --silent --show-error --dump-header \"$headers_file\" \\\n  --request POST \"$API_BASE/v1/reports\" \\\n  --header \"Authorization: Bearer $ARTEXT_API_KEY\" \\\n  --header \"Idempotency-Key: $IDEMPOTENCY_KEY\" \\\n  --header 'Content-Type: application/json' \\\n  --data-binary '{\"language\":\"ca\",\"domain_slug\":\"llenguatge-clar\",\"text_type_slug\":\"text-juridic-administratiu-dirigit-a-la-ciutadania\",\"text\":\"En el dia d’avui es durà a terme la revisió de la sol·licitud.\",\"external_id\":\"document-123\"}')\n\n# status_url és relatiu: resol-lo contra API_BASE.\nstatus_url=\"$API_BASE$(jq -r '.status_url' <<<\"$created\")\"\nretry_after=$(awk 'BEGIN { IGNORECASE=1 } /^Retry-After:/ { gsub(\"\\r\", \"\", $2); print $2 }' \"$headers_file\" | tail -1)\nretry_after=${retry_after:-2}\n\n# Consulta el mateix informe respectant Retry-After i amb un límit total.\nfor attempt in $(seq 1 90); do\n  sleep \"$retry_after\"\n  report=$(curl --fail-with-body --silent --show-error --dump-header \"$headers_file\" \\\n    --header \"Authorization: Bearer $ARTEXT_API_KEY\" \\\n    \"$status_url\")\n  status=$(jq -r '.status' <<<\"$report\")\n  case \"$status\" in\n    completed) break ;;\n    failed) jq -r '.error.message // \"Analysis failed\"' <<<\"$report\" >&2; exit 1 ;;\n    queued|running)\n      retry_after=$(awk 'BEGIN { IGNORECASE=1 } /^Retry-After:/ { gsub(\"\\r\", \"\", $2); print $2 }' \"$headers_file\" | tail -1)\n      retry_after=${retry_after:-2}\n      ;;\n    *) echo \"Unknown status: $status\" >&2; exit 1 ;;\n  esac\ndone\n\n# Processa el resultat només després de completed.\ntest \"$status\" = completed || { echo 'Polling timed out' >&2; exit 1; }\njq '.result.measurements, .result.recommendations' <<<\"$report\"","python":"import os\nimport time\nimport uuid\nfrom urllib.parse import urljoin\n\nimport requests\n\n# Desa la clau fora del codi i carrega-la des de l’entorn.\nAPI_BASE = 'http://demo.sistema-artext.com'\nAPI_KEY = os.environ[\"ARTEXT_API_KEY\"]\nHEADERS = {\"Authorization\": f\"Bearer {API_KEY}\"}\npayload = {'language': 'ca', 'domain_slug': 'llenguatge-clar', 'text_type_slug': 'text-juridic-administratiu-dirigit-a-la-ciutadania', 'text': 'En el dia d’avui es durà a terme la revisió de la sol·licitud.', 'external_id': 'document-123'}\n\n# Crea l’informe una sola vegada. Idempotency-Key permet repetir el POST amb seguretat després d’un error de xarxa.\nresponse = requests.post(\n    f\"{API_BASE}/v1/reports\",\n    headers={**HEADERS, \"Idempotency-Key\": str(uuid.uuid4())},\n    json=payload,\n    timeout=30,\n)\nresponse.raise_for_status()\ncreated = response.json()\n# status_url és relatiu: resol-lo contra API_BASE.\nstatus_url = urljoin(f\"{API_BASE}/\", created[\"status_url\"])\nretry_after = int(response.headers.get(\"Retry-After\", \"2\"))\n\n# Consulta el mateix informe respectant Retry-After i amb un límit total.\ndeadline = time.monotonic() + 180\nwhile True:\n    time.sleep(retry_after)\n    response = requests.get(status_url, headers=HEADERS, timeout=30)\n    retry_after = int(response.headers.get(\"Retry-After\", \"2\"))\n    if response.status_code == 429:\n        continue\n    response.raise_for_status()\n    report = response.json()\n    status = report[\"status\"]\n    if status == \"completed\":\n        break\n    if status == \"failed\":\n        raise RuntimeError((report.get(\"error\") or {}).get(\"message\") or \"Analysis failed\")\n    if status not in {\"queued\", \"running\"}:\n        raise RuntimeError(f\"Unknown report status: {status}\")\n    if time.monotonic() >= deadline:\n        raise TimeoutError(\"Report polling timed out\")\n\n# Processa el resultat només després de completed.\nresult = report[\"result\"]\nfor measurement in result[\"measurements\"]:\n    print(measurement[\"metric_id\"], measurement[\"value\"], measurement[\"unit\"])\nfor index, recommendation in enumerate(result[\"recommendations\"]):\n    print(index, recommendation[\"metric_id\"], len(recommendation[\"occurrences\"]))","javascript":"// Node.js 18+. Executa aquest codi al servidor; no exposis mai la clau al navegador.\nconst API_BASE = \"http://demo.sistema-artext.com\";\nconst API_KEY = process.env.ARTEXT_API_KEY;\nif (!API_KEY) throw new Error(\"ARTEXT_API_KEY is required\");\n\nconst headers = {\n  \"Authorization\": `Bearer ${API_KEY}`,\n  \"Content-Type\": \"application/json\"\n};\nconst api = async (path, options = {}) => {\n  const response = await fetch(new URL(path, `${API_BASE}/`), {\n    ...options,\n    headers: { ...headers, ...options.headers },\n    signal: AbortSignal.timeout(30_000)\n  });\n  if (!response.ok && response.status !== 429) {\n    throw new Error(`${response.status}: ${await response.text()}`);\n  }\n  return response;\n};\nconst delay = (milliseconds) =>\n  new Promise((resolve) => setTimeout(resolve, milliseconds));\n\n// Crea l’informe una sola vegada. Idempotency-Key permet repetir el POST amb seguretat després d’un error de xarxa.\nconst createdResponse = await api(\"v1/reports\", {\n  method: \"POST\",\n  headers: { \"Idempotency-Key\": crypto.randomUUID() },\n  body: JSON.stringify({\"language\":\"ca\",\"domain_slug\":\"llenguatge-clar\",\"text_type_slug\":\"text-juridic-administratiu-dirigit-a-la-ciutadania\",\"text\":\"En el dia d’avui es durà a terme la revisió de la sol·licitud.\",\"external_id\":\"document-123\"})\n});\nconst created = await createdResponse.json();\nconst deadline = Date.now() + 180_000;\nlet retryAfter = Number(createdResponse.headers.get(\"Retry-After\") || 2);\nlet report;\n\n// Consulta el mateix informe respectant Retry-After i amb un límit total.\nwhile (Date.now() < deadline) {\n  await delay(retryAfter * 1_000);\n  const statusResponse = await api(created.status_url);\n  retryAfter = Number(statusResponse.headers.get(\"Retry-After\") || 2);\n  if (statusResponse.status === 429) continue;\n  report = await statusResponse.json();\n  if (report.status === \"completed\") break;\n  if (report.status === \"failed\") {\n    throw new Error(report.error?.message || \"Analysis failed\");\n  }\n  if (![\"queued\", \"running\"].includes(report.status)) {\n    throw new Error(`Unknown report status: ${report.status}`);\n  }\n}\nif (report?.status !== \"completed\") {\n  throw new Error(\"Report polling timed out\");\n}\n\n// Processa el resultat només després de completed.\nfor (const item of report.result.measurements) {\n  console.log(item.metric_id, item.value, item.unit);\n}\nfor (const [index, item] of report.result.recommendations.entries()) {\n  console.log(index, item.metric_id, item.occurrences.length);\n}"},"sdk":{"python":"# Instal·la el client oficial: pip install artext\n# Executa aquest codi al servidor; no exposis mai la clau al navegador.\nimport os\n\nfrom artext import Artext\n\nclient = Artext(\n    api_key=os.environ[\"ARTEXT_API_KEY\"],\n    base_url=\"http://demo.sistema-artext.com\",\n)\n\n# analyze crea l'informe, espera respectant Retry-After i retorna el resultat.\n# Una anàlisi fallida llança una excepció amb el detall de l'error.\nreport = client.analyze(\n    \"En el dia d’avui es durà a terme la revisió de la sol·licitud.\",\n    language=\"ca\",\n    domain_slug=\"llenguatge-clar\",\n    text_type_slug=\"text-juridic-administratiu-dirigit-a-la-ciutadania\",\n)\n\nprint(report.result.measurement(\"word-count\").value)\nfor recommendation in report.result.recommendations:\n    print(recommendation.metric_id, recommendation.summary)\n    for occurrence in recommendation.occurrences:\n        print(\"  \", occurrence.text, \"->\", occurrence.replacement)\n","javascript":"// Instal·la el client oficial: npm install artext\n// Executa aquest codi al servidor; no exposis mai la clau al navegador.\nimport { Artext } from \"artext\";\n\nconst client = new Artext({\n  apiKey: process.env.ARTEXT_API_KEY,\n  baseUrl: \"http://demo.sistema-artext.com\",\n});\n\n// analyze crea l'informe, espera respectant Retry-After i retorna el resultat.\n// Una anàlisi fallida llança una excepció amb el detall de l'error.\nconst report = await client.analyze({\n  text: \"En el dia d’avui es durà a terme la revisió de la sol·licitud.\",\n  language: \"ca\",\n  domainSlug: \"llenguatge-clar\",\n  textTypeSlug: \"text-juridic-administratiu-dirigit-a-la-ciutadania\",\n});\n\nfor (const recommendation of report.result.recommendations) {\n  console.log(recommendation.metric_id, recommendation.summary);\n  for (const occurrence of recommendation.occurrences) {\n    console.log(\"  \", occurrence.text, \"->\", occurrence.replacement);\n  }\n}\n"},"request":{"language":"ca","domain_slug":"llenguatge-clar","text_type_slug":"text-juridic-administratiu-dirigit-a-la-ciutadania","text":"En el dia d’avui es durà a terme la revisió de la sol·licitud.","external_id":"document-123"},"responses":{"queued":{"report_id":"rep_7f12a4c8","external_id":"document-123","status":"queued","status_url":"/v1/reports/rep_7f12a4c8","events_url":"/v1/reports/rep_7f12a4c8/events"},"completed":{"report_id":"rep_7f12a4c8","external_id":"document-123","status":"completed","position_in_queue":null,"result":{"schema_version":"2.0","offset_unit":"unicode_code_points","language":"ca","genre":{"domain":{"slug":"llenguatge-clar","name":"Llenguatge clar"},"text_type":{"slug":"text-juridic-administratiu-dirigit-a-la-ciutadania","name":"Text juridicoadministratiu"}},"measurements":[{"metric_id":"word-count","value":12,"unit":"words","implementation_version":"1.0"}],"recommendations":[{"id":"rec_1","metric_id":"redundant-expressions","implementation_version":"1.0","metric_title":"Eliminació d’expressions redundants","category":"lexical","summary":"Convé formular el fragment d’una manera més directa.","explanation":null,"occurrences":[{"id":"occ_1","text":"En el dia d’avui","paragraph_index":0,"sentence_index":0,"start":0,"end":16,"replacement":null,"alternatives":[],"edits":[{"start":0,"end":16,"text":""}]}],"guidance":["Elimina l’expressió si el context ho permet."]}]},"error":null},"failed":{"report_id":"rep_7f12a4c8","external_id":"document-123","status":"failed","position_in_queue":null,"result":null,"error":{"code":"analysis_failed","message":"The analysis could not be completed."}}}}}