Документация для разработчиков

Публичный API v1

REST API для загрузки и конвертации файлов из ваших приложений. Стабильный контракт, вебхуки, песочница-симулятор и идемпотентные запросы.

Базовый URL https://api.perefile.ru/v1 Открыть справку OpenAPI ->

# Введение

API Perefile v1 - это REST-интерфейс поверх HTTPS. Тела запросов и ответов - JSON (кроме загрузки файла через multipart и скачивания результата). Все эндпоинты находятся под базовым URL и версионированы префиксом /v1.

Каждый ответ несёт заголовок X-Livemode и поле livemode в теле: true - боевой режим (расходует квоту и реальные конверсии), false - песочница (симулятор).

ℹ️

Базовые URL .com и .ru равнозначны и обслуживаются одним сервисом. Используйте тот, что ближе к вашей инфраструктуре; счёт и квота общие для аккаунта.

# Аутентификация

Каждый запрос требует ваш API-ключ в заголовке X-API-Key. Альтернатива - заголовок Authorization: Bearer <ключ>. Ключи создаются в личном кабинете в разделе «API» и показываются один раз - сохраните их в надёжном месте.

  • Боевые ключи начинаются с pf_live_ - доступны на тарифах с API-доступом.
  • Тестовые ключи начинаются с pf_test_ - работают всегда и ведут в песочницу-симулятор.
  • Ключ можно отозвать в любой момент в личном кабинете; отзыв вступает в силу в течение минуты.
cURL
curl https://api.perefile.ru/v1/me \
  -H "X-API-Key: pf_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Ответ
{
  "plan": "api_start",
  "livemode": true,
  "quota": { "limit": 1000, "used": 137, "reset_at": "2026-07-12T09:00:00Z" },
  "rate_limits": { "per_minute": 60, "per_day": 5000, "max_concurrent": 10 },
  "api_keys_active": 2
}
ℹ️

Никогда не публикуйте боевой ключ в браузерном коде или мобильном приложении. Запросы к /v1 идут только с вашего сервера. CORS для /v1 закрыт намеренно.

# Быстрый старт

Минимальный сценарий «загрузить и сконвертировать» - два запроса: сначала загружаете файл и получаете file_id, затем создаёте конверсию. Готовый результат заберёте по download_url.

cURL
# 1. Загрузка файла -> file_id
curl https://api.perefile.ru/v1/files \
  -H "X-API-Key: $PEREFILE_KEY" \
  -F "file=@document.docx"

# 2. Конверсия docx -> pdf
curl https://api.perefile.ru/v1/conversions \
  -H "X-API-Key: $PEREFILE_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "input": "file_abc123", "target_format": "pdf" }'
Python
import requests

BASE = "https://api.perefile.ru/v1"
HEAD = {"X-API-Key": "pf_live_xxx"}

# 1. Загрузка
with open("document.docx", "rb") as f:
    up = requests.post(f"{BASE}/files", headers=HEAD, files={"file": f})
file_id = up.json()["file_id"]

# 2. Конверсия
conv = requests.post(
    f"{BASE}/conversions", headers=HEAD,
    json={"input": file_id, "target_format": "pdf"},
)
print(conv.json()["id"], conv.json()["status"])

# Доступные форматы

GET /v1/formats возвращает список поддерживаемых пар «исходный формат -> целевой формат» и операцию (convert, merge, split и др.). Список кешируется на 5 минут.

cURL
curl https://api.perefile.ru/v1/formats -H "X-API-Key: $PEREFILE_KEY"
Ответ
{
  "pairs": [
    { "from": "docx", "to": "pdf", "operation": "convert" },
    { "from": "pdf", "to": "docx", "operation": "convert" },
    { "from": "pdf", "to": "pdf", "operation": "merge" }
  ]
}

# Загрузка файлов

POST /v1/files принимает файл двумя способами: multipart-форма (поле file) или JSON с полем url (загрузка по ссылке с защитой от SSRF). В ответе - file_id, имя, размер, определённый формат и срок жизни (expires_at, 24 часа). file_id переиспользуем: один файл можно конвертировать несколько раз.

Файл
curl https://api.perefile.ru/v1/files \
  -H "X-API-Key: $PEREFILE_KEY" \
  -F "file=@report.docx"
По ссылке
curl https://api.perefile.ru/v1/files \
  -H "X-API-Key: $PEREFILE_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://example.com/report.docx" }'
