{
  "openapi": "3.1.0",
  "info": {
    "title": "TranslaQE API",
    "version": "1.0.0",
    "description": "Machine translation that adapts to your translation memories and glossaries, with a quality score for every sentence (MTQE).\n\nSend an API key in every request: `Authorization: Bearer tq_live_…`. Errors come as `application/problem+json` (RFC 9457). Every response carries `X-Request-Id` and the `RateLimit-*` headers. Guides: https://developer.translaqe.com"
  },
  "servers": [
    {
      "url": "https://api.translaqe.com"
    }
  ],
  "externalDocs": {
    "description": "Guides",
    "url": "https://developer.translaqe.com"
  },
  "tags": [
    {
      "name": "Translation",
      "description": "Translate sentences and get a quality score for each one."
    },
    {
      "name": "Quality estimation",
      "description": "Score translations you already have, whoever made them."
    },
    {
      "name": "Languages",
      "description": "The languages you can translate from and into."
    },
    {
      "name": "Documents",
      "description": "Translate whole files in the background: upload, follow the job, review its sentences and download the translated file."
    },
    {
      "name": "Translation memories",
      "description": "Sentence pairs you have already translated. A sentence found in a memory is not sent to the engine, and close matches guide it."
    },
    {
      "name": "Glossaries",
      "description": "Terms that must always be translated the same way."
    },
    {
      "name": "Projects",
      "description": "A project groups the memories and the glossaries of one client or one kind of content, so you can translate with all of them by naming the project."
    },
    {
      "name": "Account",
      "description": "Your plan and what is left of it, your usage and the log of your requests."
    }
  ],
  "paths": {
    "/v1/languages": {
      "get": {
        "operationId": "listLanguages",
        "tags": [
          "Languages"
        ],
        "summary": "List languages",
        "description": "The language catalogue, in display order. Any language can be the source or the target. `qe: true` means its quality scores are validated; sentences in the other languages are translated too, but come back with the band `sin-nota` (no score). No API key is needed.",
        "security": [],
        "parameters": [
          {
            "name": "after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 16
            },
            "description": "Cursor: the `next_after` of the previous page. Leave it out for the first page."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 500,
              "minimum": 1,
              "default": 100
            },
            "description": "How many to return per page."
          }
        ],
        "responses": {
          "200": {
            "description": "A page of the catalogue.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LanguagesResponse"
                },
                "example": {
                  "languages": [
                    {
                      "code": "es",
                      "name": "Español",
                      "qe": true
                    },
                    {
                      "code": "en",
                      "name": "English",
                      "qe": true
                    }
                  ],
                  "next_after": null
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/translate": {
      "post": {
        "operationId": "translate",
        "tags": [
          "Translation"
        ],
        "summary": "Translate sentences",
        "description": "Translates up to 50 segments (10,000 characters in total, 2,000 each) and answers in the same request. A segment is one sentence. Send it as a string to translate it, or as `{source, target}` to post-edit a translation you already have: what is wrong is fixed and the rest is left alone.\n\nEvery segment comes back with its translation, a quality score from 0 to 100, a band (`fiable`, `revisar`, `rehacer` or `sin-nota`), the glossary terms that were applied and the checks it did not pass. To adapt the translation, name saved memories and glossaries (`memory_ids`, `glossary_ids`), a project (`project_id`), send terms inline (`glossary`) or style instructions (`instructions`).\n\nIt is all or nothing: if no model gives a valid translation for some segment, the answer is `422`. The source characters count against your plan. For longer texts and for files, use `POST /v1/jobs`.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TranslateRequest"
              },
              "example": {
                "source_lang": "es",
                "target_lang": "en",
                "segments": [
                  "El contrato entra en vigor el 1 de marzo.",
                  "Las partes podrán rescindirlo con un preaviso de 30 días."
                ],
                "glossary_ids": [
                  "gl_3f9a1c2b7d5e4f60a1b2c3d4e5f60718"
                ],
                "instructions": "British English. Formal register."
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The segments, translated and scored, in the order they were sent.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TranslateResponse"
                },
                "example": {
                  "source_lang": "es",
                  "target_lang": "en",
                  "model_version": "adapt-1",
                  "qe_version": "score-1",
                  "segments": [
                    {
                      "index": 0,
                      "source": "El contrato entra en vigor el 1 de marzo.",
                      "target": "The agreement enters into force on 1 March.",
                      "origin": "engine",
                      "score": 93,
                      "band": "fiable",
                      "applied_terms": [
                        {
                          "source": "contrato",
                          "target": "agreement"
                        }
                      ],
                      "checks": [],
                      "status": "translated",
                      "changed": null,
                      "explanation": null
                    },
                    {
                      "index": 1,
                      "source": "Las partes podrán rescindirlo con un preaviso de 30 días.",
                      "target": "The parties may terminate it with 30 days' notice.",
                      "origin": "engine",
                      "score": 71,
                      "band": "revisar",
                      "applied_terms": [],
                      "checks": [],
                      "status": "translated",
                      "changed": null,
                      "explanation": null
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not allow it: the free trial is over (`trial-ended`) or it has fewer characters left than the request needs (`quota-exceeded`). See `GET /v1/plan`.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "No model gave a valid translation for some segment (`translation-failed`). `errors` lists them. Sending the same request again gives the same result: remove or change those segments.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "502": {
            "description": "The engine answered something that does not match the request (`engine-mismatch`). Try again.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/qe": {
      "post": {
        "operationId": "estimateQuality",
        "tags": [
          "Quality estimation"
        ],
        "summary": "Score existing translations",
        "description": "Machine translation quality estimation (MTQE): scores up to 100 translations made by any engine or by people, without a reference translation. Each one gets a score from 0 to 100, a band and the checks it did not pass. Scoring does not use up characters of your plan.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QeRequest"
              },
              "example": {
                "source_lang": "es",
                "target_lang": "en",
                "items": [
                  {
                    "source": "Se aplicará la tarifa vigente en el momento del pedido.",
                    "target": "It will apply the tariff in force in the moment of the order."
                  }
                ]
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "The score of each item, in the order they were sent.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QeResponse"
                },
                "example": {
                  "qe_version": "score-1",
                  "items": [
                    {
                      "index": 0,
                      "score": 42,
                      "band": "rehacer",
                      "checks": []
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not allow it: the free trial is over (`trial-ended`) or it has fewer characters left than the request needs (`quota-exceeded`). See `GET /v1/plan`.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "502": {
            "description": "The engine answered something that does not match the request (`engine-mismatch`). Try again.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/jobs": {
      "post": {
        "operationId": "createDocument",
        "tags": [
          "Documents"
        ],
        "summary": "Translate a document",
        "description": "Uploads a file and queues its translation. The answer is the job (`202`): follow it with `GET /v1/jobs/{job_id}` until its `status` is `succeeded`, and download the translated file from `GET /v1/jobs/{job_id}/file`. The file keeps its format and its layout.\n\nWith the `Idempotency-Key` header, sending the request again returns the same job (`200`) instead of creating another. If no model can translate some sentence, the job ends `failed` with the code `partial` and without a file; with `allow_partial`, the file is delivered with those sentences in the source language. With `webhook_url`, a `POST` is sent there when the job ends, well or badly.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "A value of your own that identifies this upload. Repeating the request with the same value returns the job it created the first time."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file",
                  "source_lang",
                  "target_lang"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "The document. Office (DOCX, XLSX, PPTX and their macro-enabled and template variants), OpenDocument (ODT, ODS, ODP, ODG and their templates), HTML, XHTML, TXT, Markdown, JSON, YAML, PO or Java properties. Up to 50 MB."
                  },
                  "source_lang": {
                    "type": "string",
                    "example": "es",
                    "description": "The language the document is written in (BCP 47: `es`, `en`, `pt-BR`…)."
                  },
                  "target_lang": {
                    "type": "string",
                    "example": "en",
                    "description": "The language to translate it into. Not the same as `source_lang`."
                  },
                  "notify_email": {
                    "type": "string",
                    "description": "An address to email when the job ends."
                  },
                  "webhook_url": {
                    "type": "string",
                    "description": "An HTTPS address to `POST` to when the job ends, well or badly, with its id and status."
                  },
                  "memory_ids": {
                    "type": "string",
                    "description": "Translation memories to use (`tm_…`), separated by commas. Up to 20."
                  },
                  "glossary_ids": {
                    "type": "string",
                    "description": "Glossaries to use (`gl_…`), separated by commas. Up to 20."
                  },
                  "project_id": {
                    "type": "string",
                    "description": "A project (`prj_…`): its memories and glossaries for this language pair are used too, and the job is listed under it."
                  },
                  "allow_partial": {
                    "type": "boolean",
                    "default": false,
                    "description": "Deliver the file even if some sentence cannot be translated: it goes in the source language."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The job already existed: same `Idempotency-Key`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "202": {
            "description": "The job, queued.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                },
                "example": {
                  "id": "job_8c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f",
                  "kind": "translate_document",
                  "status": "queued",
                  "file_name": "contract.docx",
                  "source_lang": "es",
                  "target_lang": "en",
                  "allow_partial": false,
                  "stage": null,
                  "progress": {
                    "done": 0,
                    "total": null
                  },
                  "counts": null,
                  "result": null,
                  "error": null,
                  "error_code": null,
                  "attempts": 0,
                  "created_at": "2026-10-12T09:30:00+00:00",
                  "started_at": null,
                  "finished_at": null,
                  "project_id": null
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "402": {
            "description": "The plan does not allow it: the free trial is over (`trial-ended`) or it has fewer characters left than the request needs (`quota-exceeded`). See `GET /v1/plan`.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "413": {
            "description": "The file is larger than the maximum (`document-rejected`): 50 MB.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listDocuments",
        "tags": [
          "Documents"
        ],
        "summary": "List documents",
        "description": "The document translation jobs of your organisation, newest first, each with its status, its progress and the counts of its sentences.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "queued",
                "running",
                "retrying",
                "succeeded",
                "failed",
                "cancelled"
              ],
              "type": "string"
            },
            "description": "Only the jobs in this status."
          },
          {
            "name": "project_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 128
            },
            "description": "Only the jobs of this project (`prj_…`)."
          },
          {
            "name": "after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 128
            },
            "description": "Cursor: the `next_after` of the previous page. Leave it out for the first page."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 200,
              "minimum": 1,
              "default": 50
            },
            "description": "How many to return per page."
          }
        ],
        "responses": {
          "200": {
            "description": "A page of jobs.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Jobs"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/jobs/{job_id}": {
      "get": {
        "operationId": "getDocument",
        "tags": [
          "Documents"
        ],
        "summary": "Get a document",
        "description": "The job: its status, the stage it is in, its progress and, when it ends, its result or its error. Poll it every few seconds, or give `webhook_url` when you create it. The jobs that index a memory or a glossary are read here too.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The id of the job (`job_…`)."
          }
        ],
        "responses": {
          "200": {
            "description": "The job.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                },
                "example": {
                  "id": "job_8c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f",
                  "kind": "translate_document",
                  "status": "succeeded",
                  "file_name": "contract.docx",
                  "source_lang": "es",
                  "target_lang": "en",
                  "allow_partial": false,
                  "stage": null,
                  "progress": {
                    "done": 184,
                    "total": 184
                  },
                  "counts": {
                    "segments": 184,
                    "translated": 151,
                    "from_memory": 27,
                    "untranslatable": 6,
                    "edited": 0,
                    "failed": 0,
                    "pending": 0,
                    "characters": 21840,
                    "words": 3512
                  },
                  "result": {
                    "file_id": "f_2b7c9d1e",
                    "segments": 184,
                    "scored": true,
                    "average_score": 88.4,
                    "low_score_segments": 9,
                    "failed_segments": 0,
                    "mark_warnings": 0
                  },
                  "error": null,
                  "error_code": null,
                  "attempts": 1,
                  "created_at": "2026-10-12T09:30:00+00:00",
                  "started_at": "2026-10-12T09:30:02+00:00",
                  "finished_at": "2026-10-12T09:31:47+00:00",
                  "project_id": null
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "There is no job with that id (`job-not-found`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteDocument",
        "tags": [
          "Documents"
        ],
        "summary": "Delete a document",
        "description": "Deletes the job with everything it holds: its sentences, the original file and the translated one. It cannot be undone. The usage already recorded does not change.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The id of the job (`job_…`)."
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted."
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "There is no job with that id (`job-not-found`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "409": {
            "description": "The job is queued or running: cancel it first (`job-busy`). Just after cancelling, it may take a few seconds before it can be deleted.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/jobs/{job_id}/cancel": {
      "post": {
        "operationId": "cancelDocument",
        "tags": [
          "Documents"
        ],
        "summary": "Cancel a document",
        "description": "A queued job leaves the queue. A running job stops between batches of sentences; what was already translated has been counted.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The id of the job (`job_…`)."
          }
        ],
        "responses": {
          "200": {
            "description": "The job, cancelled or about to be.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "There is no job with that id (`job-not-found`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/jobs/{job_id}/file": {
      "get": {
        "operationId": "downloadDocument",
        "tags": [
          "Documents"
        ],
        "summary": "Download the translated document",
        "description": "The translated file, in the format of the original. Its name comes in the `Content-Disposition` header.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The id of the job (`job_…`)."
          }
        ],
        "responses": {
          "200": {
            "description": "The translated file.",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "There is no job with that id (`job-not-found`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "409": {
            "description": "The job has not produced a file: it is not finished, or it failed (`job-not-ready`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/jobs/{job_id}/segments": {
      "get": {
        "operationId": "listDocumentSegments",
        "tags": [
          "Documents"
        ],
        "summary": "List the sentences of a document",
        "description": "The sentences of the document in order, each with its source, its translation, its state and its score. They are available as soon as the document has been read, also while the job is running or if it failed. Filter by `state` or by `band` to go straight to what needs review.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The id of the job (`job_…`)."
          },
          {
            "name": "state",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "not_translated",
                "draft",
                "translated",
                "rejected_translation",
                "approved_translation",
                "rejected_sign_off",
                "approved_sign_off"
              ],
              "type": "string"
            },
            "description": "Only the sentences in this state."
          },
          {
            "name": "band",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "fiable",
                "revisar",
                "rehacer",
                "sin-nota"
              ],
              "type": "string"
            },
            "description": "Only the sentences in this quality band."
          },
          {
            "name": "after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": -1
            },
            "description": "The position of the last sentence you already have: the `next_after` of the previous page."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 500,
              "minimum": 1
            },
            "description": "How many to return per page."
          }
        ],
        "responses": {
          "200": {
            "description": "A page of sentences.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobSegments"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "There is no job with that id (`job-not-found`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/jobs/{job_id}/segments/{position}": {
      "patch": {
        "operationId": "editDocumentSegment",
        "tags": [
          "Documents"
        ],
        "summary": "Correct a sentence of a document",
        "description": "Changes the translation of a sentence, its state, or both. With a new translation the sentence becomes a person's (`origin: interactive`), loses its score and is left as `translated` unless you say another state. The translation must carry the same marks as the source (`<g1>…</g1>`, `<x1/>`).\n\nThe file already delivered does not change until you ask to build it again with `POST /v1/jobs/{job_id}/rebuild`.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The id of the job (`job_…`)."
          },
          {
            "name": "position",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 0
            },
            "description": "The position of the sentence in the document, from 0."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SegmentEdit"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The sentence, as it is now.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobSegment"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "There is no job with that id, or it has no sentence at that position.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "409": {
            "description": "The job is running (`job-busy`), or the sentence is locked (`segment-locked`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/jobs/{job_id}/rebuild": {
      "post": {
        "operationId": "rebuildDocument",
        "tags": [
          "Documents"
        ],
        "summary": "Build the document again",
        "description": "After correcting sentences: the job goes back to the queue and, when it ends, its result is the new file. Nothing is translated or scored, so it uses no characters. It works for a finished job and for a failed one that has its sentences: one that ended `partial`, once the missing translations have been written, or one that failed while the file was being built.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The id of the job (`job_…`)."
          }
        ],
        "responses": {
          "202": {
            "description": "The job, queued again.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "There is no job with that id (`job-not-found`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "409": {
            "description": "The job is queued or running (`job-busy`), or it has no sentences to build from.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/jobs/{job_id}/review": {
      "post": {
        "operationId": "reviewDocument",
        "tags": [
          "Documents"
        ],
        "summary": "Send the reviewed sentences to a memory",
        "description": "Adds to one of your translation memories the sentences of the document that a person stands by: the ones a person wrote, and the ones approved (`approved_translation`, `approved_sign_off`). What the engine translated and nobody touched is left out. Next time, those sentences come from the memory instead of the engine. It can be repeated: an entry with the same source is replaced.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The id of the job (`job_…`)."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReviewRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "How many sentences went into the memory.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Review"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "There is no job with that id, or no memory with that id.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "409": {
            "description": "The job is queued or running (`job-busy`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/projects": {
      "get": {
        "operationId": "listProjects",
        "tags": [
          "Projects"
        ],
        "summary": "List projects",
        "description": "The projects of your organisation, newest first, each with what it holds.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 128
            },
            "description": "Cursor: the `next_after` of the previous page. Leave it out for the first page."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 200,
              "minimum": 1,
              "default": 50
            },
            "description": "How many to return per page."
          }
        ],
        "responses": {
          "200": {
            "description": "A page of projects.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Projects"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createProject",
        "tags": [
          "Projects"
        ],
        "summary": "Create a project",
        "description": "It starts empty. Add memories and glossaries to it, and translate with `project_id`.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProjectIn"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The project.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Project"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/projects/{project_id}": {
      "get": {
        "operationId": "getProject",
        "tags": [
          "Projects"
        ],
        "summary": "Get a project",
        "description": "The project and how many memories, glossaries and users it has.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The id of the project (`prj_…`)."
          }
        ],
        "responses": {
          "200": {
            "description": "The project.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Project"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "There is no project with that id (`project-not-found`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "renameProject",
        "tags": [
          "Projects"
        ],
        "summary": "Rename a project",
        "description": "Changes the name of the project. Nothing else about it changes.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The id of the project (`prj_…`)."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProjectIn"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The project, with its new name.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Project"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "There is no project with that id (`project-not-found`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteProject",
        "tags": [
          "Projects"
        ],
        "summary": "Delete a project",
        "description": "The project goes, with its list of users and of resources. Its memories, glossaries and documents stay in your organisation: the documents no longer belong to any project.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The id of the project (`prj_…`)."
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted."
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "There is no project with that id (`project-not-found`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/projects/{project_id}/resources": {
      "get": {
        "operationId": "listProjectResources",
        "tags": [
          "Projects"
        ],
        "summary": "List the memories and glossaries of a project",
        "description": "What is used when you translate with the project, most recently added first.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The id of the project (`prj_…`)."
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "memory",
                "glossary"
              ],
              "type": "string"
            },
            "description": "Only the memories, or only the glossaries."
          },
          {
            "name": "after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 256
            },
            "description": "Cursor: the `next_after` of the previous page. Leave it out for the first page."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 200,
              "minimum": 1,
              "default": 50
            },
            "description": "How many to return per page."
          }
        ],
        "responses": {
          "200": {
            "description": "A page of memories and glossaries.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectResourceList"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "There is no project with that id (`project-not-found`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/projects/{project_id}/resources/{resource_id}": {
      "put": {
        "operationId": "addProjectResource",
        "tags": [
          "Projects"
        ],
        "summary": "Add a memory or a glossary to a project",
        "description": "It has to belong to your organisation. If it was already in the project, nothing changes.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The id of the project (`prj_…`)."
          },
          {
            "name": "resource_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The id of the memory (`tm_…`) or of the glossary (`gl_…`)."
          }
        ],
        "responses": {
          "204": {
            "description": "It is in the project."
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "There is no project, or no memory or glossary, with that id.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "removeProjectResource",
        "tags": [
          "Projects"
        ],
        "summary": "Remove a memory or a glossary from a project",
        "description": "The memory or the glossary stays in your organisation.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The id of the project (`prj_…`)."
          },
          {
            "name": "resource_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The id of the memory (`tm_…`) or of the glossary (`gl_…`)."
          }
        ],
        "responses": {
          "204": {
            "description": "It is no longer in the project."
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "There is no project with that id (`project-not-found`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/plan": {
      "get": {
        "operationId": "getPlan",
        "tags": [
          "Account"
        ],
        "summary": "Get your plan",
        "description": "Your plan and what is left of it. On the free trial (`trial`): when it ends and how many source characters you can still translate. On the paid plan (`full`) there is no end date. `state` says whether you can translate (`active`), the trial has run out of time (`ended`) or of characters (`exhausted`), or trials are paused until next month (`paused`).",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "The plan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlanOut"
                },
                "example": {
                  "plan": "trial",
                  "state": "active",
                  "trial_ends_at": "2026-11-11T09:00:00Z",
                  "days_left": 30,
                  "character_limit": 100000,
                  "characters_used": 21840,
                  "characters_left": 78160
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/usage": {
      "get": {
        "operationId": "getUsage",
        "tags": [
          "Account"
        ],
        "summary": "Get your usage",
        "description": "Requests, sentences, characters, words and average score, by day or by hour (UTC) and, if you ask, split by kind of request, language pair, channel or key mode. One year per query at most.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Start of the period (ISO 8601 with time zone)."
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "End of the period, not included (ISO 8601 with time zone)."
          },
          {
            "name": "granularity",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "hour",
                "day"
              ],
              "type": "string",
              "default": "day"
            },
            "description": "The size of each period."
          },
          {
            "name": "group_by",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "none",
                "kind",
                "model",
                "pair",
                "channel",
                "mode"
              ],
              "type": "string",
              "default": "none"
            },
            "description": "What to split each period by: kind of request (`translate`, `document`, `qe`), model, language pair, channel (`api`, `web`) or key mode (`live`, `test`)."
          }
        ],
        "responses": {
          "200": {
            "description": "One row per period and group. Periods without usage are left out.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UsageResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/requests": {
      "get": {
        "operationId": "listRequests",
        "tags": [
          "Account"
        ],
        "summary": "List your requests",
        "description": "One row per request made with a key of your organisation, most recent first: what was asked, how it ended, how long it took and how much it translated. Never the text.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Only requests from this moment on (ISO 8601 with time zone)."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Only requests before this moment (ISO 8601 with time zone)."
          },
          {
            "name": "key_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 64
            },
            "description": "Only requests made with this key (`key_…`)."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 599,
              "minimum": 100
            },
            "description": "Only requests that ended with this HTTP status."
          },
          {
            "name": "route",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Only requests to this route, as a template: `/v1/jobs/{job_id}`."
          },
          {
            "name": "before",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 128
            },
            "description": "Cursor: the `next_before` of the previous page. Leave it out for the first page."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 200,
              "minimum": 1,
              "default": 50
            },
            "description": "How many to return per page."
          }
        ],
        "responses": {
          "200": {
            "description": "A page of requests.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Requests"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/requests/{request_id}": {
      "get": {
        "operationId": "getRequest",
        "tags": [
          "Account"
        ],
        "summary": "Get a request",
        "description": "One request, by the id that came in the `X-Request-Id` header of its response.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "request_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 128
            },
            "description": "The id of the request (`req_…`)."
          }
        ],
        "responses": {
          "200": {
            "description": "The request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RequestOut"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "There is no request with that id (`request-not-found`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/memories": {
      "post": {
        "operationId": "createMemory",
        "tags": [
          "Translation memories"
        ],
        "summary": "Upload translation memory, or create an empty one",
        "description": "With a file (`multipart/form-data`): uploads it and queues its indexing. The answer is the translation memory in `indexing` (`202`); once it is `ready`, use it with `memory_ids` in `POST /v1/translate` and `POST /v1/jobs`. With `webhook_url`, a `POST` is sent there when indexing ends, well or badly.\n\nWithout a file (JSON with `name`, `source_lang` and `target_lang`): creates it empty and ready (`201`), to fill it entry by entry.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file",
                  "source_lang",
                  "target_lang"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "The file: TMX, CSV, TSV. Up to 50 MB."
                  },
                  "source_lang": {
                    "type": "string",
                    "example": "es",
                    "description": "The source language of the translation memory (BCP 47: `es`, `en`, `pt-BR`…)."
                  },
                  "target_lang": {
                    "type": "string",
                    "example": "en",
                    "description": "Its target language. Not the same as `source_lang`."
                  },
                  "name": {
                    "type": "string",
                    "description": "A name to recognise it by. By default, the name of the file."
                  },
                  "webhook_url": {
                    "type": "string",
                    "description": "An HTTPS address to `POST` to when indexing ends, well or badly."
                  }
                }
              }
            },
            "application/json": {
              "schema": {
                "description": "An empty memory or glossary, to fill entry by entry.",
                "properties": {
                  "name": {
                    "maxLength": 200,
                    "minLength": 1,
                    "type": "string",
                    "description": "A name to recognise it by."
                  },
                  "source_lang": {
                    "type": "string",
                    "description": "Its source language. BCP 47 code: `es`, `en`, `pt-BR`…"
                  },
                  "target_lang": {
                    "type": "string",
                    "description": "Its target language. Not the same as `source_lang`. BCP 47 code: `es`, `en`, `pt-BR`…"
                  }
                },
                "required": [
                  "name",
                  "source_lang",
                  "target_lang"
                ],
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The translation memory, empty and ready.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Resource"
                }
              }
            }
          },
          "202": {
            "description": "The translation memory, being indexed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Resource"
                },
                "example": {
                  "id": "tm_5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d",
                  "kind": "memory",
                  "name": "Legal ES-EN",
                  "source_lang": "es",
                  "target_lang": "en",
                  "file_name": "legal.tmx",
                  "status": "indexing",
                  "entries": null,
                  "error": null,
                  "error_code": null,
                  "job_id": "job_1f2e3d4c5b6a79880a1b2c3d4e5f6a7b",
                  "created_at": "2026-10-12T09:12:00+00:00"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "413": {
            "description": "The file is larger than the maximum (`document-rejected`): 50 MB.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listMemories",
        "tags": [
          "Translation memories"
        ],
        "summary": "List translation memories",
        "description": "The translation memories of your organisation, newest first.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 128
            },
            "description": "Cursor: the `next_after` of the previous page. Leave it out for the first page."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 200,
              "minimum": 1,
              "default": 50
            },
            "description": "How many to return per page."
          }
        ],
        "responses": {
          "200": {
            "description": "A page of translation memories.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Resources"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/memories/{resource_id}": {
      "get": {
        "operationId": "getMemory",
        "tags": [
          "Translation memories"
        ],
        "summary": "Get translation memory",
        "description": "The translation memory: its languages, its status and how many entries it has.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "resource_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The id of the translation memory (`tm_…`)."
          }
        ],
        "responses": {
          "200": {
            "description": "The translation memory.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Resource"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "There is no translation memory with that id (`resource-not-found`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteMemory",
        "tags": [
          "Translation memories"
        ],
        "summary": "Delete translation memory",
        "description": "Deletes its entries and its file. If it was still being indexed, the indexing is cancelled. It cannot be undone.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "resource_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The id of the translation memory (`tm_…`)."
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted."
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "There is no translation memory with that id (`resource-not-found`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/memories/{resource_id}/entries": {
      "get": {
        "operationId": "listMemoryEntries",
        "tags": [
          "Translation memories"
        ],
        "summary": "List the entries of translation memory",
        "description": "In order of source text. With `q`, the entries whose source is closest to that text, best match first and without further pages.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "resource_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The id of the translation memory (`tm_…`)."
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 2000,
              "default": ""
            },
            "description": "Text to look for in the source of the entries."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 200,
              "minimum": 1,
              "default": 50
            },
            "description": "How many to return per page."
          },
          {
            "name": "after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 20000
            },
            "description": "Cursor: the `next_after` of the previous page. Leave it out for the first page."
          }
        ],
        "responses": {
          "200": {
            "description": "A page of entries.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Entries"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "There is no translation memory with that id (`resource-not-found`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "addMemoryEntry",
        "tags": [
          "Translation memories"
        ],
        "summary": "Add an entry to translation memory",
        "description": "Adds a sentence pair without uploading a file. If there was already an entry with that source, it is replaced (`200`); if it is new, `201`. It can be used at once in `POST /v1/translate` and `POST /v1/jobs`.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "resource_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The id of the translation memory (`tm_…`)."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EntryIn"
              },
              "example": {
                "source": "preaviso",
                "target": "notice"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The entry with that source, replaced.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Entry"
                }
              }
            }
          },
          "201": {
            "description": "The new entry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Entry"
                },
                "example": {
                  "id": "e_9d8c7b6a",
                  "source": "preaviso",
                  "target": "notice"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "There is no translation memory with that id (`resource-not-found`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "409": {
            "description": "The translation memory is still being indexed (`resource-busy`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/memories/{resource_id}/entries/{entry_id}": {
      "patch": {
        "operationId": "editMemoryEntry",
        "tags": [
          "Translation memories"
        ],
        "summary": "Change the target of an entry",
        "description": "The source of an entry is what identifies it and cannot be changed: for another source, add a new entry and delete this one.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "resource_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The id of the translation memory (`tm_…`)."
          },
          {
            "name": "entry_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The id of the entry."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EntryEdit"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The entry, with its new target.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Entry"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "There is no translation memory, or no entry, with that id.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "409": {
            "description": "The translation memory is still being indexed (`resource-busy`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteMemoryEntry",
        "tags": [
          "Translation memories"
        ],
        "summary": "Delete an entry",
        "description": "Removes the entry from the translation memory. It cannot be undone.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "resource_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The id of the translation memory (`tm_…`)."
          },
          {
            "name": "entry_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The id of the entry."
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted."
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "There is no translation memory, or no entry, with that id.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "409": {
            "description": "The translation memory is still being indexed (`resource-busy`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/glossaries": {
      "post": {
        "operationId": "createGlossary",
        "tags": [
          "Glossaries"
        ],
        "summary": "Upload glossary, or create an empty one",
        "description": "With a file (`multipart/form-data`): uploads it and queues its indexing. The answer is the glossary in `indexing` (`202`); once it is `ready`, use it with `glossary_ids` in `POST /v1/translate` and `POST /v1/jobs`. With `webhook_url`, a `POST` is sent there when indexing ends, well or badly.\n\nWithout a file (JSON with `name`, `source_lang` and `target_lang`): creates it empty and ready (`201`), to fill it entry by entry.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file",
                  "source_lang",
                  "target_lang"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "The file: TBX, CSV, TSV. Up to 50 MB."
                  },
                  "source_lang": {
                    "type": "string",
                    "example": "es",
                    "description": "The source language of the glossary (BCP 47: `es`, `en`, `pt-BR`…)."
                  },
                  "target_lang": {
                    "type": "string",
                    "example": "en",
                    "description": "Its target language. Not the same as `source_lang`."
                  },
                  "name": {
                    "type": "string",
                    "description": "A name to recognise it by. By default, the name of the file."
                  },
                  "webhook_url": {
                    "type": "string",
                    "description": "An HTTPS address to `POST` to when indexing ends, well or badly."
                  }
                }
              }
            },
            "application/json": {
              "schema": {
                "description": "An empty memory or glossary, to fill entry by entry.",
                "properties": {
                  "name": {
                    "maxLength": 200,
                    "minLength": 1,
                    "type": "string",
                    "description": "A name to recognise it by."
                  },
                  "source_lang": {
                    "type": "string",
                    "description": "Its source language. BCP 47 code: `es`, `en`, `pt-BR`…"
                  },
                  "target_lang": {
                    "type": "string",
                    "description": "Its target language. Not the same as `source_lang`. BCP 47 code: `es`, `en`, `pt-BR`…"
                  }
                },
                "required": [
                  "name",
                  "source_lang",
                  "target_lang"
                ],
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The glossary, empty and ready.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Resource"
                }
              }
            }
          },
          "202": {
            "description": "The glossary, being indexed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Resource"
                },
                "example": {
                  "id": "gl_3f9a1c2b7d5e4f60a1b2c3d4e5f60718",
                  "kind": "glossary",
                  "name": "Legal terms",
                  "source_lang": "es",
                  "target_lang": "en",
                  "file_name": "terms.csv",
                  "status": "indexing",
                  "entries": null,
                  "error": null,
                  "error_code": null,
                  "job_id": "job_1f2e3d4c5b6a79880a1b2c3d4e5f6a7b",
                  "created_at": "2026-10-12T09:12:00+00:00"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "413": {
            "description": "The file is larger than the maximum (`document-rejected`): 50 MB.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listGlossaries",
        "tags": [
          "Glossaries"
        ],
        "summary": "List glossaries",
        "description": "The glossaries of your organisation, newest first.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 128
            },
            "description": "Cursor: the `next_after` of the previous page. Leave it out for the first page."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 200,
              "minimum": 1,
              "default": 50
            },
            "description": "How many to return per page."
          }
        ],
        "responses": {
          "200": {
            "description": "A page of glossaries.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Resources"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/glossaries/{resource_id}": {
      "get": {
        "operationId": "getGlossary",
        "tags": [
          "Glossaries"
        ],
        "summary": "Get glossary",
        "description": "The glossary: its languages, its status and how many entries it has.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "resource_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The id of the glossary (`gl_…`)."
          }
        ],
        "responses": {
          "200": {
            "description": "The glossary.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Resource"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "There is no glossary with that id (`resource-not-found`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteGlossary",
        "tags": [
          "Glossaries"
        ],
        "summary": "Delete glossary",
        "description": "Deletes its entries and its file. If it was still being indexed, the indexing is cancelled. It cannot be undone.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "resource_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The id of the glossary (`gl_…`)."
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted."
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "There is no glossary with that id (`resource-not-found`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/glossaries/{resource_id}/entries": {
      "get": {
        "operationId": "listGlossaryEntries",
        "tags": [
          "Glossaries"
        ],
        "summary": "List the entries of glossary",
        "description": "In order of source text. With `q`, the entries whose source is closest to that text, best match first and without further pages.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "resource_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The id of the glossary (`gl_…`)."
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 2000,
              "default": ""
            },
            "description": "Text to look for in the source of the entries."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 200,
              "minimum": 1,
              "default": 50
            },
            "description": "How many to return per page."
          },
          {
            "name": "after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 20000
            },
            "description": "Cursor: the `next_after` of the previous page. Leave it out for the first page."
          }
        ],
        "responses": {
          "200": {
            "description": "A page of entries.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Entries"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "There is no glossary with that id (`resource-not-found`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "addGlossaryEntry",
        "tags": [
          "Glossaries"
        ],
        "summary": "Add an entry to glossary",
        "description": "Adds a term without uploading a file. If there was already an entry with that source, it is replaced (`200`); if it is new, `201`. It can be used at once in `POST /v1/translate` and `POST /v1/jobs`.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "resource_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The id of the glossary (`gl_…`)."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EntryIn"
              },
              "example": {
                "source": "preaviso",
                "target": "notice"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The entry with that source, replaced.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Entry"
                }
              }
            }
          },
          "201": {
            "description": "The new entry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Entry"
                },
                "example": {
                  "id": "e_9d8c7b6a",
                  "source": "preaviso",
                  "target": "notice"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "There is no glossary with that id (`resource-not-found`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "409": {
            "description": "The glossary is still being indexed (`resource-busy`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/glossaries/{resource_id}/entries/{entry_id}": {
      "patch": {
        "operationId": "editGlossaryEntry",
        "tags": [
          "Glossaries"
        ],
        "summary": "Change the target of an entry",
        "description": "The source of an entry is what identifies it and cannot be changed: for another source, add a new entry and delete this one.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "resource_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The id of the glossary (`gl_…`)."
          },
          {
            "name": "entry_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The id of the entry."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EntryEdit"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The entry, with its new target.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Entry"
                }
              }
            }
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "There is no glossary, or no entry, with that id.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "409": {
            "description": "The glossary is still being indexed (`resource-busy`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteGlossaryEntry",
        "tags": [
          "Glossaries"
        ],
        "summary": "Delete an entry",
        "description": "Removes the entry from the glossary. It cannot be undone.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "resource_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The id of the glossary (`gl_…`)."
          },
          {
            "name": "entry_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The id of the entry."
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted."
          },
          "400": {
            "description": "The request is not valid (`invalid-request` and others). `errors` says what is wrong, field by field.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                },
                "example": {
                  "type": "https://developer.translaqe.com/errors/invalid-request",
                  "title": "La petición no es válida",
                  "status": 400,
                  "errors": [
                    {
                      "path": "target_lang",
                      "message": "El idioma de origen y el de destino deben ser distintos"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, wrong or revoked (`unauthorized`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "The key may not do this (`forbidden`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "404": {
            "description": "There is no glossary, or no entry, with that id.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "409": {
            "description": "The glossary is still being indexed (`resource-busy`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests (`rate-limited`). `Retry-After` says how many seconds to wait.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "503": {
            "description": "The engine or a service behind the API is not available right now; try again shortly. For organisations on the free trial it can also mean that trials are paused until next month (`trial-paused`).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Entries": {
        "properties": {
          "resource_id": {
            "type": "string",
            "description": "The memory or the glossary."
          },
          "total": {
            "type": "integer",
            "description": "How many there are: all the entries or, with `q`, the ones that match."
          },
          "entries": {
            "items": {
              "$ref": "#/components/schemas/Entry"
            },
            "type": "array",
            "description": "The entries of this page."
          },
          "next_after": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "What to send as `after` to get the next page; `null` if there are no more."
          }
        },
        "type": "object",
        "required": [
          "resource_id",
          "total",
          "entries",
          "next_after"
        ]
      },
      "Entry": {
        "properties": {
          "id": {
            "type": "string",
            "description": "Its id. It comes from its source: adding the same source again changes this entry."
          },
          "source": {
            "type": "string",
            "description": "The text in the source language."
          },
          "target": {
            "type": "string",
            "description": "Its translation."
          }
        },
        "type": "object",
        "required": [
          "id",
          "source",
          "target"
        ]
      },
      "EntryEdit": {
        "properties": {
          "target": {
            "type": "string",
            "maxLength": 10000,
            "minLength": 1,
            "description": "The new translation."
          }
        },
        "type": "object",
        "required": [
          "target"
        ],
        "description": "The new target of an entry."
      },
      "EntryIn": {
        "properties": {
          "source": {
            "type": "string",
            "maxLength": 10000,
            "minLength": 1,
            "description": "The text in the source language."
          },
          "target": {
            "type": "string",
            "maxLength": 10000,
            "minLength": 1,
            "description": "Its translation."
          }
        },
        "type": "object",
        "required": [
          "source",
          "target"
        ],
        "description": "A sentence pair of a memory, or a term of a glossary."
      },
      "GlossaryTerm": {
        "properties": {
          "source": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1,
            "description": "The term in the source language."
          },
          "target": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1,
            "description": "Its translation."
          }
        },
        "type": "object",
        "required": [
          "source",
          "target"
        ],
        "description": "A term and how it must be translated."
      },
      "Job": {
        "properties": {
          "id": {
            "type": "string",
            "description": "The id of the job (`job_…`)."
          },
          "kind": {
            "type": "string",
            "enum": [
              "translate_document",
              "index_resource"
            ],
            "description": "`translate_document`, or `index_resource` for a memory or a glossary being indexed."
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "running",
              "retrying",
              "succeeded",
              "failed",
              "cancelled"
            ],
            "description": "`queued`, `running`, `retrying` (it failed and will be tried again), `succeeded`, `failed` or `cancelled`. The last three are final."
          },
          "file_name": {
            "type": "string",
            "description": "The name of the file that was uploaded."
          },
          "source_lang": {
            "type": "string",
            "description": "The source language."
          },
          "target_lang": {
            "type": "string",
            "description": "The target language."
          },
          "allow_partial": {
            "type": "boolean",
            "description": "Whether the file is delivered even if some sentence could not be translated."
          },
          "stage": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "extracting",
                  "translating",
                  "scoring",
                  "rebuilding"
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "The stage the job is in, or the one where it failed: `extracting` (reading the document), `translating`, `scoring` or `rebuilding` (building the translated file). `null` while queued and when it ends well."
          },
          "progress": {
            "$ref": "#/components/schemas/JobProgress",
            "description": "How far it has got."
          },
          "counts": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobCounts"
              },
              {
                "type": "null"
              }
            ],
            "description": "The sentences of the document, from the moment it is read; also if the job fails."
          },
          "result": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "What it produced; `null` until it ends well."
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why it failed, in words; `null` if it has not."
          },
          "error_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A stable code for the failure: `unsupported_format`, `nothing_to_translate`, `partial` (some sentence could not be translated), `internal`…"
          },
          "attempts": {
            "type": "integer",
            "description": "How many times it has been tried."
          },
          "created_at": {
            "type": "string",
            "description": "When it was created (ISO 8601, UTC)."
          },
          "started_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When it started; `null` while queued."
          },
          "finished_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When it ended; `null` until then."
          },
          "project_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The project it was sent with, if any."
          }
        },
        "type": "object",
        "required": [
          "id",
          "kind",
          "status",
          "file_name",
          "source_lang",
          "target_lang",
          "allow_partial",
          "stage",
          "progress",
          "counts",
          "result",
          "error",
          "error_code",
          "attempts",
          "created_at",
          "started_at",
          "finished_at"
        ],
        "description": "A background job: the translation of a document, or the indexing of a memory or a glossary."
      },
      "JobCounts": {
        "properties": {
          "segments": {
            "type": "integer",
            "description": "Sentences in the document."
          },
          "translated": {
            "type": "integer",
            "description": "Translated by the engine."
          },
          "from_memory": {
            "type": "integer",
            "description": "Taken from a translation memory."
          },
          "untranslatable": {
            "type": "integer",
            "description": "With nothing to translate: they keep their source."
          },
          "edited": {
            "type": "integer",
            "description": "With a translation written by a person."
          },
          "failed": {
            "type": "integer",
            "description": "No model could translate them: they are not tried again."
          },
          "pending": {
            "type": "integer",
            "description": "Without a translation yet: not reached, or about to be retried."
          },
          "characters": {
            "type": "integer",
            "description": "Characters of the source of all the sentences, without formatting marks."
          },
          "words": {
            "type": "integer",
            "description": "Words of the source of all the sentences."
          }
        },
        "type": "object",
        "required": [
          "segments",
          "translated",
          "from_memory",
          "untranslatable",
          "edited",
          "failed",
          "pending",
          "characters",
          "words"
        ],
        "description": "The sentences of the document and what became of each. `translated`, `from_memory`, `untranslatable`, `edited`, `failed` and `pending` add up to `segments`."
      },
      "JobProgress": {
        "properties": {
          "done": {
            "type": "integer",
            "description": "Sentences done so far."
          },
          "total": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Sentences in total; `null` until the document has been read."
          }
        },
        "type": "object",
        "required": [
          "done",
          "total"
        ],
        "description": "How far the job has got."
      },
      "JobResult": {
        "properties": {
          "file_id": {
            "type": "string",
            "description": "The id of the translated file. Download it from `GET /v1/jobs/{job_id}/file`."
          },
          "segments": {
            "type": "integer",
            "description": "How many sentences the document has."
          },
          "scored": {
            "type": "boolean",
            "description": "`false` if scoring was not available: the translation is delivered anyway, without scores."
          },
          "average_score": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "The average score of its sentences; `null` if they were not scored."
          },
          "low_score_segments": {
            "type": "integer",
            "description": "Sentences with a score under 60."
          },
          "failed_segments": {
            "type": "integer",
            "default": 0,
            "description": "Sentences without a translation, left in the source language. Only with `allow_partial`."
          },
          "mark_warnings": {
            "type": "integer",
            "default": 0,
            "description": "Sentences where a formatting mark had to be fixed while building the file: worth a look at how their formatting came out."
          }
        },
        "type": "object",
        "required": [
          "file_id",
          "segments",
          "scored",
          "average_score",
          "low_score_segments"
        ],
        "description": "What a finished job produced."
      },
      "JobSegment": {
        "properties": {
          "position": {
            "type": "integer",
            "description": "Its order in the document, from 0."
          },
          "unit": {
            "type": "string",
            "description": "The id of its paragraph in the document."
          },
          "mid": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The id of the sentence inside its paragraph, if the paragraph is split into sentences."
          },
          "source": {
            "type": "string",
            "description": "The source text, with its formatting marks."
          },
          "target": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The translation, with its marks; `null` if it has none yet."
          },
          "state": {
            "type": "string",
            "enum": [
              "not_translated",
              "draft",
              "translated",
              "rejected_translation",
              "approved_translation",
              "rejected_sign_off",
              "approved_sign_off"
            ],
            "description": "Its confirmation level, as CAT tools name them: `not_translated`, `draft`, `translated`, `rejected_translation`, `approved_translation`, `rejected_sign_off` or `approved_sign_off`."
          },
          "origin": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "mt",
                  "tm",
                  "source",
                  "interactive"
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Where the translation comes from: `mt` (the engine), `tm` (a memory), `source` (the source, copied) or `interactive` (a person)."
          },
          "origin_detail": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "With what: the engine version, if it was the engine."
          },
          "match_percent": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "How close the match was, if it came from a memory."
          },
          "locked": {
            "type": "boolean",
            "description": "Whether the sentence is locked: a locked sentence cannot be changed."
          },
          "score": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Quality score from 0 (worst) to 100 (best); `null` if there is no score."
          },
          "band": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "fiable",
                  "revisar",
                  "rehacer",
                  "sin-nota"
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Quality band: `fiable` (reliable: use it as it is), `revisar` (worth a review), `rehacer` (translate it again) or `sin-nota` (no score for this language pair). `null` while it has not been scored."
          },
          "checks": {
            "items": {
              "$ref": "#/components/schemas/QeCheck"
            },
            "type": "array",
            "description": "The automatic checks the translation did not pass. Empty if it passed them all."
          },
          "tags": {
            "items": {
              "$ref": "#/components/schemas/SegmentTag"
            },
            "type": "array",
            "description": "The formatting marks of the sentence."
          },
          "characters": {
            "type": "integer",
            "description": "Characters of the source, without marks."
          },
          "words": {
            "type": "integer",
            "description": "Words of the source."
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why it could not be translated, if it failed."
          },
          "failed": {
            "type": "boolean",
            "description": "`true` if no model could translate it and it is not tried again."
          }
        },
        "type": "object",
        "required": [
          "position",
          "unit",
          "mid",
          "source",
          "target",
          "state",
          "origin",
          "origin_detail",
          "match_percent",
          "locked",
          "score",
          "band",
          "checks",
          "tags",
          "characters",
          "words",
          "error",
          "failed"
        ],
        "description": "A sentence of a document."
      },
      "JobSegments": {
        "properties": {
          "job_id": {
            "type": "string",
            "description": "The job."
          },
          "total": {
            "type": "integer",
            "description": "How many sentences of the document match the filter, not only the ones in this page."
          },
          "segments": {
            "items": {
              "$ref": "#/components/schemas/JobSegment"
            },
            "type": "array",
            "description": "The sentences of this page, in the order of the document."
          },
          "next_after": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "What to send as `after` to get the next page; `null` if there are no more."
          }
        },
        "type": "object",
        "required": [
          "job_id",
          "total",
          "segments",
          "next_after"
        ]
      },
      "Jobs": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/Job"
            },
            "type": "array",
            "description": "The jobs of this page, newest first."
          },
          "next_after": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "What to send as `after` to get the next page; `null` if there are no more."
          }
        },
        "type": "object",
        "required": [
          "data"
        ]
      },
      "Language": {
        "properties": {
          "code": {
            "type": "string",
            "description": "BCP 47 code."
          },
          "name": {
            "type": "string",
            "description": "Its name, in that language."
          },
          "qe": {
            "type": "boolean",
            "description": "Whether quality scores are validated for this language."
          }
        },
        "type": "object",
        "required": [
          "code",
          "name",
          "qe"
        ]
      },
      "LanguagesResponse": {
        "properties": {
          "languages": {
            "items": {
              "$ref": "#/components/schemas/Language"
            },
            "type": "array",
            "description": "The languages of this page."
          },
          "next_after": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "What to send as `after` to get the next page; `null` if there are no more."
          }
        },
        "type": "object",
        "required": [
          "languages"
        ]
      },
      "PlanOut": {
        "properties": {
          "plan": {
            "type": "string",
            "enum": [
              "trial",
              "full"
            ],
            "description": "`trial` (the free trial) or `full` (the paid plan)."
          },
          "state": {
            "type": "string",
            "enum": [
              "active",
              "ended",
              "exhausted",
              "paused"
            ],
            "description": "`active` (you can translate), `ended` (the trial has run out of time), `exhausted` (no characters left) or `paused` (trials are paused until next month)."
          },
          "trial_ends_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the trial ends; `null` on the paid plan."
          },
          "days_left": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Days left of the trial, counting today."
          },
          "character_limit": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Source characters you can translate; `null` if there is no limit."
          },
          "characters_used": {
            "type": "integer",
            "description": "The ones already translated, plus the ones set aside for documents being translated."
          },
          "characters_left": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "The ones you can still translate; `null` if there is no limit."
          }
        },
        "type": "object",
        "required": [
          "plan",
          "state",
          "trial_ends_at",
          "days_left",
          "character_limit",
          "characters_used",
          "characters_left"
        ],
        "description": "Your plan and what is left of it."
      },
      "PostEditSegment": {
        "properties": {
          "source": {
            "type": "string",
            "maxLength": 2000,
            "minLength": 1,
            "description": "The sentence in the source language."
          },
          "target": {
            "type": "string",
            "maxLength": 4000,
            "minLength": 1,
            "description": "The translation you already have."
          }
        },
        "type": "object",
        "required": [
          "source",
          "target"
        ],
        "description": "A sentence with a translation to post-edit: what is wrong is fixed, the rest is left alone."
      },
      "Problem": {
        "properties": {
          "type": {
            "type": "string",
            "description": "A URI that identifies the kind of error, and the page that explains it: `https://developer.translaqe.com/errors/rate-limited`. Tell errors apart by this, not by `title`."
          },
          "title": {
            "type": "string",
            "description": "A short summary, in words (in Spanish for now)."
          },
          "status": {
            "type": "integer",
            "description": "The HTTP status."
          },
          "detail": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "What to do about it, when there is something to say."
          },
          "errors": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/ProblemError"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "On an invalid request, what is wrong with each field."
          }
        },
        "type": "object",
        "required": [
          "type",
          "title",
          "status"
        ],
        "description": "An error, as RFC 9457 `application/problem+json`."
      },
      "ProblemError": {
        "properties": {
          "path": {
            "type": "string",
            "description": "The field: `segments.0`, `target_lang`…"
          },
          "message": {
            "type": "string",
            "description": "What is wrong with it, in words."
          }
        },
        "type": "object",
        "required": [
          "path",
          "message"
        ],
        "description": "What is wrong with one field of the request."
      },
      "Project": {
        "properties": {
          "id": {
            "type": "string",
            "description": "The id of the project (`prj_…`)."
          },
          "name": {
            "type": "string",
            "description": "Its name."
          },
          "members": {
            "type": "integer",
            "description": "How many users it has."
          },
          "memories": {
            "type": "integer",
            "description": "How many translation memories it has."
          },
          "glossaries": {
            "type": "integer",
            "description": "How many glossaries it has."
          },
          "created_at": {
            "type": "string",
            "description": "When it was created (ISO 8601, UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "name",
          "members",
          "memories",
          "glossaries",
          "created_at"
        ],
        "description": "A project: the memories and the glossaries you translate with, and the users who work in it."
      },
      "ProjectIn": {
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 120,
            "minLength": 1,
            "description": "The name of the project."
          }
        },
        "type": "object",
        "required": [
          "name"
        ]
      },
      "ProjectResource": {
        "properties": {
          "id": {
            "type": "string",
            "description": "Its id: `tm_…` for a memory, `gl_…` for a glossary."
          },
          "kind": {
            "type": "string",
            "enum": [
              "memory",
              "glossary"
            ],
            "description": "`memory` or `glossary`."
          },
          "name": {
            "type": "string",
            "description": "Its name."
          },
          "source_lang": {
            "type": "string",
            "description": "Its source language."
          },
          "target_lang": {
            "type": "string",
            "description": "Its target language."
          }
        },
        "type": "object",
        "required": [
          "id",
          "kind",
          "name",
          "source_lang",
          "target_lang"
        ]
      },
      "ProjectResourceList": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/ProjectResource"
            },
            "type": "array",
            "description": "The memories and the glossaries of this page."
          },
          "next_after": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "What to send as `after` to get the next page; `null` if there are no more."
          }
        },
        "type": "object",
        "required": [
          "data"
        ]
      },
      "Projects": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/Project"
            },
            "type": "array",
            "description": "The projects of this page, newest first."
          },
          "next_after": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "What to send as `after` to get the next page; `null` if there are no more."
          }
        },
        "type": "object",
        "required": [
          "data"
        ]
      },
      "QeCheck": {
        "properties": {
          "code": {
            "type": "string",
            "enum": [
              "numbers",
              "tags",
              "tag_order",
              "glossary",
              "length",
              "untranslated"
            ],
            "description": "Which check: `numbers` (a number differs), `tags` (a formatting mark is missing or extra), `tag_order` (marks in a different order), `glossary` (a term was not applied), `length` (much longer or shorter than expected) or `untranslated` (left in the source language)."
          },
          "message": {
            "type": "string",
            "description": "What was found, in words."
          }
        },
        "type": "object",
        "required": [
          "code",
          "message"
        ],
        "description": "An automatic check that a translation did not pass."
      },
      "QeItem": {
        "properties": {
          "source": {
            "type": "string",
            "maxLength": 2000,
            "minLength": 1,
            "description": "The sentence in the source language."
          },
          "target": {
            "type": "string",
            "maxLength": 4000,
            "description": "The translation to score."
          }
        },
        "type": "object",
        "required": [
          "source",
          "target"
        ],
        "description": "A sentence and its translation."
      },
      "QeRequest": {
        "properties": {
          "source_lang": {
            "type": "string",
            "description": "The language of the source sentences. BCP 47 code: `es`, `en`, `pt-BR`…"
          },
          "target_lang": {
            "type": "string",
            "description": "The language of the translations. Not the same as `source_lang`. BCP 47 code: `es`, `en`, `pt-BR`…"
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/QeItem"
            },
            "type": "array",
            "maxItems": 100,
            "minItems": 1,
            "description": "The translations to score."
          },
          "glossary": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/GlossaryTerm"
                },
                "type": "array",
                "maxItems": 500
              },
              {
                "type": "null"
              }
            ],
            "description": "Terms the translations should respect: one that was not applied is reported in `checks`."
          }
        },
        "type": "object",
        "required": [
          "source_lang",
          "target_lang",
          "items"
        ]
      },
      "QeResponse": {
        "properties": {
          "qe_version": {
            "type": "string",
            "description": "The version of the scorer."
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/QeScoredItem"
            },
            "type": "array",
            "description": "One per item sent, in the same order."
          }
        },
        "type": "object",
        "required": [
          "qe_version",
          "items"
        ]
      },
      "QeScoredItem": {
        "properties": {
          "index": {
            "type": "integer",
            "description": "The position of the item in the request, from 0."
          },
          "score": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 100.0,
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "description": "Quality score from 0 (worst) to 100 (best); `null` if there is no score."
          },
          "band": {
            "type": "string",
            "enum": [
              "fiable",
              "revisar",
              "rehacer",
              "sin-nota"
            ],
            "description": "Quality band: `fiable` (reliable: use it as it is), `revisar` (worth a review), `rehacer` (translate it again) or `sin-nota` (no score for this language pair)."
          },
          "checks": {
            "items": {
              "$ref": "#/components/schemas/QeCheck"
            },
            "type": "array",
            "description": "The automatic checks the translation did not pass. Empty if it passed them all."
          }
        },
        "type": "object",
        "required": [
          "index",
          "score",
          "band",
          "checks"
        ]
      },
      "RequestOut": {
        "properties": {
          "id": {
            "type": "string",
            "description": "The id of the request: the one in the `X-Request-Id` header of its response."
          },
          "client_request_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The id you sent in `X-Request-Id`, if you sent one."
          },
          "at": {
            "type": "string",
            "format": "date-time",
            "description": "When it arrived."
          },
          "key_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The key it was made with."
          },
          "mode": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "live",
                  "test"
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "The mode of that key: `live` or `test`."
          },
          "user_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The user, if it was made from the TranslaQE web app."
          },
          "channel": {
            "type": "string",
            "enum": [
              "api",
              "web",
              "cli"
            ],
            "description": "How it came in: with an API key (`api`), from the web app (`web`) or from the command line (`cli`)."
          },
          "ip": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The IP address it came from."
          },
          "user_agent": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Its `User-Agent`."
          },
          "method": {
            "type": "string",
            "description": "The HTTP method."
          },
          "route": {
            "type": "string",
            "description": "The route, as a template: `/v1/jobs/{job_id}`."
          },
          "job_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The job it is about, if any."
          },
          "resource_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The memory, the glossary or the project it is about, if any."
          },
          "status": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "The HTTP status of the response."
          },
          "error_type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "If it ended in an error, the last part of its `type`: `rate-limited`, `invalid-request`…"
          },
          "duration_ms": {
            "type": "integer",
            "description": "How long it took, in milliseconds."
          },
          "bytes_in": {
            "type": "integer",
            "description": "Size of the request body, in bytes."
          },
          "bytes_out": {
            "type": "integer",
            "description": "Size of the response body, in bytes."
          },
          "source_lang": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The source language of what was translated or scored."
          },
          "target_lang": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Its target language."
          },
          "segments": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Sentences translated or scored. For a document, see its job."
          },
          "characters": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Characters of the source."
          },
          "model": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The version of the engine that answered."
          }
        },
        "type": "object",
        "required": [
          "id",
          "client_request_id",
          "at",
          "key_id",
          "mode",
          "user_id",
          "channel",
          "ip",
          "user_agent",
          "method",
          "route",
          "job_id",
          "resource_id",
          "status",
          "error_type",
          "duration_ms",
          "bytes_in",
          "bytes_out",
          "source_lang",
          "target_lang",
          "segments",
          "characters",
          "model"
        ],
        "description": "A request of your organisation: who made it, what it asked, how it ended and how much it translated. Never the text."
      },
      "Requests": {
        "properties": {
          "requests": {
            "items": {
              "$ref": "#/components/schemas/RequestOut"
            },
            "type": "array",
            "description": "The requests of this page, most recent first."
          },
          "next_before": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "What to send as `before` to get the next page; `null` if there are no more."
          }
        },
        "type": "object",
        "required": [
          "requests",
          "next_before"
        ]
      },
      "Resource": {
        "properties": {
          "id": {
            "type": "string",
            "description": "Its id: `tm_…` for a memory, `gl_…` for a glossary."
          },
          "kind": {
            "type": "string",
            "enum": [
              "memory",
              "glossary"
            ],
            "description": "`memory` or `glossary`."
          },
          "name": {
            "type": "string",
            "description": "Its name."
          },
          "source_lang": {
            "type": "string",
            "description": "Its source language."
          },
          "target_lang": {
            "type": "string",
            "description": "Its target language."
          },
          "file_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The file it was uploaded with; `null` if it was created empty."
          },
          "status": {
            "type": "string",
            "enum": [
              "indexing",
              "ready",
              "failed",
              "cancelled"
            ],
            "description": "`indexing` (its entries are being read), `ready` (it can be used), `failed` (see `error`) or `cancelled`."
          },
          "entries": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "How many entries it has; `null` until it has been indexed."
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why indexing failed, in words."
          },
          "error_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A stable code for the failure: `invalid_resource`, `empty_resource`…"
          },
          "job_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The job that indexes it: follow it at `GET /v1/jobs/{job_id}`. `null` if it was created empty."
          },
          "created_at": {
            "type": "string",
            "description": "When it was created (ISO 8601, UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "kind",
          "name",
          "source_lang",
          "target_lang",
          "file_name",
          "status",
          "entries",
          "error",
          "error_code",
          "job_id",
          "created_at"
        ],
        "description": "A translation memory (`tm_…`) or a glossary (`gl_…`)."
      },
      "Resources": {
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/Resource"
            },
            "type": "array",
            "description": "The memories or the glossaries of this page, newest first."
          },
          "next_after": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "What to send as `after` to get the next page; `null` if there are no more."
          }
        },
        "type": "object",
        "required": [
          "data"
        ]
      },
      "Review": {
        "properties": {
          "job_id": {
            "type": "string",
            "description": "The job."
          },
          "memory_id": {
            "type": "string",
            "description": "The memory."
          },
          "reviewed": {
            "type": "integer",
            "description": "Sentences of the document that a person wrote or approved."
          },
          "added": {
            "type": "integer",
            "description": "The ones that went into the memory: new, or replacing the entry with that source."
          },
          "skipped": {
            "type": "integer",
            "description": "The ones that could not go into the memory: too long."
          },
          "entries": {
            "type": "integer",
            "description": "Entries in the memory afterwards."
          }
        },
        "type": "object",
        "required": [
          "job_id",
          "memory_id",
          "reviewed",
          "added",
          "skipped",
          "entries"
        ]
      },
      "ReviewRequest": {
        "properties": {
          "memory_id": {
            "type": "string",
            "maxLength": 128,
            "minLength": 1,
            "description": "The translation memory to add the reviewed sentences to (`tm_…`). It must cover the language pair of the document."
          }
        },
        "type": "object",
        "required": [
          "memory_id"
        ]
      },
      "SegmentEdit": {
        "properties": {
          "target": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 10000
              },
              {
                "type": "null"
              }
            ],
            "description": "The new translation, with the marks of the source (`<g1>…</g1>`, `<x1/>`)."
          },
          "state": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "not_translated",
                  "draft",
                  "translated",
                  "rejected_translation",
                  "approved_translation",
                  "rejected_sign_off",
                  "approved_sign_off"
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "The new state. With a new translation and no state, the sentence is left as `translated`."
          }
        },
        "type": "object",
        "description": "What to change in a sentence: its translation, its state, or both."
      },
      "SegmentTag": {
        "properties": {
          "n": {
            "type": "integer",
            "description": "Its number in the sentence."
          },
          "kind": {
            "type": "string",
            "description": "`g` (a span with an opening and a closing), `x` (an object), `b` (a lone opening) or `e` (a lone closing)."
          },
          "code": {
            "type": "string",
            "description": "What the format writes for it, if known (`<b>`, `<br>`, `**`)."
          }
        },
        "type": "object",
        "required": [
          "n",
          "kind",
          "code"
        ],
        "description": "A formatting mark of a sentence (`<g1>…</g1>`, `<x1/>`)."
      },
      "TranslateRequest": {
        "properties": {
          "source_lang": {
            "type": "string",
            "description": "The language of the segments. BCP 47 code: `es`, `en`, `pt-BR`…"
          },
          "target_lang": {
            "type": "string",
            "description": "The language to translate into. Not the same as `source_lang`. BCP 47 code: `es`, `en`, `pt-BR`…"
          },
          "segments": {
            "items": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 2000,
                  "minLength": 1
                },
                {
                  "$ref": "#/components/schemas/PostEditSegment"
                }
              ]
            },
            "type": "array",
            "maxItems": 50,
            "minItems": 1,
            "description": "The sentences, one per item: a string to translate it, or `{source, target}` to post-edit the translation you send. Up to 10,000 characters in total."
          },
          "glossary": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/GlossaryTerm"
                },
                "type": "array",
                "maxItems": 500
              },
              {
                "type": "null"
              }
            ],
            "description": "Terms to apply in this request only, on top of the saved glossaries."
          },
          "model_id": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 64
              },
              {
                "type": "null"
              }
            ],
            "description": "A model of your own, if you have one trained. Leave it out to use the standard engine."
          },
          "qe": {
            "type": "boolean",
            "default": true,
            "description": "Whether to score each translation. With `false`, `score` is `null` and `band` is `sin-nota`."
          },
          "memory_ids": {
            "items": {
              "type": "string",
              "maxLength": 128,
              "minLength": 1
            },
            "type": "array",
            "maxItems": 20,
            "description": "Saved translation memories to use (`tm_…`). They must cover this language pair."
          },
          "glossary_ids": {
            "items": {
              "type": "string",
              "maxLength": 128,
              "minLength": 1
            },
            "type": "array",
            "maxItems": 20,
            "description": "Saved glossaries to use (`gl_…`). They must cover this language pair."
          },
          "instructions": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000
              },
              {
                "type": "null"
              }
            ],
            "description": "Style instructions for the engine: register, language variant, tone. They take precedence over glossaries and memories."
          },
          "project_id": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 128,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "description": "A project (`prj_…`): its memories and glossaries for this language pair are used too."
          }
        },
        "type": "object",
        "required": [
          "source_lang",
          "target_lang",
          "segments"
        ]
      },
      "TranslateResponse": {
        "properties": {
          "source_lang": {
            "type": "string",
            "description": "The source language of the request."
          },
          "target_lang": {
            "type": "string",
            "description": "The target language of the request."
          },
          "model_version": {
            "type": "string",
            "description": "The version of the engine that translated."
          },
          "qe_version": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The version of the scorer; `null` if nothing was scored."
          },
          "segments": {
            "items": {
              "$ref": "#/components/schemas/TranslatedSegment"
            },
            "type": "array",
            "description": "One per segment sent, in the same order."
          }
        },
        "type": "object",
        "required": [
          "source_lang",
          "target_lang",
          "model_version",
          "qe_version",
          "segments"
        ]
      },
      "TranslatedSegment": {
        "properties": {
          "index": {
            "type": "integer",
            "description": "The position of the segment in the request, from 0."
          },
          "source": {
            "type": "string",
            "description": "The sentence that was sent."
          },
          "target": {
            "type": "string",
            "description": "Its translation."
          },
          "origin": {
            "type": "string",
            "enum": [
              "engine",
              "memory"
            ],
            "description": "Where the translation comes from: the `engine`, or a translation `memory`."
          },
          "score": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 100.0,
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "description": "Quality score from 0 (worst) to 100 (best); `null` if there is no score."
          },
          "band": {
            "type": "string",
            "enum": [
              "fiable",
              "revisar",
              "rehacer",
              "sin-nota"
            ],
            "description": "Quality band: `fiable` (reliable: use it as it is), `revisar` (worth a review), `rehacer` (translate it again) or `sin-nota` (no score for this language pair)."
          },
          "applied_terms": {
            "items": {
              "$ref": "#/components/schemas/GlossaryTerm"
            },
            "type": "array",
            "description": "The glossary terms that were applied in this segment."
          },
          "checks": {
            "items": {
              "$ref": "#/components/schemas/QeCheck"
            },
            "type": "array",
            "description": "The automatic checks the translation did not pass. Empty if it passed them all."
          },
          "status": {
            "type": "string",
            "enum": [
              "translated",
              "post_edited",
              "matched",
              "repeated",
              "untranslatable"
            ],
            "description": "`translated` (by the engine), `post_edited` (the translation you sent, corrected), `matched` (taken from a memory), `repeated` (already translated for your organisation: reused) or `untranslatable` (nothing to translate: returned as it came)."
          },
          "changed": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only when post-editing: whether the translation you sent was changed."
          },
          "explanation": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only when post-editing: what was corrected."
          }
        },
        "type": "object",
        "required": [
          "index",
          "source",
          "target",
          "origin",
          "score",
          "band",
          "applied_terms",
          "checks",
          "status"
        ]
      },
      "UsageResponse": {
        "properties": {
          "granularity": {
            "type": "string",
            "enum": [
              "hour",
              "day"
            ],
            "description": "The size of each period."
          },
          "group_by": {
            "type": "string",
            "enum": [
              "none",
              "kind",
              "model",
              "pair",
              "profile",
              "channel",
              "mode"
            ],
            "description": "What each period is split by."
          },
          "rows": {
            "items": {
              "$ref": "#/components/schemas/UsageRow"
            },
            "type": "array",
            "description": "One row per period and group, oldest first."
          }
        },
        "type": "object",
        "required": [
          "granularity",
          "group_by",
          "rows"
        ]
      },
      "UsageRow": {
        "properties": {
          "period": {
            "type": "string",
            "description": "The start of the day or of the hour (UTC)."
          },
          "group": {
            "type": "string",
            "description": "The value of the group (a kind, a language pair…); empty if nothing is grouped."
          },
          "requests": {
            "type": "integer",
            "description": "Requests."
          },
          "segments": {
            "type": "integer",
            "description": "Sentences translated or scored."
          },
          "characters": {
            "type": "integer",
            "description": "Characters of the source."
          },
          "words": {
            "type": "integer",
            "description": "Words of the source."
          },
          "average_score": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "The average score; `null` if nothing was scored."
          },
          "low_scores": {
            "type": "integer",
            "description": "Sentences with a score under 60."
          }
        },
        "type": "object",
        "required": [
          "period",
          "group",
          "requests",
          "segments",
          "characters",
          "words",
          "average_score",
          "low_scores"
        ]
      }
    },
    "securitySchemes": {
      "ApiKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "Your API key, as a bearer token: `Authorization: Bearer tq_live_…`. Keys are created in the TranslaQE web app. A `tq_test_…` key works the same and its usage is counted apart."
      }
    }
  }
}
