# Введение
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 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.
# 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" }' 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 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" }' 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.
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 секунды и увеличивайте его (экспоненциальная задержка), не чаще одного раза в секунду.
- Типичная конверсия занимает секунды, крупные файлы - десятки секунд. Для долгих задач используйте вебхуки, а не удержание соединения.
- GET /v1/conversions/{id} возвращает status, progress (0-100) и, при status=completed, download_url с expires_at.
- GET /v1/conversions/{id}/download отдаёт результат: 302 на временную ссылку либо поток. Для split-операций результат - один ZIP.
- 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"
}
} 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) 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 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 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 (секунд до конца окна) и подробностями квоты.
{
"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-ключ в личном кабинете и попробуйте запросы в песочнице - без расхода квоты.
Перейти в личный кабинет