Ответ
{
  "file_id": "file_abc123",
  "name": "report.docx",
  "size": 248173,
  "detected_format": "docx",
  "expires_at": "2026-06-15T09:00:00Z",
  "livemode": true
}
ℹ️

Формат определяется по содержимому (magic-bytes), а не по расширению. Слишком большой файл или неподдерживаемый тип отклоняется сразу, до создания конверсии.

# Создание конверсий

POST /v1/conversions создаёт конверсию. Поле input - это file_id (строка), массив file_id (только для merge) либо объект { url }. Дополнительно: operation (по умолчанию convert), target_format и произвольные settings.

Объединение файлов (merge)

Передайте массив из нескольких file_id с operation: merge. Объединение N файлов в один результат считается одной конверсией.

Сахар: загрузка и конверсия одним запросом

Если нужно сконвертировать один файл и не хочется делать два запроса - отправьте multipart прямо на /v1/conversions с полями file и target_format.

Один файл
curl https://api.perefile.ru/v1/conversions \
  -H "X-API-Key: $PEREFILE_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "input": "file_abc123", "target_format": "pdf" }'
Merge
curl https://api.perefile.ru/v1/conversions \
  -H "X-API-Key: $PEREFILE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "input": ["file_a", "file_b", "file_c"],
        "operation": "merge",
        "target_format": "pdf"
      }'
Сахар
curl https://api.perefile.ru/v1/conversions \
  -H "X-API-Key: $PEREFILE_KEY" \
  -F "file=@report.docx" \
  -F "target_format=pdf"
Ответ
{
  "id": "3f1c2e4a-0b9d-4c7e-8a1f-2d6b5c4e3a21",
  "status": "queued",
  "created_at": "2026-06-14T09:00:00Z",
  "poll_url": "https://api.perefile.ru/v1/conversions/3f1c2e4a-0b9d-4c7e-8a1f-2d6b5c4e3a21",
  "livemode": true
}

# Параметры конверсии (settings)

Поле settings в POST /v1/conversions - необязательный объект параметров обработки. Набор ключей зависит от операции и категории форматов; нераспознанные ключи игнорируются. Ниже - частые параметры, полный справочник по категориям (схемы *Settings) - в справочнике на странице /developers/reference.

  • PDF: pdf_password (пароль на результат), source_password (пароль исходного PDF), pages и split_mode (разбиение), compress_level (screen/ebook/printer).
  • Изображения: quality (1-100 или low/medium/high/maximum), width и height, maintain_aspect, dpi (растеризация).
  • Видео: video_codec (h264/h265/vp9/av1), video_resolution (1080p/720p/...), video_bitrate, video_fps.
  • Аудио: audio_codec (aac/mp3/opus/flac), audio_bitrate, audio_sample_rate (44100/48000/...).
  • Документы и книги: paper_size, paper_orientation, toc, font_size; OCR: ocr_languages, ocr_quality; архивы: compression_level, password.
Защита PDF паролем
curl https://api.perefile.ru/v1/conversions \
  -H "X-API-Key: $PEREFILE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "input": "file_abc123",
        "target_format": "pdf",
        "settings": { "pdf_password": "s3cret" }
      }'
Сжатие и ресайз изображения
curl https://api.perefile.ru/v1/conversions \
  -H "X-API-Key: $PEREFILE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "input": "file_img1",
        "target_format": "webp",
        "settings": { "quality": 80, "width": 1280, "maintain_aspect": true }
      }'
ℹ️

settings передаётся как есть: неизвестные параметры не вызывают ошибку, а игнорируются. Точные ключи, диапазоны и значения по умолчанию по каждой категории - в справочнике /developers/reference.

# Получение результата

Конверсия выполняется асинхронно. Есть два способа узнать о готовности: поллинг и вебхуки. Короткие конверсии (до ~30 секунд) удобно опрашивать поллингом по poll_url; для долгих - подпишитесь на вебхуки и не держите соединение.

