{
  "openapi": "3.1.0",
  "info": {
    "title": "InstReg Integration API",
    "version": "1.0.0",
    "description": "API для запуска и контроля очередей регистрации Instagram. Все методы требуют Integration API key."
  },
  "servers": [
    {
      "url": "https://myrzboss.com",
      "description": "Production"
    }
  ],
  "tags": [
    {
      "name": "Capabilities",
      "description": "Состояние и возможности сервиса"
    },
    {
      "name": "Batches",
      "description": "Очереди регистрации"
    },
    {
      "name": "Results",
      "description": "Результаты и CSV"
    },
    {
      "name": "Providers",
      "description": "Почта и телефонные номера"
    },
    {
      "name": "Bios",
      "description": "Пул био"
    },
    {
      "name": "Proxies",
      "description": "Проверка proxy"
    }
  ],
  "security": [
    {
      "BearerAuth": []
    }
  ],
  "paths": {
    "/api/integrations/v1/registration/capabilities": {
      "get": {
        "tags": [
          "Capabilities"
        ],
        "summary": "Получить возможности сервиса",
        "operationId": "getRegistrationCapabilities",
        "responses": {
          "200": {
            "description": "Возможности сервиса",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CapabilitiesResponse"
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/api/integrations/v1/registration/batches": {
      "get": {
        "tags": [
          "Batches"
        ],
        "summary": "Получить список очередей",
        "operationId": "listRegistrationBatches",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Фильтр по статусу очереди",
            "schema": {
              "$ref": "#/components/schemas/BatchStatus"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "batchId из nextCursor предыдущего ответа",
            "schema": {
              "$ref": "#/components/schemas/PublicId"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Количество записей",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Список очередей",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchListResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "post": {
        "tags": [
          "Batches"
        ],
        "summary": "Создать очередь",
        "description": "Создаёт одну очередь. У пользователя одновременно может выполняться только одна очередь. Idempotency-Key обязателен.",
        "operationId": "createRegistrationBatch",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateBatchRequest"
              },
              "examples": {
                "anymessage": {
                  "summary": "Регистрация через AnyMessage",
                  "value": {
                    "count": 5,
                    "contactMode": "anymessage",
                    "emailDomain": "example.com",
                    "create2fa": false,
                    "proxyFormat": "url",
                    "proxyText": "http://user:pass@203.0.113.10:10000\nhttp://user:pass@203.0.113.11:10000"
                  }
                },
                "cyberyozh": {
                  "summary": "Регистрация через CyberYozh",
                  "value": {
                    "count": 2,
                    "contactMode": "cyberyozh",
                    "phoneOption": "0123456789abcdef0123456789abcdef",
                    "quotedPrice": "0.25",
                    "create2fa": false,
                    "proxyFormat": "auto",
                    "proxyText": ""
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Повтор ранее выполненного запроса, если очередь уже завершена",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateBatchResponse"
                }
              }
            }
          },
          "202": {
            "description": "Очередь принята или возвращён повтор активного запроса",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateBatchResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/api/integrations/v1/registration/batches/{batchId}": {
      "get": {
        "tags": [
          "Batches"
        ],
        "summary": "Получить очередь",
        "operationId": "getRegistrationBatch",
        "parameters": [
          {
            "$ref": "#/components/parameters/BatchId"
          }
        ],
        "responses": {
          "200": {
            "description": "Очередь и её элементы",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/api/integrations/v1/registration/batches/{batchId}/cancel": {
      "post": {
        "tags": [
          "Batches"
        ],
        "summary": "Отменить очередь",
        "description": "Отменяет ожидающие элементы. Уже запущенные browser-сессии завершаются безопасно. Idempotency-Key не требуется.",
        "operationId": "cancelRegistrationBatch",
        "parameters": [
          {
            "$ref": "#/components/parameters/BatchId"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "maxProperties": 0
              },
              "example": {}
            }
          }
        },
        "responses": {
          "200": {
            "description": "Отмена применена либо очередь уже отменена или завершена",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CancelBatchResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/api/integrations/v1/registration/results": {
      "get": {
        "tags": [
          "Results"
        ],
        "summary": "Получить результаты",
        "operationId": "listRegistrationResults",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Фильтр по статусу результата",
            "schema": {
              "$ref": "#/components/schemas/JobStatus"
            }
          },
          {
            "name": "batchId",
            "in": "query",
            "required": false,
            "description": "Фильтр по очереди. Также поддерживается batch_id.",
            "schema": {
              "$ref": "#/components/schemas/PublicId"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "jobId из nextCursor предыдущего ответа",
            "schema": {
              "$ref": "#/components/schemas/PublicId"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Количество записей",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Список результатов без паролей, cookies и OTP",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResultsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/api/integrations/v1/registration/results.csv": {
      "get": {
        "tags": [
          "Results"
        ],
        "summary": "Скачать CSV с созданными аккаунтами",
        "description": "Возвращает накопительный CSV. Требует scope registration:credentials. Ответ содержит Cache-Control: no-store.",
        "operationId": "downloadRegistrationResultsCsv",
        "responses": {
          "200": {
            "description": "CSV файл",
            "headers": {
              "Content-Disposition": {
                "description": "Имя файла",
                "schema": {
                  "type": "string",
                  "example": "attachment; filename=\"instagram_accounts.csv\""
                }
              },
              "Cache-Control": {
                "description": "Запрет кеширования",
                "schema": {
                  "type": "string",
                  "example": "no-store, max-age=0"
                }
              }
            },
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/integrations/v1/registration/email-domains": {
      "get": {
        "tags": [
          "Providers"
        ],
        "summary": "Получить домены AnyMessage",
        "operationId": "listRegistrationEmailDomains",
        "responses": {
          "200": {
            "description": "Домены, остатки и цены",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailDomainsResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          }
        }
      }
    },
    "/api/integrations/v1/registration/phone-options": {
      "get": {
        "tags": [
          "Providers"
        ],
        "summary": "Получить номера CyberYozh",
        "operationId": "listRegistrationPhoneOptions",
        "responses": {
          "200": {
            "description": "Доступные предложения и лимиты стоимости",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PhoneOptionsResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "502": {
            "$ref": "#/components/responses/BadGateway"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/api/integrations/v1/registration/bios": {
      "get": {
        "tags": [
          "Bios"
        ],
        "summary": "Получить состояние пула био",
        "operationId": "getRegistrationBios",
        "responses": {
          "200": {
            "description": "Счётчики пула и лимиты",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BiosResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "post": {
        "tags": [
          "Bios"
        ],
        "summary": "Добавить био в пул",
        "description": "Одна строка biosText соответствует одному био. Пустые, некорректные и повторяющиеся строки пропускаются.",
        "operationId": "importRegistrationBios",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ImportBiosRequest"
              },
              "example": {
                "biosText": "Digital creator\nTravel and coffee\nNew account"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Результат импорта",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImportBiosResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/integrations/v1/registration/proxies/check": {
      "post": {
        "tags": [
          "Proxies"
        ],
        "summary": "Проверить proxy",
        "description": "Проверяются первые три proxy. Разрешены только proxy с публичным адресом.",
        "operationId": "checkRegistrationProxies",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProxyCheckRequest"
              },
              "example": {
                "proxyFormat": "url",
                "proxyText": "http://user:pass@203.0.113.10:10000"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Результаты проверки. Поле ok равно false, если хотя бы один proxy не работает.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProxyCheckResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "Integration API key",
        "description": "Передайте Integration API key: Authorization: Bearer <key>."
      }
    },
    "parameters": {
      "BatchId": {
        "name": "batchId",
        "in": "path",
        "required": true,
        "description": "Публичный идентификатор очереди",
        "schema": {
          "$ref": "#/components/schemas/PublicId"
        }
      },
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": true,
        "description": "Уникальный ключ запроса. Повтор с тем же ключом и payload возвращает прежнюю очередь; другой payload возвращает 409.",
        "schema": {
          "type": "string",
          "minLength": 8,
          "maxLength": 128,
          "pattern": "^[A-Za-z0-9._:-]{8,128}$",
          "example": "site-order-20260723-0001"
        }
      }
    },
    "headers": {
      "RateLimitLimit": {
        "description": "Лимит запросов за минуту",
        "schema": {
          "type": "integer"
        }
      },
      "RateLimitRemaining": {
        "description": "Оставшееся число запросов",
        "schema": {
          "type": "integer"
        }
      },
      "RateLimitReset": {
        "description": "Unix timestamp сброса лимита",
        "schema": {
          "type": "integer",
          "format": "int64"
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Некорректный запрос",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Integration API key отсутствует, отключён или недействителен",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "examples": {
              "missing": {
                "value": {
                  "ok": false,
                  "error": "missing_integration_key",
                  "message": "Передайте Bearer integration key."
                }
              },
              "invalid": {
                "value": {
                  "ok": false,
                  "error": "invalid_integration_key",
                  "message": "Integration key не найден или отключён."
                }
              }
            }
          }
        }
      },
      "Forbidden": {
        "description": "Доступ пользователя закончился, ключ не имеет требуемого scope или операция отключена",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "NotFound": {
        "description": "Ресурс не найден",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "Conflict": {
        "description": "Конфликт состояния или Idempotency-Key",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "UnprocessableEntity": {
        "description": "JSON принят, но данные не прошли проверку",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Лимит запросов исчерпан",
        "headers": {
          "Retry-After": {
            "description": "Через сколько секунд повторить запрос",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimitLimit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimitRemaining"
          },
          "X-RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimitReset"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "ok": false,
              "error": "rate_limit_exceeded",
              "message": "Лимит Integration API исчерпан. Повторите запрос позже."
            }
          }
        }
      },
      "BadGateway": {
        "description": "Внешний провайдер вернул ошибку",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "ServiceUnavailable": {
        "description": "Сервис или внешний провайдер не настроен либо временно недоступен",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "InternalError": {
        "description": "Внутренняя ошибка",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      }
    },
    "schemas": {
      "PublicId": {
        "type": "string",
        "minLength": 12,
        "maxLength": 100,
        "pattern": "^[A-Za-z0-9_-]{12,100}$",
        "example": "BbgVaDhiTS4G1RjZ"
      },
      "BatchStatus": {
        "type": "string",
        "enum": [
          "queued",
          "running",
          "cancelling",
          "completed",
          "partial",
          "failed",
          "cancelled"
        ]
      },
      "BatchItemStatus": {
        "type": "string",
        "enum": [
          "queued",
          "running",
          "completed",
          "review",
          "failed",
          "cancelled"
        ]
      },
      "JobStatus": {
        "type": "string",
        "enum": [
          "starting",
          "session_ready",
          "form_filled",
          "birthdate_required",
          "birthdate_filled",
          "awaiting_otp",
          "otp_filled",
          "awaiting_captcha",
          "captcha_filled",
          "awaiting_review",
          "username_unavailable",
          "created",
          "failed",
          "cancelled"
        ]
      },
      "ProxyFormat": {
        "type": "string",
        "enum": [
          "auto",
          "jarvee",
          "url",
          "host_port_user_pass",
          "user_pass_host_port",
          "host_port"
        ],
        "default": "auto"
      },
      "UnixTime": {
        "type": "integer",
        "format": "int64",
        "minimum": 0,
        "description": "Unix timestamp в секундах. 0 означает, что событие ещё не произошло."
      },
      "ErrorResponse": {
        "type": "object",
        "required": [
          "ok",
          "error"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": false
          },
          "error": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        },
        "additionalProperties": true
      },
      "CapabilitiesResponse": {
        "type": "object",
        "required": [
          "ok",
          "registration"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "registration": {
            "type": "object",
            "required": [
              "enabled",
              "activeCount",
              "maxActive",
              "maxBatchSize",
              "proxyFormats",
              "providers",
              "features"
            ],
            "properties": {
              "enabled": {
                "type": "boolean"
              },
              "activeCount": {
                "type": "integer",
                "minimum": 0
              },
              "maxActive": {
                "type": "integer",
                "minimum": 1,
                "maximum": 30
              },
              "maxBatchSize": {
                "type": "integer",
                "minimum": 1,
                "maximum": 30
              },
              "proxyFormats": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ProxyFormat"
                },
                "uniqueItems": true
              },
              "providers": {
                "type": "object",
                "required": [
                  "anymessage",
                  "cyberyozh",
                  "yescaptcha"
                ],
                "properties": {
                  "anymessage": {
                    "type": "boolean"
                  },
                  "cyberyozh": {
                    "type": "boolean"
                  },
                  "yescaptcha": {
                    "type": "boolean"
                  }
                },
                "additionalProperties": false
              },
              "features": {
                "type": "object",
                "required": [
                  "bio",
                  "jarvee",
                  "twoFactor",
                  "credentialsCsv"
                ],
                "properties": {
                  "bio": {
                    "type": "boolean"
                  },
                  "jarvee": {
                    "type": "boolean"
                  },
                  "twoFactor": {
                    "type": "boolean"
                  },
                  "credentialsCsv": {
                    "type": "boolean"
                  }
                },
                "additionalProperties": false
              }
            },
            "additionalProperties": false
          }
        },
        "additionalProperties": false
      },
      "CreateBatchRequest": {
        "type": "object",
        "required": [
          "count"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "minimum": 1,
            "maximum": 30,
            "description": "Фактический максимум также возвращается в capabilities.maxBatchSize."
          },
          "commonPassword": {
            "type": "string",
            "minLength": 8,
            "maxLength": 200,
            "description": "Необязательно. Если не передан, для каждого аккаунта генерируется отдельный пароль."
          },
          "contactMode": {
            "type": "string",
            "enum": [
              "anymessage",
              "cyberyozh"
            ],
            "default": "anymessage"
          },
          "emailDomain": {
            "type": "string",
            "minLength": 3,
            "maxLength": 190,
            "pattern": "^[a-z0-9.-]{3,190}$",
            "description": "Необязательный домен AnyMessage."
          },
          "phoneOption": {
            "type": "string",
            "pattern": "^[0-9a-f]{32}$",
            "description": "offerKey из phone-options. Обязателен для contactMode=cyberyozh."
          },
          "quotedPrice": {
            "type": "string",
            "pattern": "^[0-9]+(?:\\.[0-9]+)?$",
            "description": "Цена из phone-options. Обязательна для contactMode=cyberyozh."
          },
          "create2fa": {
            "type": "boolean",
            "default": false,
            "description": "Передавайте true только если capabilities.registration.features.twoFactor=true."
          },
          "proxyFormat": {
            "$ref": "#/components/schemas/ProxyFormat"
          },
          "proxyText": {
            "type": "string",
            "description": "Один proxy на строку. Если proxy переданы, их должно быть не меньше count."
          }
        },
        "allOf": [
          {
            "if": {
              "properties": {
                "contactMode": {
                  "const": "cyberyozh"
                }
              },
              "required": [
                "contactMode"
              ]
            },
            "then": {
              "required": [
                "phoneOption",
                "quotedPrice"
              ]
            }
          }
        ],
        "additionalProperties": false
      },
      "BatchCounts": {
        "type": "object",
        "required": [
          "queued",
          "running",
          "completed",
          "fulfilled",
          "review",
          "failed",
          "cancelled"
        ],
        "properties": {
          "queued": {
            "type": "integer",
            "minimum": 0
          },
          "running": {
            "type": "integer",
            "minimum": 0
          },
          "completed": {
            "type": "integer",
            "minimum": 0
          },
          "fulfilled": {
            "type": "integer",
            "minimum": 0
          },
          "review": {
            "type": "integer",
            "minimum": 0
          },
          "failed": {
            "type": "integer",
            "minimum": 0
          },
          "cancelled": {
            "type": "integer",
            "minimum": 0
          }
        },
        "additionalProperties": false
      },
      "BatchItem": {
        "type": "object",
        "required": [
          "itemId",
          "position",
          "fullName",
          "requestedUsername",
          "birthDate",
          "proxy",
          "jobId",
          "status",
          "lastError",
          "createdAt",
          "updatedAt",
          "completedAt"
        ],
        "properties": {
          "itemId": {
            "$ref": "#/components/schemas/PublicId"
          },
          "position": {
            "type": "integer",
            "minimum": 1
          },
          "fullName": {
            "type": "string"
          },
          "requestedUsername": {
            "type": "string"
          },
          "birthDate": {
            "type": "string",
            "format": "date"
          },
          "proxy": {
            "type": "string",
            "description": "Без пароля."
          },
          "jobId": {
            "type": "string",
            "description": "Пустая строка до запуска элемента."
          },
          "status": {
            "$ref": "#/components/schemas/BatchItemStatus"
          },
          "lastError": {
            "type": "string"
          },
          "createdAt": {
            "$ref": "#/components/schemas/UnixTime"
          },
          "updatedAt": {
            "$ref": "#/components/schemas/UnixTime"
          },
          "completedAt": {
            "$ref": "#/components/schemas/UnixTime"
          }
        },
        "additionalProperties": false
      },
      "Batch": {
        "type": "object",
        "required": [
          "batchId",
          "status",
          "requestedCount",
          "proxyFormat",
          "emailDomain",
          "cancelRequested",
          "counts",
          "lastError",
          "createdAt",
          "updatedAt",
          "completedAt"
        ],
        "properties": {
          "batchId": {
            "$ref": "#/components/schemas/PublicId"
          },
          "status": {
            "$ref": "#/components/schemas/BatchStatus"
          },
          "requestedCount": {
            "type": "integer",
            "minimum": 1,
            "maximum": 30
          },
          "proxyFormat": {
            "$ref": "#/components/schemas/ProxyFormat"
          },
          "emailDomain": {
            "type": "string"
          },
          "cancelRequested": {
            "type": "boolean"
          },
          "counts": {
            "$ref": "#/components/schemas/BatchCounts"
          },
          "lastError": {
            "type": "string"
          },
          "createdAt": {
            "$ref": "#/components/schemas/UnixTime"
          },
          "updatedAt": {
            "$ref": "#/components/schemas/UnixTime"
          },
          "completedAt": {
            "$ref": "#/components/schemas/UnixTime"
          },
          "items": {
            "type": "array",
            "maxItems": 100,
            "items": {
              "$ref": "#/components/schemas/BatchItem"
            }
          }
        },
        "additionalProperties": false
      },
      "PaginationMeta": {
        "type": "object",
        "required": [
          "limit",
          "hasNext",
          "nextCursor"
        ],
        "properties": {
          "limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100
          },
          "hasNext": {
            "type": "boolean"
          },
          "nextCursor": {
            "type": "string",
            "description": "Пустая строка, если следующей страницы нет."
          }
        },
        "additionalProperties": false
      },
      "BatchListResponse": {
        "type": "object",
        "required": [
          "ok",
          "batches",
          "meta"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "batches": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Batch"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta"
          }
        },
        "additionalProperties": false
      },
      "BatchResponse": {
        "type": "object",
        "required": [
          "ok",
          "batch"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "batch": {
            "$ref": "#/components/schemas/Batch"
          }
        },
        "additionalProperties": false
      },
      "CreateBatchResponse": {
        "type": "object",
        "required": [
          "ok",
          "batch",
          "message"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "batch": {
            "$ref": "#/components/schemas/Batch"
          },
          "idempotentReplay": {
            "type": "boolean"
          },
          "message": {
            "type": "string"
          }
        },
        "additionalProperties": true
      },
      "CancelBatchResponse": {
        "type": "object",
        "required": [
          "ok",
          "batch",
          "message"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "batch": {
            "$ref": "#/components/schemas/Batch"
          },
          "idempotentReplay": {
            "type": "boolean"
          },
          "message": {
            "type": "string"
          }
        },
        "additionalProperties": true
      },
      "RegistrationResult": {
        "type": "object",
        "required": [
          "id",
          "publicId",
          "jobId",
          "requestedUsername",
          "finalUsername",
          "status",
          "pauseReason",
          "lastError",
          "createdAt",
          "updatedAt",
          "completedAt",
          "accountCreatedAt",
          "fulfilled",
          "postCreateState",
          "bioStatus",
          "bioReadyAt",
          "jarveeStatus",
          "jarveeLastError",
          "jarveeDeliveredAt",
          "signupAttemptedAt",
          "contactProvider",
          "providerDomain",
          "providerCountryCode",
          "providerOrderState",
          "maskedContact",
          "captchaProviderStatus",
          "autoContinue",
          "profileUrl"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/PublicId"
          },
          "publicId": {
            "$ref": "#/components/schemas/PublicId"
          },
          "jobId": {
            "$ref": "#/components/schemas/PublicId"
          },
          "batchId": {
            "type": "string",
            "description": "Пустая строка, если результат создан не через пакетную очередь."
          },
          "requestedUsername": {
            "type": "string"
          },
          "finalUsername": {
            "type": "string"
          },
          "status": {
            "$ref": "#/components/schemas/JobStatus"
          },
          "pauseReason": {
            "type": "string"
          },
          "lastError": {
            "type": "string"
          },
          "createdAt": {
            "$ref": "#/components/schemas/UnixTime"
          },
          "updatedAt": {
            "$ref": "#/components/schemas/UnixTime"
          },
          "completedAt": {
            "$ref": "#/components/schemas/UnixTime"
          },
          "accountCreatedAt": {
            "$ref": "#/components/schemas/UnixTime"
          },
          "fulfilled": {
            "type": "boolean"
          },
          "postCreateState": {
            "type": "string"
          },
          "bioStatus": {
            "type": "string"
          },
          "bioReadyAt": {
            "$ref": "#/components/schemas/UnixTime"
          },
          "jarveeStatus": {
            "type": "string"
          },
          "jarveeLastError": {
            "type": "string"
          },
          "jarveeDeliveredAt": {
            "$ref": "#/components/schemas/UnixTime"
          },
          "signupAttemptedAt": {
            "$ref": "#/components/schemas/UnixTime"
          },
          "contactProvider": {
            "type": "string"
          },
          "providerDomain": {
            "type": "string"
          },
          "providerCountryCode": {
            "type": "string"
          },
          "providerOrderState": {
            "type": "string"
          },
          "maskedContact": {
            "type": "string"
          },
          "captchaProviderStatus": {
            "type": "string"
          },
          "autoContinue": {
            "type": "boolean"
          },
          "profileUrl": {
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "ResultsResponse": {
        "type": "object",
        "required": [
          "ok",
          "results",
          "meta"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RegistrationResult"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta"
          }
        },
        "additionalProperties": false
      },
      "EmailDomain": {
        "type": "object",
        "required": [
          "domain",
          "count",
          "price"
        ],
        "properties": {
          "domain": {
            "type": "string"
          },
          "count": {
            "type": "integer",
            "minimum": 0
          },
          "price": {
            "type": "string",
            "description": "Цена в USD."
          }
        },
        "additionalProperties": false
      },
      "EmailDomainsResponse": {
        "type": "object",
        "required": [
          "ok",
          "domains"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "domains": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EmailDomain"
            }
          }
        },
        "additionalProperties": true
      },
      "PhoneOption": {
        "type": "object",
        "required": [
          "offerKey",
          "provider",
          "period",
          "serviceCode",
          "countryCode",
          "countryName",
          "price",
          "availability"
        ],
        "properties": {
          "offerKey": {
            "type": "string",
            "pattern": "^[0-9a-f]{32}$"
          },
          "provider": {
            "type": "string",
            "enum": [
              "virtual",
              "residential"
            ]
          },
          "period": {
            "type": "string",
            "example": "MIN_15"
          },
          "serviceCode": {
            "type": "string"
          },
          "countryCode": {
            "type": "string"
          },
          "countryName": {
            "type": "string"
          },
          "price": {
            "type": "string",
            "description": "Цена в USD."
          },
          "availability": {
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "PhoneLimits": {
        "type": "object",
        "required": [
          "maxUnitPrice",
          "maxBatchTotal",
          "maxUserDaily"
        ],
        "properties": {
          "maxUnitPrice": {
            "type": "string"
          },
          "maxBatchTotal": {
            "type": "string"
          },
          "maxUserDaily": {
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "PhoneOptionsResponse": {
        "type": "object",
        "required": [
          "ok",
          "options",
          "limits"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "options": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PhoneOption"
            }
          },
          "limits": {
            "$ref": "#/components/schemas/PhoneLimits"
          },
          "partial": {
            "type": "boolean"
          }
        },
        "additionalProperties": true
      },
      "BioCounts": {
        "type": "object",
        "required": [
          "available",
          "reserved",
          "total"
        ],
        "properties": {
          "available": {
            "type": "integer",
            "minimum": 0
          },
          "reserved": {
            "type": "integer",
            "minimum": 0
          },
          "total": {
            "type": "integer",
            "minimum": 0
          }
        },
        "additionalProperties": false
      },
      "BiosResponse": {
        "type": "object",
        "required": [
          "ok",
          "bios",
          "bioMaxItems",
          "bioMaxLength"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "bios": {
            "$ref": "#/components/schemas/BioCounts"
          },
          "bioMaxItems": {
            "type": "integer",
            "minimum": 1
          },
          "bioMaxLength": {
            "type": "integer",
            "const": 150
          }
        },
        "additionalProperties": true
      },
      "ImportBiosRequest": {
        "type": "object",
        "required": [
          "biosText"
        ],
        "properties": {
          "biosText": {
            "type": "string",
            "minLength": 1,
            "description": "UTF-8 текст, одно био на строку. Максимальная длина одного био — 150 символов."
          }
        },
        "additionalProperties": false
      },
      "ImportBiosResponse": {
        "type": "object",
        "required": [
          "ok",
          "bios",
          "added",
          "ignored",
          "message"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "bios": {
            "$ref": "#/components/schemas/BioCounts"
          },
          "added": {
            "type": "integer",
            "minimum": 0
          },
          "ignored": {
            "type": "integer",
            "minimum": 0
          },
          "message": {
            "type": "string"
          }
        },
        "additionalProperties": true
      },
      "ProxyCheckRequest": {
        "type": "object",
        "required": [
          "proxyText"
        ],
        "properties": {
          "proxyFormat": {
            "$ref": "#/components/schemas/ProxyFormat"
          },
          "proxyText": {
            "type": "string",
            "minLength": 1,
            "description": "Один proxy на строку."
          }
        },
        "additionalProperties": false
      },
      "ProxyCheckResult": {
        "type": "object",
        "required": [
          "ok",
          "proxy",
          "message"
        ],
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "proxy": {
            "type": "string",
            "description": "Proxy без пароля."
          },
          "ip": {
            "type": "string",
            "description": "Определённый внешний IP. Может отсутствовать в ответе об ошибке."
          },
          "message": {
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "ProxyCheckResponse": {
        "type": "object",
        "required": [
          "ok",
          "checked",
          "working",
          "results",
          "message"
        ],
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "checked": {
            "type": "integer",
            "minimum": 1,
            "maximum": 3
          },
          "working": {
            "type": "integer",
            "minimum": 0,
            "maximum": 3
          },
          "results": {
            "type": "array",
            "minItems": 1,
            "maxItems": 3,
            "items": {
              "$ref": "#/components/schemas/ProxyCheckResult"
            }
          },
          "message": {
            "type": "string"
          }
        },
        "additionalProperties": true
      }
    }
  }
}
