{
  "openapi": "3.1.0",
  "info": {
    "title": "Redacto API: тестовая среда",
    "version": "1.0.0",
    "summary": "HTTP API для синтетической проверки движка Redacto.",
    "description": "Размещенная тестовая среда предназначена только для синтетических тестовых данных из опубликованного списка разрешенных значений. Sandbox API key контур отклоняет распознанные чувствительные значения вне этого словаря. Не отправляйте реальные персональные данные, реальные документы, реальные JWT и реальные словари восстановления."
  },
  "servers": [
    {
      "url": "https://sandbox-api.redactoapp.ru",
      "description": "Размещенная тестовая среда API"
    }
  ],
  "tags": [
    {
      "name": "Сервис",
      "description": "Служебные проверки процесса и готовности среды выполнения."
    },
    {
      "name": "Каталог",
      "description": "Каталог поддерживаемых типов сущностей для `policy.entityTypes`."
    },
    {
      "name": "Текст",
      "description": "Анонимизация и восстановление текста."
    },
    {
      "name": "Файлы",
      "description": "Синхронная обработка файлов."
    },
    {
      "name": "Фоновые задачи (выключены в тестовой среде)",
      "description": "Маршруты `/v1/jobs/*` показаны для корпоративных сценариев, но в публичной тестовой среде выключены по умолчанию. Для быстрого старта используйте `/v1/anonymize/file` и `/v1/restore/file`."
    }
  ],
  "paths": {
    "/healthz": {
      "get": {
        "tags": [
          "Сервис"
        ],
        "summary": "Проверка состояния процесса",
        "security": [],
        "responses": {
          "200": {
            "description": "Процесс отвечает.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OkResponse"
                }
              }
            }
          }
        }
      }
    },
    "/readyz": {
      "get": {
        "tags": [
          "Сервис"
        ],
        "summary": "Готовность среды выполнения",
        "security": [],
        "responses": {
          "200": {
            "description": "Среда выполнения готова к обработке запросов.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OkResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/entity-types": {
      "get": {
        "tags": [
          "Каталог"
        ],
        "summary": "Получить каталог сущностей",
        "description": "Публичный endpoint каталога без авторизации и без расхода квоты. Возвращает допустимые значения для `policy.entityTypes`, русские и английские названия, группы интерфейса, набор по умолчанию, обязательные серверные типы и синтетические значения, разрешенные в размещенной тестовой среде.",
        "security": [],
        "responses": {
          "200": {
            "description": "Каталог поддерживаемых сущностей.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EntityTypeCatalogResponse"
                },
                "examples": {
                  "email": {
                    "summary": "Фрагмент каталога",
                    "value": {
                      "schemaVersion": 24,
                      "entityTypes": [
                        {
                          "type": "EMAIL",
                          "title": {
                            "ru": "Email",
                            "en": "Email"
                          },
                          "defaultEnabled": true,
                          "required": true,
                          "groups": [
                            "common.contacts"
                          ],
                          "syntheticValues": [
                            "ivan.sintetov@synthetic.example.test",
                            "info@demo-org.example.test",
                            "billing@synthetic-bank.example.test",
                            "support@redacto-sandbox.example.test",
                            "kz-demo@synthetic.example.test"
                          ]
                        }
                      ],
                      "defaultEntityTypes": [
                        "PERSON",
                        "ORG",
                        "BANK",
                        "ADDRESS",
                        "EMAIL"
                      ],
                      "defaultDisabledEntityTypes": [
                        "CONTRACTNO"
                      ],
                      "requiredEntityTypes": [
                        "EMAIL"
                      ],
                      "syntheticDataVersion": 1
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/anonymize/text": {
      "post": {
        "tags": [
          "Текст"
        ],
        "summary": "Анонимизировать текст",
        "security": [
          {
            "SandboxBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AnonymizeTextRequest"
              },
              "examples": {
                "email": {
                  "summary": "Синтетический email",
                  "value": {
                    "text": "Тестовый контакт support@redacto-sandbox.example.test",
                    "enableNer": false
                  }
                },
                "emailPhoneAllowlist": {
                  "summary": "Обрабатывать только EMAIL и PHONE",
                  "value": {
                    "text": "Почта support@redacto-sandbox.example.test, телефон +7 (111) 111-11-11, ИНН 9901000002",
                    "enableNer": false,
                    "policy": {
                      "entityTypes": [
                        "EMAIL",
                        "PHONE"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Текст замаскирован.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnonymizeTextResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/AuthRequiredOrRejected"
          },
          "403": {
            "$ref": "#/components/responses/ScopeRequired"
          },
          "413": {
            "$ref": "#/components/responses/BodyTooLarge"
          },
          "429": {
            "$ref": "#/components/responses/QuotaExceeded"
          }
        },
        "description": "В размещенной тестовой среде распознанные чувствительные значения должны входить в синтетический словарь из `GET /v1/entity-types`; иначе endpoint возвращает `400 synthetic_data_required`."
      }
    },
    "/v1/restore/text": {
      "post": {
        "tags": [
          "Текст"
        ],
        "summary": "Восстановить текст",
        "security": [
          {
            "SandboxBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RestoreTextRequest"
              },
              "examples": {
                "email": {
                  "summary": "Синтетический email",
                  "value": {
                    "text": "Тестовый контакт [EMAIL_1]",
                    "dictionary": {
                      "version": 1,
                      "mapping": {
                        "[EMAIL_1]": "support@redacto-sandbox.example.test"
                      },
                      "generator": "Redacto",
                      "sourceFilename": "text.txt",
                      "maskedFilename": "text.sanitized.txt",
                      "encrypted": false
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Текст восстановлен.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RestoreTextResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/AuthRequiredOrRejected"
          },
          "403": {
            "$ref": "#/components/responses/ScopeRequired"
          },
          "413": {
            "$ref": "#/components/responses/BodyTooLarge"
          },
          "429": {
            "$ref": "#/components/responses/QuotaExceeded"
          }
        },
        "description": "В размещенной тестовой среде распознанные чувствительные значения должны входить в синтетический словарь из `GET /v1/entity-types`; иначе endpoint возвращает `400 synthetic_data_required`."
      }
    },
    "/v1/anonymize/file": {
      "post": {
        "tags": [
          "Файлы"
        ],
        "summary": "Анонимизировать файл синхронно",
        "description": "Поддерживаются `.txt`, `.csv`, `.docx`, `.xlsx`, `.pptx`. Ответ всегда ZIP с анонимизированным файлом и `*.dict.json`. В размещенной тестовой среде распознанные чувствительные значения должны входить в синтетический словарь из `GET /v1/entity-types`; иначе endpoint возвращает `400 synthetic_data_required`.",
        "security": [
          {
            "SandboxBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/AnonymizeFileMultipartRequest"
              },
              "examples": {
                "emailPhoneAllowlist": {
                  "summary": "Файл: обрабатывать только EMAIL и PHONE",
                  "value": {
                    "file": "<binary>",
                    "policy": "{\"entityTypes\":[\"EMAIL\",\"PHONE\"]}"
                  }
                }
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AnonymizeFileJsonRequest"
              },
              "examples": {
                "emailOnly": {
                  "summary": "Файл: обрабатывать только EMAIL",
                  "value": {
                    "filename": "synthetic.txt",
                    "contentBase64": "0J/QvtGH0YLQsCBzeW50aGV0aWMtYnV5ZXJAZXhhbXBsZS50ZXN0",
                    "policy": {
                      "entityTypes": [
                        "EMAIL"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "ZIP с анонимизированным файлом и словарем восстановления.",
            "content": {
              "application/zip": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/AuthRequiredOrRejected"
          },
          "403": {
            "$ref": "#/components/responses/ScopeRequired"
          },
          "413": {
            "$ref": "#/components/responses/BodyTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedFormat"
          },
          "429": {
            "$ref": "#/components/responses/QuotaExceeded"
          }
        }
      }
    },
    "/v1/restore/file": {
      "post": {
        "tags": [
          "Файлы"
        ],
        "summary": "Восстановить файл",
        "security": [
          {
            "SandboxBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/RestoreFileMultipartRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RestoreFileJsonRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Восстановленный файл.",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/AuthRequiredOrRejected"
          },
          "403": {
            "$ref": "#/components/responses/ScopeRequired"
          },
          "413": {
            "$ref": "#/components/responses/BodyTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedFormat"
          },
          "429": {
            "$ref": "#/components/responses/QuotaExceeded"
          }
        },
        "description": "В размещенной тестовой среде распознанные чувствительные значения должны входить в синтетический словарь из `GET /v1/entity-types`; иначе endpoint возвращает `400 synthetic_data_required`."
      }
    },
    "/v1/jobs/anonymize-file": {
      "post": {
        "tags": [
          "Фоновые задачи (выключены в тестовой среде)"
        ],
        "summary": "Выключено в тестовой среде: создать фоновую задачу для анонимизации файла по запросу",
        "description": "Фоновая обработка предназначена для корпоративных сценариев с крупными Office-файлами или шлюзом с коротким временем ожидания HTTP-запроса. В публичной тестовой среде выключена по умолчанию и доступна по запросу; при выключенной серверной настройке API возвращает `403 feature_disabled`. В размещенной тестовой среде распознанные чувствительные значения должны входить в синтетический словарь из `GET /v1/entity-types`; иначе endpoint возвращает `400 synthetic_data_required`.",
        "security": [
          {
            "SandboxBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/AnonymizeFileMultipartRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AnonymizeFileJsonRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Фоновая задача создана.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobStatus"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/AuthRequiredOrRejected"
          },
          "403": {
            "$ref": "#/components/responses/JobFeatureDisabledOrScopeRequired"
          },
          "413": {
            "$ref": "#/components/responses/BodyTooLarge"
          },
          "415": {
            "$ref": "#/components/responses/UnsupportedFormat"
          },
          "429": {
            "$ref": "#/components/responses/QuotaExceeded"
          }
        }
      }
    },
    "/v1/jobs/{jobId}": {
      "get": {
        "tags": [
          "Фоновые задачи (выключены в тестовой среде)"
        ],
        "summary": "Выключено в тестовой среде: получить статус фоновой задачи по запросу",
        "description": "Endpoint работает только когда фоновые задачи включены по запросу. В публичной тестовой среде по умолчанию возвращает `403 feature_disabled`.",
        "security": [
          {
            "SandboxBearer": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/JobId"
          }
        ],
        "responses": {
          "200": {
            "description": "Текущий статус фоновой задачи.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobStatus"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/AuthRequiredOrRejected"
          },
          "403": {
            "$ref": "#/components/responses/JobFeatureDisabledOrScopeRequired"
          },
          "404": {
            "$ref": "#/components/responses/JobNotFound"
          },
          "429": {
            "$ref": "#/components/responses/QuotaExceeded"
          }
        }
      },
      "delete": {
        "tags": [
          "Фоновые задачи (выключены в тестовой среде)"
        ],
        "summary": "Выключено в тестовой среде: удалить фоновую задачу и временный результат по запросу",
        "description": "Endpoint работает только когда фоновые задачи включены по запросу. В публичной тестовой среде по умолчанию возвращает `403 feature_disabled`.",
        "security": [
          {
            "SandboxBearer": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/JobId"
          }
        ],
        "responses": {
          "200": {
            "description": "Фоновая задача удалена.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OkResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/AuthRequiredOrRejected"
          },
          "403": {
            "$ref": "#/components/responses/JobFeatureDisabledOrScopeRequired"
          },
          "404": {
            "$ref": "#/components/responses/JobNotFound"
          },
          "429": {
            "$ref": "#/components/responses/QuotaExceeded"
          }
        }
      }
    },
    "/v1/jobs/{jobId}/result": {
      "get": {
        "tags": [
          "Фоновые задачи (выключены в тестовой среде)"
        ],
        "summary": "Выключено в тестовой среде: скачать ZIP-результат фоновой задачи по запросу",
        "description": "Endpoint работает только когда фоновые задачи включены по запросу. В публичной тестовой среде по умолчанию возвращает `403 feature_disabled`. При включенном сценарии результат удаляется после успешного скачивания; `keep=1` допустим только для диагностики.",
        "security": [
          {
            "SandboxBearer": []
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/JobId"
          },
          {
            "name": "keep",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "1"
              ]
            },
            "description": "Оставить результат после скачивания для диагностики."
          }
        ],
        "responses": {
          "200": {
            "description": "ZIP с анонимизированным файлом и словарем восстановления.",
            "content": {
              "application/zip": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/AuthRequiredOrRejected"
          },
          "403": {
            "$ref": "#/components/responses/JobFeatureDisabledOrScopeRequired"
          },
          "404": {
            "$ref": "#/components/responses/JobNotFound"
          },
          "409": {
            "$ref": "#/components/responses/JobNotReady"
          },
          "429": {
            "$ref": "#/components/responses/QuotaExceeded"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "SandboxBearer": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "rdx_sbx_<keyId>_<secret>",
        "description": "API ключ тестовой среды, выданный через сценарий выдачи серверной частью. Ключ показывается один раз после подтверждения email."
      }
    },
    "parameters": {
      "JobId": {
        "name": "jobId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "pattern": "^job_[A-Za-z0-9_-]+$"
        },
        "example": "job_synthetic"
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Некорректный запрос.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "examples": {
              "badJson": {
                "value": {
                  "error": "bad_json"
                }
              },
              "syntheticDataRequired": {
                "value": {
                  "error": "synthetic_data_required"
                }
              }
            }
          }
        }
      },
      "AuthRequiredOrRejected": {
        "description": "Нет Bearer token, ключ поврежден, истек, отозван или не совпал хэш.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "examples": {
              "required": {
                "value": {
                  "error": "auth_required"
                }
              },
              "rejected": {
                "value": {
                  "error": "auth_rejected"
                }
              }
            }
          }
        }
      },
      "ScopeRequired": {
        "description": "Ключ валиден, но нет нужной области доступа.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "error": "scope_required"
            }
          }
        }
      },
      "JobFeatureDisabledOrScopeRequired": {
        "description": "Фоновые задачи выключены по умолчанию или у ключа нет нужной области доступа.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "examples": {
              "featureDisabled": {
                "value": {
                  "error": "feature_disabled"
                }
              },
              "scopeRequired": {
                "value": {
                  "error": "scope_required"
                }
              }
            }
          }
        }
      },
      "BodyTooLarge": {
        "description": "Тело запроса больше лимита тестовой среды.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "error": "body_too_large"
            }
          }
        }
      },
      "QuotaExceeded": {
        "description": "Превышен почасовой или общий лимит ключа.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "error": "quota_exceeded"
            }
          }
        }
      },
      "UnsupportedFormat": {
        "description": "Неподдерживаемый формат или Content-Type.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "examples": {
              "format": {
                "value": {
                  "error": "unsupported_format"
                }
              },
              "mediaType": {
                "value": {
                  "error": "unsupported_media_type"
                }
              }
            }
          }
        }
      },
      "JobNotFound": {
        "description": "Фоновая задача не найдена или уже удалена.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "error": "job_not_found"
            }
          }
        }
      },
      "JobNotReady": {
        "description": "Результат фоновой задачи еще не готов.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "error": "job_not_ready"
            }
          }
        }
      }
    },
    "schemas": {
      "OkResponse": {
        "type": "object",
        "required": [
          "ok"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string",
            "examples": [
              "auth_required",
              "scope_required",
              "quota_exceeded",
              "feature_disabled",
              "synthetic_data_required"
            ]
          }
        },
        "additionalProperties": false
      },
      "PolicyOverride": {
        "type": "object",
        "description": "Опциональная политика запроса поверх политики клиента. Итоговая политика собирается как `политика по умолчанию -> политика клиента -> политика запроса`. Поле `entityTypes` работает как список разрешенных типов: API обрабатывает только эти типы сущностей, а типы вне списка считаются выключенными для данного запроса. Серверные обязательные типы из `REDACTO_REQUIRED_ENTITY_TYPES` могут быть добавлены обратно и не отключаются настройками конкретного запроса.",
        "properties": {
          "entityTypes": {
            "type": "array",
            "description": "Список разрешенных типов сущностей для этого запроса: API будет обрабатывать только эти типы. Полный список допустимых значений задан в перечислении ниже и доступен через `GET /v1/entity-types`. Чтобы отключить одну сущность из набора по умолчанию, передайте полный список типов, которые должны остаться включенными. Пример `[\"EMAIL\",\"PHONE\"]` означает: маскировать email и телефоны, остальные типы не обрабатывать, кроме обязательных серверных типов.",
            "items": {
              "type": "string",
              "enum": [
                "PERSON",
                "ORG",
                "BANK",
                "ADDRESS",
                "EMAIL",
                "SITE",
                "IP_ADDRESS",
                "MAC_ADDRESS",
                "PHONE",
                "PRICE",
                "NDS",
                "DOB",
                "CARD",
                "CRYPTO",
                "PASSPORT",
                "PASSPORT_KZ",
                "PASSPORT_AUTHORITY",
                "PASSPORT_BIRTH_PLACE",
                "PASSPORT_CITIZENSHIP",
                "PASSPORT_ISSUE_DATE",
                "PASSPORT_EXPIRY_DATE",
                "PASSPORT_DEPT_CODE",
                "INN",
                "KPP",
                "OKPO",
                "OKTMO",
                "SNILS",
                "LICENSE_PLATE",
                "VIN",
                "STS",
                "PTS",
                "EPTS",
                "CADASTRAL_NUMBER",
                "EGRN_REGISTRATION_NO",
                "LEGACY_REALTY_OBJECT_NO",
                "POWER_OF_ATTORNEY_NO",
                "NOTARY_REGISTER_NO",
                "DRIVER_LICENSE_NO",
                "BIRTH_CERTIFICATE_NO",
                "MCHD",
                "POSTAL_TRACKING_NO",
                "CONTRACTNO",
                "OGRN",
                "RS",
                "LS",
                "KS",
                "BIK",
                "TREASURY_RS",
                "EKS",
                "TOFK_BIK",
                "IIN",
                "BIN",
                "IIK",
                "IBAN",
                "ISIN",
                "KZ_BIK",
                "KBE",
                "KNP"
              ]
            },
            "examples": [
              [
                "EMAIL",
                "PHONE"
              ],
              [
                "EMAIL"
              ],
              [
                "EMAIL",
                "PHONE",
                "PERSON",
                "ORG",
                "INN"
              ]
            ]
          }
        },
        "additionalProperties": true
      },
      "Dictionary": {
        "type": "object",
        "description": "Словарь восстановления. Содержит исходные значения и считается чувствительным артефактом.",
        "required": [
          "version",
          "mapping",
          "generator",
          "encrypted"
        ],
        "properties": {
          "version": {
            "type": "integer",
            "examples": [
              1
            ]
          },
          "sourceFilename": {
            "type": "string",
            "examples": [
              "text.txt"
            ]
          },
          "maskedFilename": {
            "type": "string",
            "examples": [
              "text.sanitized.txt"
            ]
          },
          "mapping": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "examples": [
              {
                "[EMAIL_1]": "support@redacto-sandbox.example.test"
              }
            ]
          },
          "generator": {
            "type": "string",
            "const": "Redacto",
            "examples": [
              "Redacto"
            ]
          },
          "encrypted": {
            "type": "boolean",
            "description": "false для обычного словаря; encrypted envelope использует отдельные поля шифрования.",
            "examples": [
              false
            ]
          }
        },
        "additionalProperties": true
      },
      "Report": {
        "type": "object",
        "properties": {
          "totalFindings": {
            "type": "integer",
            "minimum": 0
          },
          "maskedCount": {
            "type": "integer",
            "minimum": 0
          },
          "dictionaryEntries": {
            "type": "integer",
            "minimum": 0
          }
        },
        "additionalProperties": true
      },
      "AnonymizeTextRequest": {
        "type": "object",
        "required": [
          "text"
        ],
        "properties": {
          "text": {
            "type": "string",
            "minLength": 1,
            "examples": [
              "Тестовый контакт support@redacto-sandbox.example.test"
            ]
          },
          "enableNer": {
            "type": "boolean",
            "default": true
          },
          "dictionaryPassword": {
            "type": "string",
            "default": ""
          },
          "policy": {
            "$ref": "#/components/schemas/PolicyOverride"
          }
        },
        "additionalProperties": false
      },
      "AnonymizeTextResponse": {
        "type": "object",
        "required": [
          "maskedText",
          "dictionary",
          "report"
        ],
        "properties": {
          "maskedText": {
            "type": "string",
            "examples": [
              "Тестовый контакт [EMAIL_1]"
            ]
          },
          "dictionary": {
            "$ref": "#/components/schemas/Dictionary"
          },
          "report": {
            "$ref": "#/components/schemas/Report"
          }
        },
        "additionalProperties": true
      },
      "RestoreTextRequest": {
        "type": "object",
        "required": [
          "text",
          "dictionary"
        ],
        "properties": {
          "text": {
            "type": "string",
            "examples": [
              "Тестовый контакт [EMAIL_1]"
            ]
          },
          "dictionary": {
            "$ref": "#/components/schemas/Dictionary"
          },
          "dictionaryPassword": {
            "type": "string",
            "default": ""
          }
        },
        "additionalProperties": false
      },
      "RestoreTextResponse": {
        "type": "object",
        "required": [
          "text"
        ],
        "properties": {
          "text": {
            "type": "string",
            "examples": [
              "Тестовый контакт support@redacto-sandbox.example.test"
            ]
          }
        },
        "additionalProperties": false
      },
      "AnonymizeFileMultipartRequest": {
        "type": "object",
        "required": [
          "file"
        ],
        "properties": {
          "file": {
            "type": "string",
            "format": "binary",
            "description": "Файл `.txt`, `.csv`, `.docx`, `.xlsx` или `.pptx`."
          },
          "policy": {
            "type": "string",
            "description": "JSON-строка с политикой запроса. Например: `{\"entityTypes\":[\"EMAIL\",\"PHONE\"]}` означает обрабатывать только EMAIL и PHONE, кроме обязательных серверных типов.",
            "examples": [
              "{\"entityTypes\":[\"EMAIL\",\"PHONE\"]}"
            ]
          },
          "dictionaryPassword": {
            "type": "string",
            "default": ""
          }
        }
      },
      "AnonymizeFileJsonRequest": {
        "type": "object",
        "required": [
          "filename",
          "contentBase64"
        ],
        "properties": {
          "filename": {
            "type": "string",
            "examples": [
              "synthetic.txt"
            ]
          },
          "contentBase64": {
            "type": "string",
            "contentEncoding": "base64"
          },
          "policy": {
            "$ref": "#/components/schemas/PolicyOverride"
          },
          "dictionaryPassword": {
            "type": "string",
            "default": ""
          }
        },
        "additionalProperties": false
      },
      "RestoreFileMultipartRequest": {
        "type": "object",
        "required": [
          "file",
          "dictionary"
        ],
        "properties": {
          "file": {
            "type": "string",
            "format": "binary",
            "description": "Анонимизированный файл."
          },
          "dictionary": {
            "type": "string",
            "format": "binary",
            "description": "`*.dict.json` из ZIP-ответа анонимизации."
          },
          "dictionaryPassword": {
            "type": "string",
            "default": ""
          }
        }
      },
      "RestoreFileJsonRequest": {
        "type": "object",
        "required": [
          "filename",
          "contentBase64",
          "dictionary"
        ],
        "properties": {
          "filename": {
            "type": "string",
            "examples": [
              "synthetic.sanitized.txt"
            ]
          },
          "contentBase64": {
            "type": "string",
            "contentEncoding": "base64"
          },
          "dictionary": {
            "$ref": "#/components/schemas/Dictionary"
          },
          "dictionaryPassword": {
            "type": "string",
            "default": ""
          }
        },
        "additionalProperties": false
      },
      "JobStatus": {
        "type": "object",
        "required": [
          "jobId",
          "status",
          "createdAt",
          "updatedAt",
          "expiresAt"
        ],
        "properties": {
          "jobId": {
            "type": "string",
            "examples": [
              "job_synthetic"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "processing",
              "ready",
              "error"
            ]
          },
          "error": {
            "type": "string",
            "default": ""
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "resultName": {
            "type": "string",
            "default": ""
          },
          "report": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Report"
              },
              {
                "type": "null"
              }
            ]
          },
          "statusUrl": {
            "type": "string",
            "examples": [
              "/v1/jobs/job_synthetic"
            ]
          },
          "resultUrl": {
            "type": "string",
            "examples": [
              "/v1/jobs/job_synthetic/result"
            ]
          }
        },
        "additionalProperties": true
      },
      "EntityTypeTitle": {
        "type": "object",
        "required": [
          "ru",
          "en"
        ],
        "properties": {
          "ru": {
            "type": "string",
            "examples": [
              "Email"
            ]
          },
          "en": {
            "type": "string",
            "examples": [
              "Email"
            ]
          }
        },
        "additionalProperties": false
      },
      "EntityTypeItem": {
        "type": "object",
        "required": [
          "type",
          "title",
          "defaultEnabled",
          "required",
          "groups",
          "syntheticValues"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "PERSON",
              "ORG",
              "BANK",
              "ADDRESS",
              "EMAIL",
              "SITE",
              "IP_ADDRESS",
              "MAC_ADDRESS",
              "PHONE",
              "PRICE",
              "NDS",
              "DOB",
              "CARD",
              "CRYPTO",
              "PASSPORT",
              "PASSPORT_KZ",
              "PASSPORT_AUTHORITY",
              "PASSPORT_BIRTH_PLACE",
              "PASSPORT_CITIZENSHIP",
              "PASSPORT_ISSUE_DATE",
              "PASSPORT_EXPIRY_DATE",
              "PASSPORT_DEPT_CODE",
              "INN",
              "KPP",
              "OKPO",
              "OKTMO",
              "SNILS",
              "LICENSE_PLATE",
              "VIN",
              "STS",
              "PTS",
              "EPTS",
              "CADASTRAL_NUMBER",
              "EGRN_REGISTRATION_NO",
              "LEGACY_REALTY_OBJECT_NO",
              "POWER_OF_ATTORNEY_NO",
              "NOTARY_REGISTER_NO",
              "DRIVER_LICENSE_NO",
              "BIRTH_CERTIFICATE_NO",
              "MCHD",
              "POSTAL_TRACKING_NO",
              "CONTRACTNO",
              "OGRN",
              "RS",
              "LS",
              "KS",
              "BIK",
              "TREASURY_RS",
              "EKS",
              "TOFK_BIK",
              "IIN",
              "BIN",
              "IIK",
              "IBAN",
              "ISIN",
              "KZ_BIK",
              "KBE",
              "KNP"
            ],
            "examples": [
              "EMAIL"
            ]
          },
          "title": {
            "$ref": "#/components/schemas/EntityTypeTitle"
          },
          "defaultEnabled": {
            "type": "boolean",
            "examples": [
              true
            ]
          },
          "required": {
            "type": "boolean",
            "description": "true, если тип принудительно добавляется серверной настройкой REDACTO_REQUIRED_ENTITY_TYPES.",
            "examples": [
              false
            ]
          },
          "groups": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "examples": [
              [
                "common.contacts"
              ]
            ]
          },
          "syntheticValues": {
            "type": "array",
            "description": "Синтетические значения, которые размещенная тестовая среда принимает для этого типа сущности. Значения из пользовательского текста, файлов и словарей восстановления вне этого списка отклоняются в контуре `sandbox_api_key`.",
            "items": {
              "type": "string"
            },
            "examples": [
              [
                "ivan.sintetov@synthetic.example.test",
                "info@demo-org.example.test",
                "billing@synthetic-bank.example.test",
                "support@redacto-sandbox.example.test",
                "kz-demo@synthetic.example.test"
              ]
            ]
          }
        },
        "additionalProperties": false
      },
      "EntityTypeCatalogResponse": {
        "type": "object",
        "required": [
          "schemaVersion",
          "entityTypes",
          "defaultEntityTypes",
          "defaultDisabledEntityTypes",
          "requiredEntityTypes",
          "syntheticDataVersion"
        ],
        "properties": {
          "schemaVersion": {
            "type": "integer",
            "examples": [
              24
            ]
          },
          "entityTypes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EntityTypeItem"
            }
          },
          "defaultEntityTypes": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "PERSON",
                "ORG",
                "BANK",
                "ADDRESS",
                "EMAIL",
                "SITE",
                "IP_ADDRESS",
                "MAC_ADDRESS",
                "PHONE",
                "PRICE",
                "NDS",
                "DOB",
                "CARD",
                "CRYPTO",
                "PASSPORT",
                "PASSPORT_KZ",
                "PASSPORT_AUTHORITY",
                "PASSPORT_BIRTH_PLACE",
                "PASSPORT_CITIZENSHIP",
                "PASSPORT_ISSUE_DATE",
                "PASSPORT_EXPIRY_DATE",
                "PASSPORT_DEPT_CODE",
                "INN",
                "KPP",
                "OKPO",
                "OKTMO",
                "SNILS",
                "LICENSE_PLATE",
                "VIN",
                "STS",
                "PTS",
                "EPTS",
                "CADASTRAL_NUMBER",
                "EGRN_REGISTRATION_NO",
                "LEGACY_REALTY_OBJECT_NO",
                "POWER_OF_ATTORNEY_NO",
                "NOTARY_REGISTER_NO",
                "DRIVER_LICENSE_NO",
                "BIRTH_CERTIFICATE_NO",
                "MCHD",
                "POSTAL_TRACKING_NO",
                "CONTRACTNO",
                "OGRN",
                "RS",
                "LS",
                "KS",
                "BIK",
                "TREASURY_RS",
                "EKS",
                "TOFK_BIK",
                "IIN",
                "BIN",
                "IIK",
                "IBAN",
                "ISIN",
                "KZ_BIK",
                "KBE",
                "KNP"
              ]
            }
          },
          "defaultDisabledEntityTypes": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "PERSON",
                "ORG",
                "BANK",
                "ADDRESS",
                "EMAIL",
                "SITE",
                "IP_ADDRESS",
                "MAC_ADDRESS",
                "PHONE",
                "PRICE",
                "NDS",
                "DOB",
                "CARD",
                "CRYPTO",
                "PASSPORT",
                "PASSPORT_KZ",
                "PASSPORT_AUTHORITY",
                "PASSPORT_BIRTH_PLACE",
                "PASSPORT_CITIZENSHIP",
                "PASSPORT_ISSUE_DATE",
                "PASSPORT_EXPIRY_DATE",
                "PASSPORT_DEPT_CODE",
                "INN",
                "KPP",
                "OKPO",
                "OKTMO",
                "SNILS",
                "LICENSE_PLATE",
                "VIN",
                "STS",
                "PTS",
                "EPTS",
                "CADASTRAL_NUMBER",
                "EGRN_REGISTRATION_NO",
                "LEGACY_REALTY_OBJECT_NO",
                "POWER_OF_ATTORNEY_NO",
                "NOTARY_REGISTER_NO",
                "DRIVER_LICENSE_NO",
                "BIRTH_CERTIFICATE_NO",
                "MCHD",
                "POSTAL_TRACKING_NO",
                "CONTRACTNO",
                "OGRN",
                "RS",
                "LS",
                "KS",
                "BIK",
                "TREASURY_RS",
                "EKS",
                "TOFK_BIK",
                "IIN",
                "BIN",
                "IIK",
                "IBAN",
                "ISIN",
                "KZ_BIK",
                "KBE",
                "KNP"
              ]
            },
            "examples": [
              [
                "CONTRACTNO"
              ]
            ]
          },
          "requiredEntityTypes": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "PERSON",
                "ORG",
                "BANK",
                "ADDRESS",
                "EMAIL",
                "SITE",
                "IP_ADDRESS",
                "MAC_ADDRESS",
                "PHONE",
                "PRICE",
                "NDS",
                "DOB",
                "CARD",
                "CRYPTO",
                "PASSPORT",
                "PASSPORT_KZ",
                "PASSPORT_AUTHORITY",
                "PASSPORT_BIRTH_PLACE",
                "PASSPORT_CITIZENSHIP",
                "PASSPORT_ISSUE_DATE",
                "PASSPORT_EXPIRY_DATE",
                "PASSPORT_DEPT_CODE",
                "INN",
                "KPP",
                "OKPO",
                "OKTMO",
                "SNILS",
                "LICENSE_PLATE",
                "VIN",
                "STS",
                "PTS",
                "EPTS",
                "CADASTRAL_NUMBER",
                "EGRN_REGISTRATION_NO",
                "LEGACY_REALTY_OBJECT_NO",
                "POWER_OF_ATTORNEY_NO",
                "NOTARY_REGISTER_NO",
                "DRIVER_LICENSE_NO",
                "BIRTH_CERTIFICATE_NO",
                "MCHD",
                "POSTAL_TRACKING_NO",
                "CONTRACTNO",
                "OGRN",
                "RS",
                "LS",
                "KS",
                "BIK",
                "TREASURY_RS",
                "EKS",
                "TOFK_BIK",
                "IIN",
                "BIN",
                "IIK",
                "IBAN",
                "ISIN",
                "KZ_BIK",
                "KBE",
                "KNP"
              ]
            },
            "description": "Типы, которые сервер добавит обратно, даже если политика запроса их не указала."
          },
          "syntheticDataVersion": {
            "type": "integer",
            "description": "Версия опубликованного словаря синтетических значений размещенной тестовой среды.",
            "examples": [
              1
            ]
          }
        },
        "additionalProperties": false
      }
    }
  }
}