Жизненный цикл и поллинг

  • Статусы: queued (принята) -> processing (обрабатывается) -> completed (готово) либо failed (причина в error.code). Возможна отмена - cancelled. Completed, failed и cancelled - финальные.
  • Опрашивайте poll_url до финального статуса: начните с интервала 1-2 секунды и увеличивайте его (экспоненциальная задержка), не чаще одного раза в секунду.
  • Типичная конверсия занимает секунды, крупные файлы - десятки секунд. Для долгих задач используйте вебхуки, а не удержание соединения.
  1. GET /v1/conversions/{id} возвращает status, progress (0-100) и, при status=completed, download_url с expires_at.
  2. GET /v1/conversions/{id}/download отдаёт результат: 302 на временную ссылку либо поток. Для split-операций результат - один ZIP.
  3. download_url ведёт на наш /v1-эндпоинт и требует X-API-Key - его безопасно передавать (в отличие от presigned-ссылок).
Статус
curl https://api.perefile.ru/v1/conversions/3f1c2e4a-... \
  -H "X-API-Key: $PEREFILE_KEY"
Скачивание
curl -L https://api.perefile.ru/v1/conversions/3f1c2e4a-.../download \
  -H "X-API-Key: $PEREFILE_KEY" \
  -o result.pdf
Ответ
{
  "id": "3f1c2e4a-...",
  "status": "completed",
  "progress": 100,
  "source_format": "docx",
  "target_format": "pdf",
  "created_at": "2026-06-14T09:00:00Z",
  "completed_at": "2026-06-14T09:00:07Z",
  "expires_at": "2026-06-15T09:00:07Z",
  "download_url": "https://api.perefile.ru/v1/conversions/3f1c2e4a-.../download",
  "livemode": true
}

# Вебхуки

Вебхуки - основной способ узнавать о завершении конверсий. Укажите webhook_url для ключа в личном кабинете; при создании вы один раз получите webhook_secret для проверки подписи. События: conversion.completed и conversion.failed.

  • Доставка: POST на ваш URL, таймаут 10 секунд, до 5 повторов с возрастающей паузой (1м, 5м, 30м, 2ч, 6ч).
  • Заголовки: X-Perefile-Event (тип события), X-Livemode и X-Perefile-Signature (HMAC-SHA256 тела ключом webhook_secret).
  • В теле события download_url ведёт на наш /v1-эндпоинт и требует X-API-Key - не presigned-ссылка.
Тело события
{
  "event": "conversion.completed",
  "livemode": true,
  "conversion": {
    "id": "3f1c2e4a-...",
    "status": "completed",
    "source_format": "docx",
    "target_format": "pdf",
    "created_at": "2026-06-14T09:00:00Z",
    "completed_at": "2026-06-14T09:00:07Z",
    "download_url": "https://api.perefile.ru/v1/conversions/3f1c2e4a-.../download"
  }
}
Python
import hmac, hashlib

def verify(body: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature)

# В обработчике вебхука:
#   raw = request.get_data()                       # сырое тело, без парсинга
#   sig = request.headers["X-Perefile-Signature"]
#   if not verify(raw, sig, WEBHOOK_SECRET): abort(400)
Node.js
import crypto from 'node:crypto';

function verify(rawBody, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature),
  );
}

// rawBody - именно сырые байты тела (express.raw), не JSON.parse.
ℹ️

Проверяйте подпись по сырому телу запроса до его разбора. Несовпадение подписи - отклоняйте запрос с кодом 400. Отвечайте 2xx как можно быстрее; тяжёлую обработку выносите в фоновую очередь.

# Песочница

Тестовый ключ (pf_test_) ведёт в песочницу-симулятор: контракт боевой, результат - фиктивный образец. Воркеры не задействуются, квота и счёт не расходуются, livemode равен false. Песочница тестирует интеграцию, а не качество конвертации.

  • Валидации настоящие: проверка по magic-bytes, поддержка пары форматов, лимит размера. Невалидный файл отклоняется.
  • Результат скачивания - статический образец целевого формата с пометкой PEREFILE SANDBOX; split - образец-ZIP.
  • Магические сценарии: имя файла с префиксом fail- даёт событие conversion.failed; slow- - завершение на 30-й секунде.
  • Вебхуки и Idempotency-Key работают по-настоящему. Ограничения от флуда: 60 запросов/мин и 1000 симуляций/день.
cURL
# Тестовый ключ -> песочница
curl https://api.perefile.ru/v1/conversions \
  -H "X-API-Key: pf_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -F "file=@fail-document.docx" \
  -F "target_format=pdf"
# имя с префиксом fail- -> conversion.failed

# Идемпотентность

POST /v1/conversions поддерживает заголовок Idempotency-Key (до 255 символов). Повторный запрос с тем же ключом вернёт ту же самую конверсию (с заголовком Idempotency-Replayed: true) и не спишет квоту повторно. Ключ живёт 24 часа. Используйте его при повторах после сетевых сбоев.

