# MkPDF — agent guide

MkPDF (https://mkpdf.ru) is a Russian-language service for working with PDF: 22 tools in the browser and the same operations over an HTTP API. This file is an operational guide; the exact request/response schema is in the OpenAPI spec (https://mkpdf.ru/openapi.json).

## Quick facts

- API base URL: `https://api.mkpdf.ru`; reserve host `https://api.lt.mkpdf.ru` (see below)
- Auth: `Authorization: Bearer <API key>` on every `/v1/*` request
- Request bodies: `multipart/form-data` (file operations) or `application/json` (HTML/URL → PDF)
- Response body: the result file itself (not a JSON wrapper), except OCR (JSON) and `deliver: "url"` (JSON with a link)
- Errors: JSON `{"error": "..."}` plus an HTTP status
- Interface language of the site and error messages: mostly Russian; the API contract is language-independent

## Authentication

1. A human signs in at https://mkpdf.ru/login (emailed one-time code or Yandex ID, no password) and creates an API key in the dashboard: https://mkpdf.ru/dashboard.
2. Send the key as `Authorization: Bearer <key>`. Missing or wrong key → `401`.
3. An agent cannot create an account or a key on its own: ask the user for a key and keep it in a secret, never in a prompt log or a URL.

Without a key you can only use the web tools in a browser (up to 10 operations per day per IP). The `/v1/*` API always needs a key.

## Reserve host

If `https://api.mkpdf.ru` is unreachable (connection error or timeout), the same API is available at `https://api.lt.mkpdf.ru` through a proxy in Latvia. Same paths, same parameters, same API key. Use it only as a fallback: try the main host first, switch on network failure, and expect some extra latency. API errors (`400`, `401`, `413`, `422`, `429`) mean the same on both hosts and are not fixed by switching. For async OCR, keep polling the host that created the job unless it goes down.

## Choosing an operation

| The user wants to… | Call |
|---|---|
| turn an HTML string/template into a PDF | `POST /v1/convert/html` (JSON) |
| save a live web page (with JavaScript) as a PDF | `POST /v1/convert/url` (JSON, public http/https only) |
| convert Word/Excel/PowerPoint/ODF/RTF/TXT/CSV to PDF | `POST /v1/convert/office` |
| make a PDF from pictures (JPG, PNG, GIF, BMP, TIFF) | `POST /v1/convert/image` |
| merge several PDFs into one | `POST /v1/merge` |
| take some pages out or cut a PDF into parts | `POST /v1/pdf/split` |
| get editable text from a PDF with a text layer | `/v1/pdf/to-word` (formatted .docx), `/v1/pdf/to-text` (plain text), `/v1/pdf/to-html` |
| render PDF pages as pictures | `/v1/pdf/to-png`, `/v1/pdf/to-jpg` |
| read text from a scan or a photo | `POST /v1/ocr/image` (one image, sync); `POST /v1/ocr/document` (multi-page PDF or large file, async) |
| rotate, crop, number pages, stamp a watermark | `/v1/pdf/rotate`, `/v1/pdf/crop`, `/v1/pdf/page-numbers`, `/v1/pdf/watermark` |
| shrink a PDF | `POST /v1/pdf/compress` (only re-encodes embedded images) |
| set or remove a password | `POST /v1/pdf/protect`, `POST /v1/pdf/unlock` |
| add text, images or rectangles on top of pages; place a signature image | `POST /v1/pdf/edit` |
| long-term archive format | `POST /v1/pdf/to-pdfa` |

Rule of thumb: if the PDF is a scan (no selectable text), run OCR first — the text extraction and Word/HTML conversions work from the text layer.

## Endpoints

### Конвертация в PDF

- `POST /v1/convert/html` — HTML → PDF: Свой HTML-шаблон — в точный PDF, с сохранением вёрстки. Web: https://mkpdf.ru/tools/html-to-pdf
- `POST /v1/convert/url` — URL → PDF: Любая веб-страница — в PDF, вместе с JS и динамикой. Web: https://mkpdf.ru/tools/url-to-pdf
- `POST /v1/convert/office` — Word / Excel / PowerPoint → PDF: Word, Excel, PowerPoint, ODT, RTF, TXT, CSV — в PDF без установки офисного пакета. Web: https://mkpdf.ru/tools/docx-to-pdf
- `POST /v1/convert/image` — JPG / PNG → PDF: Соберите фото и сканы в один PDF — по странице на изображение. Web: https://mkpdf.ru/tools/image-to-pdf

### Конвертация из PDF

- `POST /v1/pdf/to-word` — PDF → Word: Превратите PDF в редактируемый документ Word (.docx). Web: https://mkpdf.ru/tools/pdf-to-word
- `POST /v1/pdf/to-png` — PDF → PNG: Каждая страница PDF — отдельным PNG-изображением. Web: https://mkpdf.ru/tools/pdf-to-png
- `POST /v1/pdf/to-jpg` — PDF → JPG: Страницы PDF — в лёгкие JPG-изображения. Web: https://mkpdf.ru/tools/pdf-to-jpg
- `POST /v1/pdf/to-html` — PDF → HTML: PDF в один HTML-файл: текст остаётся текстом. Web: https://mkpdf.ru/tools/pdf-to-html
- `POST /v1/pdf/to-text` — PDF → TXT: Достаньте весь текст из PDF в обычный .txt. Web: https://mkpdf.ru/tools/pdf-to-text

### Работа с PDF

- `POST /v1/merge` — Объединить PDF: Склейте несколько PDF в один файл в нужном порядке. Web: https://mkpdf.ru/tools/merge-pdf
- `POST /v1/pdf/split` — Разделить PDF: Выделите нужные страницы или разбейте файл на части. Web: https://mkpdf.ru/tools/split-pdf
- `POST /v1/pdf/rotate` — Повернуть PDF: Поверните все страницы на 90°, 180° или 270°. Web: https://mkpdf.ru/tools/rotate-pdf
- `POST /v1/pdf/compress` — Сжать PDF: Уменьшите размер PDF с картинками и сканами. Web: https://mkpdf.ru/tools/compress-pdf

### Редактирование и подпись

- `POST /v1/pdf/watermark` — Водяной знак в PDF: Надпись на страницах: одна или мозаикой, под 45°, горизонтально или вертикально. Web: https://mkpdf.ru/tools/watermark-pdf
- `POST /v1/pdf/page-numbers` — Номера страниц в PDF: Проставьте номера страниц: положение, формат, без первой. Web: https://mkpdf.ru/tools/page-numbers-pdf
- `POST /v1/pdf/crop` — Обрезать PDF: Обрежьте поля страниц — с предпросмотром. Web: https://mkpdf.ru/tools/crop-pdf
- `POST /v1/pdf/edit` — Подписать PDF: Нарисуйте или загрузите подпись и поставьте на страницу. Web: https://mkpdf.ru/tools/sign-pdf
- `POST /v1/pdf/edit` — Редактор PDF: Добавьте текст, картинки и закраску прямо на страницы. Web: https://mkpdf.ru/tools/edit-pdf

### Защита и оформление

- `POST /v1/pdf/protect` — Защитить PDF паролем: Поставьте пароль на открытие PDF. Web: https://mkpdf.ru/tools/protect-pdf
- `POST /v1/pdf/to-pdfa` — PDF → PDF/A: Приведите PDF к формату долговременного хранения. Web: https://mkpdf.ru/tools/pdf-to-pdfa
- `POST /v1/pdf/unlock` — Снять пароль с PDF: Уберите пароль или запрет на копирование и печать. Web: https://mkpdf.ru/tools/unlock-pdf

### Распознавание

- `POST /v1/ocr/image` — Изображение → текст: Распознайте текст с фото, скана или PDF — с помощью OCR. Web: https://mkpdf.ru/tools/image-to-text

## Files: types, sizes, limits

- Input file: up to 50 MB (`multipart/form-data`, field `file`; repeated field `files` for merge and images).
- Pages: up to 100 per PDF for conversions, up to 500 for edits. Over the limit → `413`.
- Images → PDF: up to 30 files, 50 MB in total; JPG/JPEG, PNG, GIF, BMP, TIFF (WebP is not supported).
- OCR: `/v1/ocr/image` takes one image up to 10 MB (synchronous); `/v1/ocr/document` takes a PDF or an image set up to 50 MB (asynchronous).
- `/v1/pdf/edit`: up to 300 elements in `ops`, an embedded image up to 8 MB (PNG or JPEG, base64).
- Office input: .docx/.doc, .xlsx/.xls, .pptx/.ppt, .odt/.ods/.odp, .rtf, .txt, .csv.

Result content types:

| Operation | Response |
|---|---|
| most PDF operations, HTML/URL/Office/images → PDF | `application/pdf` |
| `/v1/pdf/to-word` | `application/vnd.openxmlformats-officedocument.wordprocessingml.document` (file name in `Content-Disposition`) |
| `/v1/pdf/to-png`, `/v1/pdf/to-jpg` | `image/png` / `image/jpeg` for one page, `application/zip` (`page-1.png`, …) for several |
| `/v1/pdf/split` | `application/pdf` (`mode=pages`) or `application/zip` (`mode=intervals`) |
| `/v1/pdf/to-html` | `text/html; charset=utf-8` (one self-contained file) |
| `/v1/pdf/to-text` | `text/plain; charset=utf-8` |
| `/v1/ocr/image` | JSON `{"text": "...", "lines": [{"text", "score", "box": [xMin, yMin, xMax, yMax]}]}` |
| `/v1/ocr/document` | `202` with JSON `{"job_id": "...", "status": "queued"}` |

Always check the `Content-Type` of the response before treating the body as a file: on an error it is JSON.

## Limits and quota

- Rate limit: 5 requests per second per API key, bursts up to 20. Over it → `429`; back off and retry.
- Quota: the free plan is 50 successful operations per month per account (shared by all its keys). Over it → `429`.
- Only successful operations are counted: a bad request or an engine failure costs nothing. For async OCR the operation is counted when the job finishes successfully.
- Every response carries `X-RateLimit-Limit` and `X-RateLimit-Remaining`.
- Paid plans (Developer, Startup, Business — a higher monthly limit) are bought by the account owner in the dashboard (https://mkpdf.ru/dashboard/billing) by card or SBP through ЮKassa; one payment is 30 days, there is no auto-renewal, and after that the account returns to the free plan. An agent cannot pay. Whether payments are switched on is `GET https://api.mkpdf.ru/billing/config` → `{"payments_enabled": true|false}`; while it is false the service is free only — do not promise prices or higher limits.

## Errors

Body: `{"error": "human-readable message"}`. Branch on the HTTP status, not on the message text (the text may change).

| Status | Meaning | What to do |
|---|---|---|
| 400 | malformed request or a bad parameter | fix the request; do not retry unchanged |
| 401 | missing or invalid API key | ask the user for a valid key |
| 413 | too many pages | split the file (`/v1/pdf/split`) and process the parts |
| 422 | PDF is password-protected or corrupt, or wrong password (`unlock`) | ask for the password or a different file |
| 429 | rate limit or monthly quota | wait and retry with backoff; if the quota is spent, tell the user |
| 502 | engine failure | retry once or twice, then report |
| 503 | tool temporarily unavailable | retry later |

## Examples

Office document → PDF:

```bash
curl -X POST https://api.mkpdf.ru/v1/convert/office \
  -H "Authorization: Bearer $MKPDF_API_KEY" \
  -F "file=@report.docx" \
  --output report.pdf
```

HTML → PDF (JSON body, A4 with margins):

```bash
curl -X POST https://api.mkpdf.ru/v1/convert/html \
  -H "Authorization: Bearer $MKPDF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"html": "<h1>Invoice 482</h1>", "options": {"format": "A4", "margin": "16mm"}}' \
  --output invoice.pdf
```

Merge PDFs (order of the `files` fields is the order in the result):

```bash
curl -X POST https://api.mkpdf.ru/v1/merge \
  -H "Authorization: Bearer $MKPDF_API_KEY" \
  -F "files=@part1.pdf" -F "files=@part2.pdf" \
  --output merged.pdf
```

Pages 1–3 and 7 of a PDF:

```bash
curl -X POST https://api.mkpdf.ru/v1/pdf/split \
  -H "Authorization: Bearer $MKPDF_API_KEY" \
  -F "file=@in.pdf" -F "mode=pages" -F "span=1-3, 7" \
  --output extract.pdf
```

Check the status code yourself when scripting: use `curl --fail-with-body` (or inspect `%{http_code}` and `Content-Type`), otherwise an error JSON is saved into the output file.

## Async jobs: OCR of documents

```bash
# 1. submit — answers 202 immediately
curl -X POST https://api.mkpdf.ru/v1/ocr/document \
  -H "Authorization: Bearer $MKPDF_API_KEY" -F "file=@scan.pdf"
# → {"job_id": "b3f1...", "status": "queued"}

# 2. poll
curl https://api.mkpdf.ru/v1/jobs/b3f1... -H "Authorization: Bearer $MKPDF_API_KEY"
# → {"id": "b3f1...", "status": "done", "result": {"pages": [{"page": 1, "text": "...", "lines": [...]}]}}
```

- `status` is one of `queued`, `processing`, `done`, `failed`. Stop polling on `done` or `failed`; on `failed` the body has `error` instead of `result`.
- The API does not publish a recommended polling interval. Poll every 2–5 seconds with a growing delay and a sensible overall timeout, well within the rate limit.
- A job is visible only to the account that created it; another account or an unknown id gets `404`.
- The quota is spent once, when the job succeeds.

## Downloading results and what happens to files

- By default the result comes back in the body of the same response; there is nothing to download separately or clean up.
- For `/v1/convert/html` and `/v1/convert/url` you can send `"deliver": "url"` and get `{"url": "...", "expires_in": "1h"}` instead — a temporary link valid for one hour. It works only when the deployment has file storage configured; otherwise stay with the default inline delivery.
- Uploaded files and results are processed for the duration of the request and are not kept afterwards, and file contents are not written to logs in the clear. Async OCR results are kept so that they can be fetched from `/v1/jobs/{id}`; the retention period is not specified.
- Passwords passed to `protect`/`unlock` are not stored or logged.

## What it does not do

- It does not edit text that already exists in a PDF: the editor places new text, images and shapes on top of pages. Use PDF → Word to get editable text.
- "Sign PDF" places an image of a signature. It is not a qualified electronic signature (КЭП).
- It does not guess passwords: unlock needs the password (or removes owner restrictions from a file that opens freely).
- Covering data with a rectangle hides it visually but does not remove the underlying text from the file.
- PDF → Word keeps paragraphs, fonts, bold/italic, colours, pictures and column tab stops; complex tables and multi-column layouts are approximated.
- Compression only re-encodes images: a text-only PDF will barely shrink.
- There is no formal SLA (no guaranteed availability percentage).

## Machine-readable resources

- OpenAPI 3.1 spec (JSON): https://mkpdf.ru/openapi.json (same content as https://mkpdf.ru/openapi.yaml)
- Postman collection and environments (main and reserve host): https://mkpdf.ru/postman/mkpdf.postman_collection.json
- Human API reference with curl/Python/Go/JavaScript examples: https://mkpdf.ru/docs and https://mkpdf.ru/docs/reference
- Short index for LLMs: https://mkpdf.ru/llms.txt
- What an agent may do on the site: https://mkpdf.ru/agents.txt
- Sitemap: https://mkpdf.ru/sitemap.xml
- This file: https://mkpdf.ru/agent.md

## Contact and operator

Support: support@mkpdf.ru
Operator: Индивидуальный предприниматель Астанов Эмиль Мурадович, INN 772346438797, OGRNIP 324774600438202
Legal documents: https://mkpdf.ru/legal/terms, https://mkpdf.ru/legal/offer, https://mkpdf.ru/legal/privacy
