Medical text formatter


Formats text aligned to medical standards. The model will receive a raw text and will return the formatted text following medical conventions.

Below we will describe the entire process that allows the successful completion of text formatting.

Request description

Endpoint: /api/v1/medical-text-formatter
Method: POST

{
  "Content-Type": "application/json",
  "Authorization": "Bearer <accessToken>"
}

Authorization: We'll pass the token obtained during the authentication process. You can reuse the generated tokens, as they have a 2-hour lifespan. Review this page: Credentials

To set the API version on a specific request, you can add a specific header named X-Invox-Medical-Api-Version with the value of the version you are targeting:

X-Invox-Medical-Api-Version: 2026-10-01

This endpoint accepts the versions 2026-03-01, 2026-08-01 and 2026-10-01. If the header is omitted, the latest version (2026-10-01) is used.

Requests sent without the X-Invox-Medical-Api-Version header resolve to the latest version (2026-10-01), which uses a different contract. Send the header with the version you are targeting to keep the contract described on this page.

Payload structure

type IMedicalTextFormatterRequest = {
  text: string; // Raw text to be formatted according to medical standards
  language?: string; // Language of the input text. Supported values: "es", "en", "pt", "pt-PT", "pt-BR", and "ca". If omitted, language will be automatically detected from the content.
  preserve_case?: boolean; // Whether to preserve the original case of the text. Default is false.
};
type IMedicalTextFormatterRequest = {
  text: string; // Raw text (plain text or Markdown) to be formatted according to medical standards. Required, between 1 and 50000 characters.
  formatting_level?: "low" | "medium" | "high"; // Degree of intervention applied to the text. Default is "medium".
  immutable_words?: string[]; // Words or expressions that must be kept literally (same case and accents) in the formatted text. Default is [].
};

Field rules

FieldRequiredDefaultRules
textYes—String between 1 and 50000 characters. Leading and trailing whitespace is not counted. Plain text and Markdown are supported.
formatting_levelNo"medium"One of "low", "medium" or "high".
immutable_wordsNo[]Array of strings. Entries are trimmed, empty entries are discarded and duplicates are removed.

Formatting levels

The formatting_level field sets the maximum degree of intervention the service is allowed to apply:

LevelTransformation
lowDeterministic cleanup, without AI: removes audio fillers (for example "eh", "um"), normalizes punctuation and spacing, fixes unambiguous gender/number agreement and capitalizes the beginning of sentences. The output is reproducible.
mediumAI-assisted reorganization of sentences and paragraphs for a more readable narrative, without replacing content words. The Markdown elements present in the input are kept.
highAI-assisted style editing. It can restructure the text to improve readability and apply limited corrections of speech-recognition errors, without changing figures, measurements, negations, laterality, certainty or temporality.
The requested level is a maximum, not a guarantee. Every request applies low first. If the medium or high result does not pass the service quality checks, the response contains the low result instead. The response is still 200 and does not indicate which level was applied.

Immutable words

The immutable_words field protects words or expressions (for example proper nouns, drug names or acronyms) so that they appear in the output exactly as written in the input:

  • Matching is literal and exact: same case and same accents. "ECG" does not protect "ecg", and "toracico" does not protect "torácico".
  • It only preserves occurrences already present in text. A word that is not in the input is never added to the output.
  • Multi-word expressions are supported and are matched literally, including their inner spacing.
  • Every occurrence is protected, so a word repeated several times is preserved in each appearance.
  • When two entries overlap, the longest match wins. On a tie, the entry that appears first in the list wins.

Language detection

The language of text is always detected automatically. Supported languages are Spanish, Catalan, English, European Portuguese and Brazilian Portuguese. If the language cannot be determined or is not supported, the service returns 200 with the original text unchanged in formatted_text.

The language and preserve_case fields are ignored if they are sent. Use immutable_words to keep specific words exactly as written. Any other unknown field is also ignored.

Responses

Correct response

Successful request

Describe the characteristics of a satisfactory response

200

Input example:

{
  "text": "presión arterial 120/80, 38 grados de temperatura y se aprecia enrojecimiento en la parte trasera del brazo",
  "language": "es",
  "preserve_case": false
}
{
  "text": "presión arterial 120/80, 38 grados de temperatura y se aprecia enrojecimiento en la parte trasera del brazo",
  "formatting_level": "medium",
  "immutable_words": ["enrojecimiento"]
}
Response example:
{
  "formatted_text": "Presión arterial 120/80, 38°C de temperatura y se aprecia enrojecimiento en la parte trasera del brazo.",
  "message": null,
  "request_id": "7ed08fbf-1fa0-4d95-a88c-d0d52320bf64"
}
{
  "formatted_text": "Presión arterial 120/80, 38°C de temperatura y se aprecia enrojecimiento en la parte trasera del brazo.",
  "request_id": "7ed08fbf-1fa0-4d95-a88c-d0d52320bf64",
  "timestamp": "2026-10-01T12:00:00.000Z"
}
Response structure
interface IMedicalTextFormatterResponse {
  formatted_text: string; // The input text formatted according to medical standards
  message: string | null; // Additional message or information about the formatting process, if applicable
  request_id: string; // Unique identifier for the request, useful for tracking and debugging purposes
}
interface IMedicalTextFormatterResponse {
  formatted_text: string; // The input text formatted according to medical standards
  request_id: string; // Unique identifier for the request, useful for tracking and debugging purposes
  timestamp: string; // Date of the response in ISO 8601 format, UTC ("Z" suffix)
}

Wrong responses

All error responses share the same structure:

type TextFormatterErrorResponseType = {
  message: string;
  errorType?: string;
};

Bad request

Describes the response when the request is not valid

400

errorTypeCause
invalidRequestBodyThe body is not an object, text is missing, is not a string or is out of range, or any field has an invalid type or value.
invalidApiVersionForEndpointThe X-Invox-Medical-Api-Version header targets a version that does not implement this endpoint.
Response example
{
  "message": "Invalid request body",
  "errorType": "invalidRequestBody"
}


Unauthorized request

Describes the response when the request is not authorized

401

Response example

{
  "message": "Unauthorized"
}


Forbidden request

Describes the response when the API Key is not allowed to consume this service

403

Response example

{
  "message": "The credential does not have permission to perform this operation",
  "errorType": "invalidPermission"
}

Remember that to consume this service, the API Key must have the permission: MEDICAL-TEXT-FORMATTER

Internal error

Describes the response when the text could not be formatted

500

errorTypeCause
inconsistentInputThe request body is not a properly formatted JSON.
errorGeneratingMedicalReportAn unexpected error occurred while formatting the text. Retry later.
Response example
{
  "message": "Error generating medical report. Please try again",
  "errorType": "errorGeneratingMedicalReport"
}


Service temporarily unavailable

Describes the response when the formatting service is temporarily unavailable

503

Response example

{
  "message": "Text formatter service is temporarily unavailable. Please try again",
  "errorType": "serviceTemporarilyUnavailable"
}

Unauthorized request

Describes the response when the request is not authorized


401

Response body

type GenericTextFormatterResponseType = {
  message: string;
};


Forbidden request

Describes the response when the API Key is not allowed to consume this service


403

Response body

type GenericTextFormatterResponseType = {
  message: string;
};

Remember that to consume this service, the API Key must have the permission: MEDICAL-TEXT-FORMATTER

Validation error

Describe the features of a validation error

422

Response body

type TextFormatterResponseType = {
  statusCode: number;
  message: string;
  error: string;
  details: {
    errorCode: string;
    message: string;
    requestId: string;
    timestamp: string;
  };
};