cURL
curl https://api.perefile.ru/v1/conversions \
  -H "X-API-Key: $PEREFILE_KEY" \
  -H "Idempotency-Key: order-9c3f-2026-06-14" \
  -H "Content-Type: application/json" \
  -d '{ "input": "file_abc123", "target_format": "pdf" }'

# Лимиты и квота

Единица учёта - конверсия (merge нескольких файлов = одна конверсия). Пакет действует на окно подписки. Текущее состояние окна возвращает GET /v1/me, а каждый ответ на создание конверсии несёт заголовки квоты.

  • X-Quota-Limit, X-Quota-Used, X-Quota-Reset - предел, использовано и время сброса окна.
  • Предохранители: лимит запросов в минуту, дневной предел и предел одновременных конверсий (max_concurrent).
  • При исчерпании или превышении лимита - ответ 429 с Retry-After (секунд до конца окна) и подробностями квоты.
429
{
  "error_code": "quota_exceeded",
  "message": "Пакет конверсий на текущее окно исчерпан",
  "livemode": true,
  "retry_after": 81234,
  "quota": { "limit": 1000, "used": 1000, "reset_at": "2026-07-12T09:00:00Z" },
  "upgrade_url": "https://perefile.ru/pricing",
  "request_id": "req_7f3a..."
}

# Модель оплаты

Тариф включает пакет конверсий на окно подписки. Сверх пакета возможен перерасход с доплатой за конверсию по ставке тарифа - счёт выставляется при закрытии окна. Перерасход управляется переключателем в личном кабинете; при выключенном перерасходе после исчерпания пакета запросы получают 429.

  • Веб-конверсии и песочница в квоту API не входят.
  • Достигнув потолка перерасхода, запросы получают 429 - выход через апгрейд тарифа.
  • Актуальные пакеты и цены - на странице тарифов; история счетов - в личном кабинете.

# Ошибки

Ошибки возвращаются с соответствующим HTTP-статусом и единым телом: error_code (машиночитаемый код), message (человекочитаемое описание), livemode, а также docs_url и request_id. Реагируйте на error_code, а не на текст message; указывайте request_id при обращении в поддержку. Полный каталог кодов с HTTP-статусами - в справочнике на странице /developers/reference.

Как реагировать по статусам

  • 401 (invalid_api_key, api_key_revoked, api_key_expired) - проверьте заголовок и ключ, при необходимости создайте новый.
  • 403 (plan_does_not_include_api, overage_unpaid) - подключите тариф с API-доступом или оплатите счёт перерасхода.
  • 400 (invalid_settings, unsupported_conversion, file_too_large, invalid_url и др.) - исправьте запрос; повтор без изменений снова вернёт ошибку.
  • 404 (not_found) - проверьте идентификатор и что ресурс принадлежит этому ключу.
  • 409 (idempotency_in_progress) - запрос с этим Idempotency-Key ещё обрабатывается; повторите позже с тем же ключом.
  • 429 (quota_exceeded, rate_limit_exceeded, too_many_active_conversions, quota_cap_reached) - дождитесь Retry-After, сверьтесь с GET /me, при исчерпании пакета смените тариф.
  • 5xx (internal_error, service_unavailable) - временный сбой; повторите с экспоненциальной задержкой.
Тело ошибки
{
  "error_code": "file_not_found",
  "message": "Файл не найден или срок его жизни истёк",
  "livemode": true,
  "docs_url": "https://perefile.ru/developers#files",
  "request_id": "req_7f3a9c..."
}

# Версионирование

Версия зафиксирована в пути - /v1. В рамках v1 мы вносим только обратносовместимые изменения: добавляем новые эндпоинты, поля и значения перечислений. Закладывайтесь на это: игнорируйте незнакомые поля в ответах и не полагайтесь на их порядок.

  • Несовместимые изменения выйдут только под новой версией пути (например, /v2).
  • Полный машиночитаемый контракт - интерактивная справка OpenAPI на странице /developers/reference (сырая спецификация: /openapi-public-v1.yaml).
  • О предстоящих изменениях и сроках поддержки мы сообщаем заранее по контактам аккаунта.

Готовы начать?

Создайте API-ключ в личном кабинете и попробуйте запросы в песочнице - без расхода квоты.

Перейти в личный кабинет