{
    "openapi": "3.1.0",
    "info": {
        "title": "TriExpert Translations API",
        "version": "1.0.0",
        "summary": "Certified translation pricing and document verification.",
        "description": "Read-only public API of TriExpert Translations (TriExpert Services LLC, Tampa, Florida).\n\nTwo jobs it is good for:\n\n1. **Quote a certified translation** before sending anyone to a form — `GET /quote`.\n2. **Check whether a certified translation is genuine** from the code printed on it — `GET /verify/{code}`.\n   Its QR, ready to print on the document, is at `GET /qr/{code}`.\n\nNo authentication and no API key. Rate limited to 60 requests per 10 minutes per IP on each endpoint.\n\n3. **Prepare an order** for the customer to confirm — `POST /orders/draft`.\n\nThat last one orders nothing by itself. It returns a `confirm_url`; the order exists when the customer opens it,\nattaches the document and accepts the terms. Documents are never accepted through this API: a certified translation\nis made from an official record, and handing someone else's passport to a third-party endpoint is not a convenience\nworth having. The form remains available: https://traduccionestriexpert.com/request/",
        "contact": {
            "name": "TriExpert Services LLC",
            "email": "support@triexpertservice.com",
            "url": "https://traduccionestriexpert.com/developers/"
        },
        "license": {
            "name": "Public read-only endpoints, no licence required for use"
        }
    },
    "servers": [
        {
            "url": "https://traduccionestriexpert.com/wp-json/triexpert/v1",
            "description": "Production"
        }
    ],
    "paths": {
        "/orders/draft": {
            "post": {
                "operationId": "prepareOrder",
                "summary": "Prepare a certified translation order for the customer to confirm",
                "description": "Prepares an order from the customer details and returns the quote plus a confirmation URL.\n\n**It orders nothing.** No TX code is issued and no email is sent. The order is created when the customer\nopens `confirm_url`, attaches the document and accepts the terms, in a browser.\n\nThe document is not a parameter here and will not be. Accepting the terms also produces a consent record\nstamped with the IP of whoever accepted, which is only meaningful if that is the customer.\n\nNo authentication. Rate limited per IP.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "nombre",
                                    "email",
                                    "idioma_origen",
                                    "idioma_destino",
                                    "paginas"
                                ],
                                "properties": {
                                    "nombre": {
                                        "type": "string",
                                        "description": "Full name, at least two words."
                                    },
                                    "email": {
                                        "type": "string",
                                        "format": "email"
                                    },
                                    "telefono": {
                                        "type": "string"
                                    },
                                    "idioma_origen": {
                                        "type": "string",
                                        "enum": [
                                            "English",
                                            "Español",
                                            "Português"
                                        ],
                                        "description": "One of: \"English\", \"Español\", \"Português\"."
                                    },
                                    "idioma_destino": {
                                        "type": "string",
                                        "enum": [
                                            "English",
                                            "Español",
                                            "Português"
                                        ],
                                        "description": "One of: \"English\", \"Español\", \"Português\"."
                                    },
                                    "tipo_documento": {
                                        "type": "string"
                                    },
                                    "paginas": {
                                        "type": "integer",
                                        "minimum": 1,
                                        "maximum": 999
                                    },
                                    "urgencia": {
                                        "type": "string",
                                        "enum": [
                                            "standard",
                                            "urgent"
                                        ]
                                    },
                                    "formato": {
                                        "type": "string",
                                        "enum": [
                                            "digital",
                                            "physical",
                                            "both"
                                        ]
                                    },
                                    "instrucciones": {
                                        "type": "string"
                                    },
                                    "lang": {
                                        "type": "string",
                                        "enum": [
                                            "en",
                                            "es"
                                        ]
                                    }
                                }
                            },
                            "example": {
                                "nombre": "Ana Torres",
                                "email": "ana@example.com",
                                "idioma_origen": "Español",
                                "idioma_destino": "English",
                                "tipo_documento": "Birth certificate",
                                "paginas": 3,
                                "urgencia": "standard",
                                "formato": "digital",
                                "lang": "en"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Draft prepared. Nothing ordered yet.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                },
                                "example": {
                                    "status": "draft",
                                    "order_created": false,
                                    "confirm_url": "https://traduccionestriexpert.com/confirm-order/{token}/",
                                    "expires_at": "2026-10-13T13:51:16+00:00"
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/DraftInvalid"
                    },
                    "429": {
                        "$ref": "#/components/responses/DraftRateLimited"
                    }
                }
            }
        },
        "/rates": {
            "get": {
                "operationId": "getRates",
                "summary": "Current price list and the formula used to compute a quote",
                "description": "Returns the base per-page rate and the multipliers, so a caller can reproduce the pricing locally.",
                "responses": {
                    "200": {
                        "description": "The current rates.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                },
                                "example": {
                                    "currency": "USD",
                                    "base_price_per_page": 15,
                                    "words_per_page": 250,
                                    "rush_multiplier": 1.35,
                                    "both_formats_multiplier": 1.2,
                                    "formula": "ceil( ceil( pages * base * rush ) * both )"
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "500": {
                        "$ref": "#/components/responses/ServerError"
                    }
                }
            }
        },
        "/quote": {
            "get": {
                "operationId": "getQuote",
                "summary": "Estimate the price of a certified translation",
                "description": "A page is 250 words. The estimate is not binding: the firm price is set once the document is received and its real pages counted.",
                "parameters": [
                    {
                        "name": "pages",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 999
                        },
                        "example": 3
                    },
                    {
                        "name": "processing",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "standard",
                                "urgent"
                            ],
                            "default": "standard"
                        },
                        "example": "standard"
                    },
                    {
                        "name": "format",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "digital",
                                "physical",
                                "both"
                            ],
                            "default": "digital"
                        },
                        "example": "digital"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The estimate.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                },
                                "example": {
                                    "currency": "USD",
                                    "total": 45,
                                    "pages": 3,
                                    "processing": "standard",
                                    "format": "digital",
                                    "binding": false
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    },
                    "500": {
                        "$ref": "#/components/responses/ServerError"
                    }
                }
            }
        },
        "/verify/{code}": {
            "get": {
                "operationId": "verifyDocument",
                "summary": "Check whether a certified translation was issued by TriExpert",
                "description": "Every certified translation carries a printed code (TX-XXXX-XXXX) and a QR. The check is public, never expires and reveals no personal data about the customer. An unrecognised code answers 200 with status \"unknown\" — the question was answered, so it is not a 404.",
                "parameters": [
                    {
                        "name": "code",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "^TX-[A-Z0-9]{4}-[A-Z0-9]{4}$"
                        },
                        "example": "TX-4F2A-9C31"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The verification result. Read the \"status\" field: authentic, in_progress, cancelled or unknown.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                },
                                "example": {
                                    "code": "TX-4F2A-9C31",
                                    "status": "authentic",
                                    "issued_on": "2026-08-14",
                                    "source_language": "Spanish",
                                    "target_language": "English",
                                    "pages": 3,
                                    "fingerprints": [
                                        {
                                            "filename": "birth-certificate.pdf",
                                            "sha256": "e3b0c442…"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    },
                    "500": {
                        "$ref": "#/components/responses/ServerError"
                    }
                }
            }
        },
        "/qr/{code}": {
            "get": {
                "operationId": "getVerificationQr",
                "summary": "The verification QR of an order, ready to print on the certified translation",
                "description": "Returns the image itself, not JSON. It is the same QR shown on the order in our back office: it encodes the\nEnglish verification page with the code in it (https://traduccionestriexpert.com/verify/?codigo=TX-XXXX-XXXX),\nbecause whoever scans it is the agency or university receiving the document, not the customer.\n\nOrders still in progress have a QR: the document is assembled before it is delivered.\n\n**Unlike `/verify/{code}`, an unknown code is a 404 and a cancelled order is a 410.** That endpoint answers a\nquestion; this one makes something that will be printed. A QR for a mistyped code scans fine and leads to\n\"not issued\", and nobody finds out until the document is in front of an official.\n\nKeep the white margin around the code: it is part of it, and most readers will not find a QR without it.\nResponses carry an ETag and `Cache-Control: public, max-age=86400`.",
                "parameters": [
                    {
                        "name": "code",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "^TX-[A-Z0-9]{4}-[A-Z0-9]{4}$"
                        },
                        "example": "TX-4F2A-9C31"
                    },
                    {
                        "name": "format",
                        "in": "query",
                        "required": false,
                        "description": "svg for the document (scales and prints without losing sharpness); png for tools that cannot take SVG.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "svg",
                                "png"
                            ],
                            "default": "svg"
                        }
                    },
                    {
                        "name": "scale",
                        "in": "query",
                        "required": false,
                        "description": "Pixels per module. Defaults to 4 for SVG and 12 for PNG.",
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 32
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The QR image.",
                        "headers": {
                            "ETag": {
                                "schema": {
                                    "type": "string"
                                }
                            },
                            "Content-Disposition": {
                                "description": "inline, with a file name built from the code: qr-TX-XXXX-XXXX.svg",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "image/svg+xml": {
                                "schema": {
                                    "type": "string"
                                }
                            },
                            "image/png": {
                                "schema": {
                                    "type": "string",
                                    "format": "binary"
                                }
                            }
                        }
                    },
                    "304": {
                        "description": "Not modified: the If-None-Match sent matches the current ETag."
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "404": {
                        "$ref": "#/components/responses/QrUnknownCode"
                    },
                    "410": {
                        "$ref": "#/components/responses/QrCancelled"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    },
                    "500": {
                        "$ref": "#/components/responses/ServerError"
                    }
                }
            }
        },
        "/orders/recent": {
            "get": {
                "operationId": "getRecentOrders",
                "summary": "The most recent orders, newest first",
                "description": "**Private.** Returns the orders with customer details: names, emails, phone numbers. This endpoint\nexists for the business tools (back office, the PDF assembler, WhatsApp), not for the public.\n\nIt requires the shared key, sent as Authorization: Bearer. The key is NOT in the settings of the\nwebsite; it is defined in wp-config.php. If you work for TriExpert and need it, ask\nsupport@triexpertservice.com.\n\nResponses are marked `Cache-Control: private, no-store`. Same rate limit as the rest of the API.",
                "security": [
                    {
                        "TriExpertKey": []
                    }
                ],
                "parameters": [
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "description": "How many orders, newest first. Between 1 and 50.",
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 50,
                            "default": 10
                        }
                    },
                    {
                        "name": "estado",
                        "in": "query",
                        "required": false,
                        "description": "Only orders in this state: recibido, traduccion, revision, certificacion, entregado, cancelada.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "recibido",
                                "traduccion",
                                "revision",
                                "certificacion",
                                "entregado",
                                "cancelada"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The most recent orders, newest first.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "count": {
                                            "type": "integer",
                                            "description": "How many orders are in this response."
                                        },
                                        "orders": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Order"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    },
                    "500": {
                        "$ref": "#/components/responses/ServerError"
                    }
                }
            }
        },
        "/orders/{code}/archivos": {
            "get": {
                "operationId": "getOrderFiles",
                "summary": "The documents of one order",
                "description": "**Private.** The originals the customer attached and the certified translations delivered\nfor this order: generated file name, original name, size, upload time, sha256 (deliveries)\nand whether retention has purged the bytes.\n\nRequires the shared key, sent as Authorization: Bearer. Same rate limit as the rest of the API.",
                "security": [
                    {
                        "TriExpertKey": []
                    }
                ],
                "parameters": [
                    {
                        "name": "code",
                        "in": "path",
                        "required": true,
                        "description": "The order code, TX-XXXX-XXXX.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The inventory of the order: originals and deliveries.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "codigo": {
                                            "type": "string",
                                            "description": "The order code, as issued."
                                        },
                                        "count": {
                                            "type": "integer",
                                            "description": "Total files of the order."
                                        },
                                        "originales": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Archivo"
                                            }
                                        },
                                        "entregas": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Archivo"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "404": {
                        "$ref": "#/components/responses/CodeUnknown"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    },
                    "500": {
                        "$ref": "#/components/responses/ServerError"
                    }
                }
            }
        },
        "/orders/{code}/archivos/{archivo}": {
            "get": {
                "operationId": "downloadOrderFile",
                "summary": "Download one document of an order",
                "description": "**Private.** The document is served as application/octet-stream with an attachment\nContent-Disposition carrying its original name. The name in the path is the GENERATED\none (900-ab12cd34ef56.pdf), as returned by GET /orders/{code}/archivos — not the name\nthe customer gave it. Files of other orders answer 404; files purged by retention\nanswer 410. Requires the shared key, sent as Authorization: Bearer.",
                "security": [
                    {
                        "TriExpertKey": []
                    }
                ],
                "parameters": [
                    {
                        "name": "code",
                        "in": "path",
                        "required": true,
                        "description": "The order code, TX-XXXX-XXXX.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "archivo",
                        "in": "path",
                        "required": true,
                        "description": "The generated file name, from the list endpoint.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The file bytes, application/octet-stream.",
                        "content": {
                            "application/octet-stream": {
                                "schema": {
                                    "type": "string",
                                    "format": "binary"
                                }
                            }
                        }
                    },
                    "304": {
                        "description": "Not modified: the If-None-Match sent matches the current ETag."
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "404": {
                        "$ref": "#/components/responses/ArchivoAjeno"
                    },
                    "410": {
                        "$ref": "#/components/responses/ArchivoPurgado"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    },
                    "500": {
                        "$ref": "#/components/responses/ServerError"
                    }
                }
            }
        },
        "/orders/{code}/entregas": {
            "post": {
                "operationId": "uploadOrderDelivery",
                "summary": "Upload the finished certified translation of an order",
                "description": "**Private.** The translated document goes in the REQUEST BODY (up to 15 MB); its file name\ngoes in ?nombre= or in the X-Filename header. Accepted types: pdf, jpg, jpeg, png, webp,\ndoc, docx. The stored file gets a generated name (e900-ab12cd34ef56.pdf), is recorded with\nits sha256 (so the verification page shows it) and, if the order is already marked as\ndelivered, the customer is notified exactly as with a panel upload.\n\nA cancelled order accepts no deliveries: 410, as on /qr/{code}.\n\nRequires the shared key, sent as Authorization: Bearer.",
                "security": [
                    {
                        "TriExpertKey": []
                    }
                ],
                "parameters": [
                    {
                        "name": "code",
                        "in": "path",
                        "required": true,
                        "description": "The order code, TX-XXXX-XXXX.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "nombre",
                        "in": "query",
                        "required": false,
                        "description": "The file name of the translated document, with its extension. Also accepted as the X-Filename header.",
                        "schema": {
                            "type": "string",
                            "example": "acta-traducida.pdf"
                        }
                    }
                ],
                "responses": {
                    "201": {
                        "description": "The document was stored and recorded.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "guardado": {
                                            "type": "boolean",
                                            "description": "Always true on success."
                                        },
                                        "archivo": {
                                            "type": "string",
                                            "description": "The generated file name."
                                        },
                                        "sha256": {
                                            "type": "string",
                                            "description": "The fingerprint shown on the verification page."
                                        },
                                        "bytes": {
                                            "type": "integer",
                                            "description": "How many bytes were stored."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/UploadInvalid"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "404": {
                        "$ref": "#/components/responses/CodeUnknown"
                    },
                    "410": {
                        "$ref": "#/components/responses/QrCancelled"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    },
                    "500": {
                        "$ref": "#/components/responses/ServerError"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "Problem": {
                "type": "object",
                "title": "Problem",
                "description": "Error object as defined by RFC 9457 (Problem Details for HTTP APIs), served as application/problem+json. Branch on \"code\"; show \"detail\" to a person; act on \"resolution\".",
                "required": [
                    "type",
                    "title",
                    "status",
                    "detail",
                    "code",
                    "resolution"
                ],
                "properties": {
                    "type": {
                        "type": "string",
                        "format": "uri",
                        "description": "URI identifying the problem type. Stable per error kind."
                    },
                    "title": {
                        "type": "string",
                        "description": "Short, human-readable summary. Does not change between occurrences of the same type."
                    },
                    "status": {
                        "type": "integer",
                        "description": "The HTTP status code, repeated inside the body.",
                        "minimum": 400,
                        "maximum": 599
                    },
                    "detail": {
                        "type": "string",
                        "description": "What went wrong with this particular request."
                    },
                    "instance": {
                        "type": "string",
                        "format": "uri",
                        "description": "The URI that produced the error."
                    },
                    "code": {
                        "type": "string",
                        "description": "Machine-readable error code. Branch on this, not on the message.",
                        "enum": [
                            "rest_missing_callback_param",
                            "rest_invalid_param",
                            "rest_no_route",
                            "tx_invalid",
                            "tx_rate",
                            "tx_not_api",
                            "tx_method_not_allowed",
                            "tx_rate_limited",
                            "tx_code_unknown",
                            "tx_code_cancelled",
                            "tx_ordenes_no_auth",
                            "tx_ordenes_sin_clave",
                            "tx_archivo_ajeno",
                            "tx_archivo_purgado",
                            "tx_entregas_nombre",
                            "tx_entregas_vacia",
                            "tx_upload",
                            "tx_internal"
                        ]
                    },
                    "resolution": {
                        "type": "string",
                        "description": "What to do about it. Actionable, not a restatement of the title."
                    },
                    "documentation": {
                        "type": "string",
                        "format": "uri",
                        "description": "Where to read more."
                    },
                    "errors": {
                        "type": "object",
                        "description": "Optional per-parameter detail, when the failure was about parameters.",
                        "additionalProperties": true
                    }
                }
            },
            "Order": {
                "type": "object",
                "title": "Order",
                "description": "One order, with the customer details. Served only behind the shared key of /orders/recent.",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "creada": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "nombre": {
                        "type": "string"
                    },
                    "email": {
                        "type": "string",
                        "format": "email"
                    },
                    "telefono": {
                        "type": "string"
                    },
                    "idioma_origen": {
                        "type": "string"
                    },
                    "idioma_destino": {
                        "type": "string"
                    },
                    "tipo_documento": {
                        "type": "string"
                    },
                    "paginas": {
                        "type": "integer"
                    },
                    "urgencia": {
                        "type": "string",
                        "enum": [
                            "standard",
                            "urgent"
                        ]
                    },
                    "formato": {
                        "type": "string",
                        "enum": [
                            "digital",
                            "physical",
                            "both"
                        ]
                    },
                    "instrucciones": {
                        "type": "string"
                    },
                    "estado": {
                        "type": "string"
                    },
                    "total": {
                        "type": "integer"
                    },
                    "codigo": {
                        "type": "string"
                    }
                }
            },
            "Archivo": {
                "type": "object",
                "title": "Archivo",
                "description": "One document of an order, as listed by GET /orders/{code}/archivos. Served only behind the shared key.",
                "properties": {
                    "archivo": {
                        "type": "string",
                        "description": "The generated file name. This is what the download endpoint wants in its path."
                    },
                    "original": {
                        "type": "string",
                        "description": "The file name as the customer gave it."
                    },
                    "bytes": {
                        "type": "integer",
                        "description": "Size in bytes."
                    },
                    "subido": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "sha256": {
                        "type": "string",
                        "description": "Fingerprint (deliveries only; empty for originals)."
                    },
                    "purgado": {
                        "type": "boolean",
                        "description": "True when retention already deleted the bytes: the record remains, the file answers 410."
                    }
                }
            }
        },
        "securitySchemes": {
            "TriExpertKey": {
                "type": "http",
                "scheme": "bearer",
                "description": "Shared key for the private endpoints: /orders/recent, /orders/{code}/archivos, /orders/{code}/archivos/{archivo} and /orders/{code}/entregas. Sent in the Authorization header, Bearer scheme."
            }
        },
        "responses": {
            "BadRequest": {
                "description": "The request was malformed: a required parameter is missing, or one of them is out of range. Served as application/problem+json.",
                "content": {
                    "application/problem+json": {
                        "schema": {
                            "$ref": "#/components/schemas/Problem"
                        },
                        "example": {
                            "type": "https://traduccionestriexpert.com/developers/#errors-rest_invalid_param",
                            "title": "Un parámetro no vale",
                            "status": 400,
                            "detail": "Invalid parameter(s): pages",
                            "instance": "https://traduccionestriexpert.com/wp-json/triexpert/v1/quote",
                            "code": "rest_invalid_param",
                            "resolution": "pages is an integer between 1 and 999; processing is standard or urgent; format is digital, physical or both.",
                            "documentation": "https://traduccionestriexpert.com/developers/"
                        }
                    }
                }
            },
            "NotFound": {
                "description": "No endpoint matches that URL. Note that an unrecognised verification code is NOT a 404: it answers 200 with status \"unknown\".",
                "content": {
                    "application/problem+json": {
                        "schema": {
                            "$ref": "#/components/schemas/Problem"
                        },
                        "example": {
                            "type": "https://traduccionestriexpert.com/developers/#errors-rest_no_route",
                            "title": "Ese endpoint no existe",
                            "status": 404,
                            "detail": "No route was found matching the URL and request method.",
                            "instance": "https://traduccionestriexpert.com/wp-json/triexpert/v1/quote",
                            "code": "rest_no_route",
                            "resolution": "The API base URL is https://traduccionestriexpert.com/wp-json/triexpert/v1. The full list of endpoints is in /openapi.json.",
                            "documentation": "https://traduccionestriexpert.com/developers/"
                        }
                    }
                }
            },
            "TooManyRequests": {
                "description": "Rate limit exceeded: 60 requests per 10 minutes, per IP, per endpoint.",
                "content": {
                    "application/problem+json": {
                        "schema": {
                            "$ref": "#/components/schemas/Problem"
                        },
                        "example": {
                            "type": "https://traduccionestriexpert.com/developers/#errors-tx_rate_limited",
                            "title": "Demasiadas peticiones",
                            "status": 429,
                            "detail": "Too many requests from this address.",
                            "instance": "https://traduccionestriexpert.com/wp-json/triexpert/v1/quote",
                            "code": "tx_rate_limited",
                            "resolution": "Wait a few minutes and retry. If you need more headroom, write to support@triexpertservice.com.",
                            "documentation": "https://traduccionestriexpert.com/developers/"
                        }
                    }
                }
            },
            "DraftInvalid": {
                "description": "A draft field is missing or did not validate. errors.field names it and errors.hint says what it expects. Served as application/problem+json.",
                "content": {
                    "application/problem+json": {
                        "schema": {
                            "$ref": "#/components/schemas/Problem"
                        },
                        "example": {
                            "type": "https://traduccionestriexpert.com/developers/#errors-tx_invalid",
                            "title": "Falta un campo del borrador o no vale",
                            "status": 400,
                            "detail": "Field missing or invalid: email",
                            "instance": "https://traduccionestriexpert.com/wp-json/triexpert/v1/quote",
                            "code": "tx_invalid",
                            "resolution": "The failing field is in errors.field, with a hint in errors.hint. Draft fields and their formats are in /openapi.json.",
                            "documentation": "https://traduccionestriexpert.com/developers/"
                        }
                    }
                }
            },
            "DraftRateLimited": {
                "description": "Too many drafts: 12 per hour from each address.",
                "content": {
                    "application/problem+json": {
                        "schema": {
                            "$ref": "#/components/schemas/Problem"
                        },
                        "example": {
                            "type": "https://traduccionestriexpert.com/developers/#errors-tx_rate",
                            "title": "Demasiados borradores",
                            "status": 429,
                            "detail": "Too many drafts from this address. Wait an hour.",
                            "instance": "https://traduccionestriexpert.com/wp-json/triexpert/v1/quote",
                            "code": "tx_rate",
                            "resolution": "Wait and retry; if you need more headroom, write to support@triexpertservice.com.",
                            "documentation": "https://traduccionestriexpert.com/developers/"
                        }
                    }
                }
            },
            "QrUnknownCode": {
                "description": "No order carries that code, so there is no QR to make. Only /qr answers 404 for this: /verify answers 200 with status \"unknown\".",
                "content": {
                    "application/problem+json": {
                        "schema": {
                            "$ref": "#/components/schemas/Problem"
                        },
                        "example": {
                            "type": "https://traduccionestriexpert.com/developers/#errors-tx_code_unknown",
                            "title": "Código desconocido",
                            "status": 404,
                            "detail": "We have not issued any order with this code.",
                            "instance": "https://traduccionestriexpert.com/wp-json/triexpert/v1/quote",
                            "code": "tx_code_unknown",
                            "resolution": "Check the code: it is the one in the order confirmation, formatted TX-XXXX-XXXX. No QR is made for a code we did not issue, so one that does not verify never ends up printed.",
                            "documentation": "https://traduccionestriexpert.com/developers/"
                        }
                    }
                }
            },
            "QrCancelled": {
                "description": "The order was cancelled and no document will be issued with its code: there is no QR to print and no delivery to upload.",
                "content": {
                    "application/problem+json": {
                        "schema": {
                            "$ref": "#/components/schemas/Problem"
                        },
                        "example": {
                            "type": "https://traduccionestriexpert.com/developers/#errors-tx_code_cancelled",
                            "title": "Encargo cancelado",
                            "status": 410,
                            "detail": "The order with this code was cancelled: no document will be issued with it.",
                            "instance": "https://traduccionestriexpert.com/wp-json/triexpert/v1/quote",
                            "code": "tx_code_cancelled",
                            "resolution": "A cancelled order has no QR to print and accepts no deliveries. If this is a mistake, write to support@triexpertservice.com.",
                            "documentation": "https://traduccionestriexpert.com/developers/"
                        }
                    }
                }
            },
            "Unauthorized": {
                "description": "This endpoint is private to TriExpert: it returns customer names, emails and phone numbers. It requires the shared key in the Authorization header, Bearer scheme.",
                "content": {
                    "application/problem+json": {
                        "schema": {
                            "$ref": "#/components/schemas/Problem"
                        },
                        "example": {
                            "type": "https://traduccionestriexpert.com/developers/#errors-tx_ordenes_no_auth",
                            "title": "Hace falta la clave",
                            "status": 401,
                            "detail": "This list is only for TriExpert: send the shared key as Authorization: Bearer.",
                            "instance": "https://traduccionestriexpert.com/wp-json/triexpert/v1/quote",
                            "code": "tx_ordenes_no_auth",
                            "resolution": "Add the shared key to the request. If you work for TriExpert and do not have it, ask support@triexpertservice.com.",
                            "documentation": "https://traduccionestriexpert.com/developers/"
                        }
                    }
                }
            },
            "CodeUnknown": {
                "description": "The code is not in any order. /verify answers 200 with status \"unknown\" to this same code; these endpoints answer 404 because they act on the order, not on a question about it.",
                "content": {
                    "application/problem+json": {
                        "schema": {
                            "$ref": "#/components/schemas/Problem"
                        },
                        "example": {
                            "type": "https://traduccionestriexpert.com/developers/#errors-tx_code_unknown",
                            "title": "Código desconocido",
                            "status": 404,
                            "detail": "We have not issued any order with this code.",
                            "instance": "https://traduccionestriexpert.com/wp-json/triexpert/v1/quote",
                            "code": "tx_code_unknown",
                            "resolution": "Check the code: it is the one in the order confirmation, formatted TX-XXXX-XXXX.",
                            "documentation": "https://traduccionestriexpert.com/developers/"
                        }
                    }
                }
            },
            "ArchivoAjeno": {
                "description": "That file name is not in this order. Names are generated (900-ab12cd34ef56.pdf) and can only be downloaded within their own order.",
                "content": {
                    "application/problem+json": {
                        "schema": {
                            "$ref": "#/components/schemas/Problem"
                        },
                        "example": {
                            "type": "https://traduccionestriexpert.com/developers/#errors-tx_archivo_ajeno",
                            "title": "Ese archivo no está en este encargo",
                            "status": 404,
                            "detail": "That file is not in this order.",
                            "instance": "https://traduccionestriexpert.com/wp-json/triexpert/v1/quote",
                            "code": "tx_archivo_ajeno",
                            "resolution": "The exact name comes from GET /orders/{code}/archivos. Files only download inside the order they belong to.",
                            "documentation": "https://traduccionestriexpert.com/developers/"
                        }
                    }
                }
            },
            "ArchivoPurgado": {
                "description": "Document retention deleted the bytes of this file: its record and its hash remain, the download does not.",
                "content": {
                    "application/problem+json": {
                        "schema": {
                            "$ref": "#/components/schemas/Problem"
                        },
                        "example": {
                            "type": "https://traduccionestriexpert.com/developers/#errors-tx_archivo_purgado",
                            "title": "Archivo borrado por retención",
                            "status": 410,
                            "detail": "This file was deleted by document retention.",
                            "instance": "https://traduccionestriexpert.com/wp-json/triexpert/v1/quote",
                            "code": "tx_archivo_purgado",
                            "resolution": "The record and its fingerprint remain in the history, but the bytes are gone for good.",
                            "documentation": "https://traduccionestriexpert.com/developers/"
                        }
                    }
                }
            },
            "UploadInvalid": {
                "description": "The document was not stored: the file name is missing, the body is empty, the extension is not accepted, the content does not match the extension, or it is over 15 MB.",
                "content": {
                    "application/problem+json": {
                        "schema": {
                            "$ref": "#/components/schemas/Problem"
                        },
                        "example": {
                            "type": "https://traduccionestriexpert.com/developers/#errors-tx_upload",
                            "title": "El archivo no se aceptó",
                            "status": 400,
                            "detail": "The content of «traduccion.exe» does not match its extension.",
                            "instance": "https://traduccionestriexpert.com/wp-json/triexpert/v1/quote",
                            "code": "tx_upload",
                            "resolution": "Accepted extensions: pdf, jpg, jpeg, png, webp, doc, docx. Content must match them, and stay under 15 MB.",
                            "documentation": "https://traduccionestriexpert.com/developers/"
                        }
                    }
                }
            },
            "ServerError": {
                "description": "Something failed on our side. Not caused by the request.",
                "content": {
                    "application/problem+json": {
                        "schema": {
                            "$ref": "#/components/schemas/Problem"
                        },
                        "example": {
                            "type": "https://traduccionestriexpert.com/developers/#errors-tx_internal",
                            "title": "Error del servidor",
                            "status": 500,
                            "detail": "The request could not be completed.",
                            "instance": "https://traduccionestriexpert.com/wp-json/triexpert/v1/quote",
                            "code": "tx_internal",
                            "resolution": "Retry in a few minutes; if it persists, write to support@triexpertservice.com with the URL and the time.",
                            "documentation": "https://traduccionestriexpert.com/developers/"
                        }
                    }
                }
            }
        }
    }
}