File Conversion API & Scraper
The File Convert API handles PDF and document operations as clean JSON.
🤖 Using an AI assistant? Copy this link into ChatGPT / Claude / Cursor — it reads every endpoint and parameter instantly and tells you if this API fits your use case.
The primary pdf_extract_text endpoint returns per-page text, page count, character count, empty-page count and a scanned flag, and you can read metadata, merge, split, rotate, convert PDF to images and images to PDF. It is built for document pipelines and data extraction that need PDF operations without a desktop tool. One ReefAPI key, one shared credit pool, the standard envelope.
The format matrix: what each action accepts and what it can emit
Every action declares its own accepted inputs and targets, and a pair that is not in this table fails before any work happens. The formats action returns this same matrix live, including the per-action caps, so you can check a pair programmatically instead of guessing.
| Action(s) | Accepts | Targets and caps |
|---|---|---|
| the 12 pdf_* actions | pdf, plus text or json where the action is a reader. Caps: extract 300 pages, redact 50 pages, merge 20 files, split 100 parts. | |
| pdf_to_images | png, jpg, webp. Max 20 pages per call, dpi 36 to 300. | |
| images_to_pdf | png, jpg, webp, gif, tiff, bmp | pdf. Max 20 images, page_size auto, a4 or letter. |
| the 7 image_* actions | png, jpg, webp, gif, tiff, bmp, avif, heif | jpg, png, webp, tiff, bmp, gif, avif (optimize: auto, jpg, png, webp, avif; thumbnail: webp, jpg, png). Caps: 64 megapixels, 20000 px per side, thumbnail box 2048. |
| office_convert | docx, doc, odt, rtf, pptx, ppt, odp, xlsx, xls, ods, html, text, csv, md | pdf, html, txt, csv, docx |
| doc_to_markdown | pdf, docx, pptx, xlsx, html | md. Max 150 pages. |
| extract_tables | pdf, xlsx, docx, html | json, csv. Max 50 tables. |
| ocr_image and ocr_pdf | images / pdf | text, and searchable_pdf from ocr_pdf. Languages eng, deu, fra, spa, tur. ocr_pdf caps at 10 pages. |
| audio_extract | mp4, webm, mkv, avi | mp3, m4a, wav, flac, ogg, opus. Max 7200 seconds. |
| audio_convert | mp3, wav, flac, ogg, m4a | mp3, m4a, wav, flac, ogg, opus. Max 7200 seconds. |
| data_convert | csv, json, xml, yaml, xlsx, text | csv, json, xml, yaml, xlsx. Max 200,000 rows. |
| media_probe | mp4, webm, mkv, avi, mp3, wav, flac, ogg, m4a | json only: container, duration, bitrate, per-stream codec, sample rate and resolution. |
Deliberately out of scope: video transcoding, CAD (dwg, dxf), fonts, ebooks (epub, mobi), archives (zip, rar), iWork documents, email (eml, msg), and reconstructing a PDF back into docx or pptx. Asking for one of those is a miss rather than a bug.
Real request and response JSON
Captured from the indexed primary action, pdf_extract_text, on .
{
"method": "POST",
"url": "https://api.reefapi.com/file-convert/v1/pdf_extract_text",
"headers": {
"x-api-key": "$REEF_KEY",
"content-type": "application/json"
},
"body": {
"file_b64": "JVBERi0xLjQKMSAwIG9iajw8L1R5cGUvQ2F0YWxvZy9QYWdlcyAyIDAgUj4+ZW5kb2JqCjIgMCBvYmo8PC9UeXBlL1BhZ2VzL0tpZHNbMyAwIFJdL0NvdW50IDE+PmVuZG9iagozIDAgb2JqPDwvVHlwZS9QYWdlL1BhcmVudCAyIDAgUi9NZWRpYUJveFswIDAgNjEyIDc5Ml0vQ29udGVudHMgNCAwIFIvUmVzb3VyY2VzPDwvRm9udDw8L0YxIDUgMCBSPj4+Pj4+ZW5kb2JqCjQgMCBvYmo8PC9MZW5ndGggNTQ+PnN0cmVhbQpCVCAvRjEgMTggVGYgNzIgNzIwIFRkIChSZWVmQVBJIGdvbGRlbiB0ZXN0IFBERikgVGogRVQKZW5kc3RyZWFtZW5kb2JqCjUgMCBvYmo8PC9UeXBlL0ZvbnQvU3VidHlwZS9UeXBlMS9CYXNlRm9udC9IZWx2ZXRpY2E+PmVuZG9iagp4cmVmCjAgNgowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMDAwMDkgMDAwMDAgbiAKMDAwMDAwMDA1MiAwMDAwMCBuIAowMDAwMDAwMTAxIDAwMDAwIG4gCjAwMDAwMDAyMTEgMDAwMDAgbiAKMDAwMDAwMDMxMCAwMDAwMCBuIAp0cmFpbGVyPDwvU2l6ZSA2L1Jvb3QgMSAwIFI+PgpzdGFydHhyZWYKMzcxCiUlRU9GCg=="
}
}{
"ok": true,
"meta": {
"api": "file-convert",
"endpoint": "pdf_extract_text",
"mode": "live",
"latency_ms": 531.5,
"record_count": 1,
"bytes": 550,
"cache_hit": false,
"input_format": "pdf",
"input_bytes": 550,
"output_bytes": 0,
"input_source": "base64"
},
"data": {
"pages": [
{
"page": 1,
"text": "ReefAPI golden test PDF"
}
],
"page_count": 1,
"pages_extracted": 1,
"characters": 23,
"empty_pages": 0,
"likely_scanned": false,
"stop_reason": "complete"
}
}What the File Conversion API does
| Action | Description | Concrete use case | Key params |
|---|---|---|---|
| pdf_extract_text | Extract text from a PDF (per page). mode=layout preserves visual alignment (pdfplumber); mode=plain is fastest. Flags likely-scanned PDFs. | Ops teams call pdf_extract_text to extract text from a PDF (per page). | none |
| pdf_metadata | PDF document properties: title/author/dates/producer, page count & size, encryption flag, AcroForm field count. | Developer tools call pdf_metadata to get pDF document properties. | none |
| pdf_merge | Merge 2-20 PDFs into one (input order preserved). Output delivery: each produced file ≤10MB comes inline as base64 (files[].file_b64); 10-50MB comes as a one-time download token (files[].download_path, 30min TTL); >50MB total is rejected. | Validation workflows call pdf_merge to get merge 2-20 PDFs into one (input order preserved). | none |
| pdf_split | Split a PDF: pages='2-5,8' extracts those pages into one PDF; chunk_size=N splits the whole document into N-page parts (max 100 parts). Output delivery: each produced file ≤10MB comes inline as base64 (files[].file_b64); 10-50MB comes as a one-time download token (files[].download_path, 30min TTL); >50MB total is rejected. | Data-quality teams call pdf_split to get split a PDF. | none |
| pdf_rotate | Rotate pages clockwise by 90/180/270° (all pages or a range). Output delivery: each produced file ≤10MB comes inline as base64 (files[].file_b64); 10-50MB comes as a one-time download token (files[].download_path, 30min TTL); >50MB total is rejected. | Ops teams call pdf_rotate to get rotate pages clockwise by 90/180/270° (all pages or a range). | none |
| pdf_to_images | Render PDF pages to PNG/JPG/WebP (pypdfium2). Max 20 pages per call, dpi ≤ 300. Output delivery: each produced file ≤10MB comes inline as base64 (files[].file_b64); 10-50MB comes as a one-time download token (files[].download_path, 30min TTL); >50MB total is rejected. | Developer tools call pdf_to_images to render PDF pages to PNG/JPG/WebP (pypdfium2). | none |
| images_to_pdf | Combine 1-20 images into a single PDF (one page per image; page_size=a4/letter centers each image on a standard page). Output delivery: each produced file ≤10MB comes inline as base64 (files[].file_b64); 10-50MB comes as a one-time download token (files[].download_path, 30min TTL); >50MB total is rejected. | Validation workflows call images_to_pdf to get combine 1-20 images into a single PDF (one page per image; page_size=a4/letter centers each i…. | none |
| pdf_watermark | Stamp a text or image watermark over pages (true alpha overlay; diagonal or centred). Output delivery: each produced file ≤10MB comes inline as base64 (files[].file_b64); 10-50MB comes as a one-time download token (files[].download_path, 30min TTL); >50MB total is rejected. | Data-quality teams call pdf_watermark to get stamp a text or image watermark over pages (true alpha overlay; diagonal or centred). | none |
| pdf_fill_form | AcroForm filling. Without 'fields' → lists the form fields (discovery). With 'fields' → fills and returns the PDF (NeedAppearances set). Output delivery: each produced file ≤10MB comes inline as base64 (files[].file_b64); 10-50MB comes as a one-time download token (files[].download_path, 30min TTL); >50MB total is rejected. | Ops teams call pdf_fill_form to get acroForm filling. | none |
| pdf_redact | TRUE redaction: target pages are re-rendered with the matches blacked out and REBUILT — original text/fonts/layers destroyed, then verified by re-extraction (output withheld if any remnant). Redacted pages lose selectable text. Find by 'terms' and/or explicit 'areas'. Output delivery: each produced file ≤10MB comes inline as base64 (files[].file_b64); 10-50MB comes as a one-time download token (files[].download_path, 30min TTL); >50MB total is rejected. | Developer tools call pdf_redact to get tRUE redaction. | none |
| pdf_compress | Shrink a PDF: stream recompression + embedded-image re-encode (level=low/balanced/strong; strong also caps image resolution). Output delivery: each produced file ≤10MB comes inline as base64 (files[].file_b64); 10-50MB comes as a one-time download token (files[].download_path, 30min TTL); >50MB total is rejected. | Validation workflows call pdf_compress to get shrink a PDF. | none |
| pdf_protect | Encrypt a PDF with AES-256 (user password to open; optional owner password). Output delivery: each produced file ≤10MB comes inline as base64 (files[].file_b64); 10-50MB comes as a one-time download token (files[].download_path, 30min TTL); >50MB total is rejected. | Data-quality teams call pdf_protect to get encrypt a PDF with AES-256 (user password to open; optional owner password). | user_password |
| pdf_unlock | Remove encryption from a PDF — REQUIRES the correct password (we never crack or bypass protection). Output delivery: each produced file ≤10MB comes inline as base64 (files[].file_b64); 10-50MB comes as a one-time download token (files[].download_path, 30min TTL); >50MB total is rejected. | Ops teams call pdf_unlock to get remove encryption from a PDF. | password |
| pdf_repair | Best-effort structural repair (broken xref/trailer/stream lengths) via a tolerant qpdf parse + clean rewrite. Output delivery: each produced file ≤10MB comes inline as base64 (files[].file_b64); 10-50MB comes as a one-time download token (files[].download_path, 30min TTL); >50MB total is rejected. | Developer tools call pdf_repair to get best-effort structural repair (broken xref/trailer/stream lengths) via a tolerant qpdf parse…. | none |
| image_convert | Convert between raster formats (jpg/png/webp/tiff/bmp/gif/avif; animated gif/webp preserved where the target supports it). Output delivery: each produced file ≤10MB comes inline as base64 (files[].file_b64); 10-50MB comes as a one-time download token (files[].download_path, 30min TTL); >50MB total is rejected. | Validation workflows call image_convert to convert between raster formats (jpg/png/webp/tiff/bmp/gif/avif; animated gif/webp preserved w…. | to |
| image_resize | Resize with fit=contain (aspect kept, fits inside box) / cover (fills+crops) / stretch. No upscaling unless upscale=true. Output delivery: each produced file ≤10MB comes inline as base64 (files[].file_b64); 10-50MB comes as a one-time download token (files[].download_path, 30min TTL); >50MB total is rejected. | Data-quality teams call image_resize to get resize with fit=contain (aspect kept, fits inside box) / cover (fills+crops) / stretch. | none |
| image_optimize | Smart perceptual compression (TinyPNG-style): binary-searches the lowest quality whose decoded result stays visually equal to the source, per a per-channel error budget (effort=low/balanced/strong). Optionally convert to webp/avif while optimizing. Never returns a bigger file. Output delivery: each produced file ≤10MB comes inline as base64 (files[].file_b64); 10-50MB comes as a one-time download token (files[].download_path, 30min TTL); >50MB total is rejected. | Ops teams call image_optimize to get smart perceptual compression (TinyPNG-style). | none |
| image_thumbnail | Fast thumbnail (16-2048px box; square=true centre-crops to a square). Output delivery: each produced file ≤10MB comes inline as base64 (files[].file_b64); 10-50MB comes as a one-time download token (files[].download_path, 30min TTL); >50MB total is rejected. | Developer tools call image_thumbnail to get fast thumbnail (16-2048px box; square=true centre-crops to a square). | none |
| image_metadata | Read image facts + EXIF (+GPS) — and with strip=true return a copy with ALL metadata removed (EXIF/GPS/XMP/ICC). | Validation workflows call image_metadata to read image facts + EXIF (+GPS). | none |
| image_rotate | Rotate (90/180/270 clockwise) and/or flip (horizontal/vertical). Output delivery: each produced file ≤10MB comes inline as base64 (files[].file_b64); 10-50MB comes as a one-time download token (files[].download_path, 30min TTL); >50MB total is rejected. | Data-quality teams call image_rotate to get rotate (90/180/270 clockwise) and/or flip (horizontal/vertical). | none |
| image_crop | Crop a pixel box (x, y from top-left + width × height). Output delivery: each produced file ≤10MB comes inline as base64 (files[].file_b64); 10-50MB comes as a one-time download token (files[].download_path, 30min TTL); >50MB total is rejected. | Ops teams call image_crop to get crop a pixel box (x, y from top-left + width × height). | width, height |
| doc_to_markdown | Document → clean markdown for RAG/agents. PDF uses a layout engine (headings from font sizes, real pipe-tables, reading order); docx/pptx/xlsx/html via MarkItDown. mode=fast trades structure for speed. Output delivery: each produced file ≤10MB comes inline as base64 (files[].file_b64); 10-50MB comes as a one-time download token (files[].download_path, 30min TTL); >50MB total is rejected. | Developer tools call doc_to_markdown to get document → clean markdown for RAG/agents. | none |
| extract_tables | Pull every table out of a PDF / xlsx / docx / html as JSON rows (+optional CSV files). Max 50 tables. | Validation workflows call extract_tables to pull every table out of a PDF / xlsx / docx / html as JSON rows (+optional CSV files). | none |
| ocr_image | OCR an image → text + word count + confidence (tesseract 5, printed text; languages: eng/deu/fra/spa/tur, combinable). | Data-quality teams call ocr_image to get oCR an image → text + word count + confidence (tesseract 5, printed text; languages. | none |
| ocr_pdf | OCR a scanned PDF: output=text → per-page text+confidence; output=searchable_pdf → image+invisible-text-layer PDF. OCR-light: max 10 pages per call (use 'pages' to window). Output delivery: each produced file ≤10MB comes inline as base64 (files[].file_b64); 10-50MB comes as a one-time download token (files[].download_path, 30min TTL); >50MB total is rejected. | Ops teams call ocr_pdf to get oCR a scanned PDF. | none |
| office_convert | Office → PDF (and html/txt; spreadsheets also → csv; text docs also → docx) via LibreOffice headless — docx/doc/odt/rtf/pptx/ppt/odp/xlsx/xls/ods/html/markdown/txt/csv in. Fonts: Noto (CJK/RTL) + Liberation (Arial/Times metrics). Output delivery: each produced file ≤10MB comes inline as base64 (files[].file_b64); 10-50MB comes as a one-time download token (files[].download_path, 30min TTL); >50MB total is rejected. | Developer tools call office_convert to get office → PDF (and html/txt; spreadsheets also → csv; text docs also → docx) via LibreOffice h…. | none |
| audio_extract | Extract the audio track from a video (mp4/webm/mkv/avi) → mp3 (default) / m4a / wav / flac / ogg / opus. Stream-copies losslessly when the codec already matches the target. NOT a video transcoder (phase-2). Output delivery: each produced file ≤10MB comes inline as base64 (files[].file_b64); 10-50MB comes as a one-time download token (files[].download_path, 30min TTL); >50MB total is rejected. | Validation workflows call audio_extract to extract the audio track from a video (mp4/webm/mkv/avi) → mp3 (default) / m4a / wav / flac /…. | none |
| audio_convert | Convert between audio formats (mp3/wav/flac/ogg/m4a in → mp3/m4a/wav/flac/ogg/opus out; ffmpeg LGPL build). Output delivery: each produced file ≤10MB comes inline as base64 (files[].file_b64); 10-50MB comes as a one-time download token (files[].download_path, 30min TTL); >50MB total is rejected. | Data-quality teams call audio_convert to convert between audio formats (mp3/wav/flac/ogg/m4a in → mp3/m4a/wav/flac/ogg/opus out; ffmpe…. | to |
| media_probe | ffprobe metadata for any audio/video file: container, duration, bitrate, per-stream codec/sample-rate/resolution, curated tags. | Ops teams call media_probe to get ffprobe metadata for any audio/video file. | none |
| data_convert | Deterministic data-format conversion: CSV ↔ JSON ↔ XML ↔ YAML ↔ Excel(xlsx) (any direction; tabular targets need tabular-shaped input — clean error otherwise). 200k-row cap. Output delivery: each produced file ≤10MB comes inline as base64 (files[].file_b64); 10-50MB comes as a one-time download token (files[].download_path, 30min TTL); >50MB total is rejected. | Developer tools call data_convert to get deterministic data-format conversion. | to |
| formats | Capability matrix: every action with its accepted input formats, targets and caps — machine-readable (the Zamzar /formats equivalent). | Validation workflows call formats to get capability matrix. | none |
Call pdf_extract_text from your stack
curl -X POST https://api.reefapi.com/file-convert/v1/pdf_extract_text \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"file_b64":"JVBERi0xLjQKMSAwIG9iajw8L1R5cGUvQ2F0YWxvZy9QYWdlcyAyIDAgUj4+ZW5kb2JqCjIgMCBvYmo8PC9UeXBlL1BhZ2VzL0tpZHNbMyAwIFJdL0NvdW50IDE+PmVuZG9iagozIDAgb2JqPDwvVHlwZS9QYWdlL1BhcmVudCAyIDAgUi9NZWRpYUJveFswIDAgNjEyIDc5Ml0vQ29udGVudHMgNCAwIFIvUmVzb3VyY2VzPDwvRm9udDw8L0YxIDUgMCBSPj4+Pj4+ZW5kb2JqCjQgMCBvYmo8PC9MZW5ndGggNTQ+PnN0cmVhbQpCVCAvRjEgMTggVGYgNzIgNzIwIFRkIChSZWVmQVBJIGdvbGRlbiB0ZXN0IFBERikgVGogRVQKZW5kc3RyZWFtZW5kb2JqCjUgMCBvYmo8PC9UeXBlL0ZvbnQvU3VidHlwZS9UeXBlMS9CYXNlRm9udC9IZWx2ZXRpY2E+PmVuZG9iagp4cmVmCjAgNgowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMDAwMDkgMDAwMDAgbiAKMDAwMDAwMDA1MiAwMDAwMCBuIAowMDAwMDAwMTAxIDAwMDAwIG4gCjAwMDAwMDAyMTEgMDAwMDAgbiAKMDAwMDAwMDMxMCAwMDAwMCBuIAp0cmFpbGVyPDwvU2l6ZSA2L1Jvb3QgMSAwIFI+PgpzdGFydHhyZWYKMzcxCiUlRU9GCg=="}'import requests
r = requests.post(
"https://api.reefapi.com/file-convert/v1/pdf_extract_text",
headers={"x-api-key": REEF_KEY},
json={
"file_b64": "JVBERi0xLjQKMSAwIG9iajw8L1R5cGUvQ2F0YWxvZy9QYWdlcyAyIDAgUj4+ZW5kb2JqCjIgMCBvYmo8PC9UeXBlL1BhZ2VzL0tpZHNbMyAwIFJdL0NvdW50IDE+PmVuZG9iagozIDAgb2JqPDwvVHlwZS9QYWdlL1BhcmVudCAyIDAgUi9NZWRpYUJveFswIDAgNjEyIDc5Ml0vQ29udGVudHMgNCAwIFIvUmVzb3VyY2VzPDwvRm9udDw8L0YxIDUgMCBSPj4+Pj4+ZW5kb2JqCjQgMCBvYmo8PC9MZW5ndGggNTQ+PnN0cmVhbQpCVCAvRjEgMTggVGYgNzIgNzIwIFRkIChSZWVmQVBJIGdvbGRlbiB0ZXN0IFBERikgVGogRVQKZW5kc3RyZWFtZW5kb2JqCjUgMCBvYmo8PC9UeXBlL0ZvbnQvU3VidHlwZS9UeXBlMS9CYXNlRm9udC9IZWx2ZXRpY2E+PmVuZG9iagp4cmVmCjAgNgowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMDAwMDkgMDAwMDAgbiAKMDAwMDAwMDA1MiAwMDAwMCBuIAowMDAwMDAwMTAxIDAwMDAwIG4gCjAwMDAwMDAyMTEgMDAwMDAgbiAKMDAwMDAwMDMxMCAwMDAwMCBuIAp0cmFpbGVyPDwvU2l6ZSA2L1Jvb3QgMSAwIFI+PgpzdGFydHhyZWYKMzcxCiUlRU9GCg=="
},
)
print(r.json()["data"])const res = await fetch("https://api.reefapi.com/file-convert/v1/pdf_extract_text", {
method: "POST",
headers: {
"x-api-key": process.env.REEF_KEY,
"content-type": "application/json",
},
body: JSON.stringify({
"file_b64": "JVBERi0xLjQKMSAwIG9iajw8L1R5cGUvQ2F0YWxvZy9QYWdlcyAyIDAgUj4+ZW5kb2JqCjIgMCBvYmo8PC9UeXBlL1BhZ2VzL0tpZHNbMyAwIFJdL0NvdW50IDE+PmVuZG9iagozIDAgb2JqPDwvVHlwZS9QYWdlL1BhcmVudCAyIDAgUi9NZWRpYUJveFswIDAgNjEyIDc5Ml0vQ29udGVudHMgNCAwIFIvUmVzb3VyY2VzPDwvRm9udDw8L0YxIDUgMCBSPj4+Pj4+ZW5kb2JqCjQgMCBvYmo8PC9MZW5ndGggNTQ+PnN0cmVhbQpCVCAvRjEgMTggVGYgNzIgNzIwIFRkIChSZWVmQVBJIGdvbGRlbiB0ZXN0IFBERikgVGogRVQKZW5kc3RyZWFtZW5kb2JqCjUgMCBvYmo8PC9UeXBlL0ZvbnQvU3VidHlwZS9UeXBlMS9CYXNlRm9udC9IZWx2ZXRpY2E+PmVuZG9iagp4cmVmCjAgNgowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMDAwMDkgMDAwMDAgbiAKMDAwMDAwMDA1MiAwMDAwMCBuIAowMDAwMDAwMTAxIDAwMDAwIG4gCjAwMDAwMDAyMTEgMDAwMDAgbiAKMDAwMDAwMDMxMCAwMDAwMCBuIAp0cmFpbGVyPDwvU2l6ZSA2L1Jvb3QgMSAwIFI+PgpzdGFydHhyZWYKMzcxCiUlRU9GCg=="
}),
});
const { ok, data, meta, error } = await res.json();Ask your MCP-connected assistant: call reefapi.file-convert.pdf_extract_text with {"file_b64":"JVBERi0xLjQKMSAwIG9iajw8L1R5cGUvQ2F0YWxvZy9QYWdlcyAyIDAgUj4+ZW5kb2JqCjIgMCBvYmo8PC9UeXBlL1BhZ2VzL0tpZHNbMyAwIFJdL0NvdW50IDE+PmVuZG9iagozIDAgb2JqPDwvVHlwZS9QYWdlL1BhcmVudCAyIDAgUi9NZWRpYUJveFswIDAgNjEyIDc5Ml0vQ29udGVudHMgNCAwIFIvUmVzb3VyY2VzPDwvRm9udDw8L0YxIDUgMCBSPj4+Pj4+ZW5kb2JqCjQgMCBvYmo8PC9MZW5ndGggNTQ+PnN0cmVhbQpCVCAvRjEgMTggVGYgNzIgNzIwIFRkIChSZWVmQVBJIGdvbGRlbiB0ZXN0IFBERikgVGogRVQKZW5kc3RyZWFtZW5kb2JqCjUgMCBvYmo8PC9UeXBlL0ZvbnQvU3VidHlwZS9UeXBlMS9CYXNlRm9udC9IZWx2ZXRpY2E+PmVuZG9iagp4cmVmCjAgNgowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMDAwMDkgMDAwMDAgbiAKMDAwMDAwMDA1MiAwMDAwMCBuIAowMDAwMDAwMTAxIDAwMDAwIG4gCjAwMDAwMDAyMTEgMDAwMDAgbiAKMDAwMDAwMDMxMCAwMDAwMCBuIAp0cmFpbGVyPDwvU2l6ZSA2L1Jvb3QgMSAwIFI+PgpzdGFydHhyZWYKMzcxCiUlRU9GCg=="}.Who uses this API and why
- Data pipelines call pdf_extract_text to turn PDFs into searchable or RAG-ready text.
- Document tools use pdf_merge and pdf_split to assemble files.
- OCR triage uses the scanned flag to route image-only PDFs correctly.
Questions developers ask before integrating
How do I send a file in, and how does the result come back?
Three ways in: file_b64 in the JSON body (a data-URI prefix is tolerated), file_url over https which is fetched server-side, or a multipart form field named 'file'. The input cap is 25 MB, exactly 26,214,400 bytes. On the way out, every produced file is an entry in files[] with filename, format, content_type, bytes and delivery. A measured pdf_to_images call returned page_001.webp at 2,716 bytes with delivery 'inline' and the bytes in file_b64. Anything above 10 MB switches to a one-time download_path with a 30-minute TTL, and a total above 50 MB is rejected outright.
What happens if the file is not the format the action expects?
It fails immediately and tells you exactly what it saw. Sending CSV bytes to audio_convert returned ok false, INVALID_PARAM, and the message "input sniffed as 'text' - this action accepts: mp3, wav, flac, ogg, m4a", with detail.sniffed and detail.accepted as separate fields so you can branch on them. The format is always determined from magic bytes; the extension and the filename are never trusted for that decision.
So is the filename ignored completely?
Not quite. It is a hint for the cases magic bytes cannot separate, and markdown is the one that matters, because a .md file is just text on the wire. Measured: markdown bytes sent with filename 'a.md' were sniffed as 'text', and office_convert still reported from 'md' and produced a 28 KB PDF. Send the filename when you have it, but do not rely on it to override the sniffed type.
pdf_extract_text returned empty pages and likely_scanned true. Is that a failure?
No, that is the diagnosis. It means the PDF has no extractable text layer, which is what a scan or an image-only export looks like, and the response says it precisely: characters 0, empty_pages 1, likely_scanned true, stop_reason 'complete'. The same call against a PDF with a real text layer returned characters 2876, empty_pages 0 and likely_scanned false. When likely_scanned comes back true, send the file to ocr_pdf instead of retrying.
Does data_convert infer types?
No, and that is deliberate. Every cell arrives as a string: a two-row CSV of name,age converted to JSON came back as [{"name":"ann","age":"30"},{"name":"bob","age":"41"}]. Casting is yours to do. The response reports what it read and wrote, from 'csv', to 'json', rows 2, so you can assert the row count before decoding anything.
What is in the response besides the converted file?
Each action returns its own facts alongside files[], and several let you verify the result without decoding base64. pdf_to_images returned page_count, rendered, dpi and stop_reason plus width and height per file. doc_to_markdown returned page_count, pages_converted, tables, empty_pages, characters and a markdown_preview of the opening text next to the full document.md. pdf_extract_text returns per-page text and no file at all.
Can it open a password-protected PDF?
Only with the password. Every PDF action takes a password parameter that unlocks the input for that call, and pdf_unlock writes out a copy with the encryption removed when you supply the correct one. Without it, an encrypted input fails cleanly with INVALID_PARAM rather than half-processing. Nothing here cracks or bypasses a password, and there is no recovery mode.
What is the File Conversion API?
File Conversion API is a ReefAPI endpoint group for file conversion It returns live JSON through POST requests under /file-convert/v1.
Is the File Conversion API free to try?
Yes. ReefAPI starts with 1,000 free credits, no card required. File Conversion calls use the same shared credit balance as every other ReefAPI engine.
Do I need a File Conversion login or account?
No login to File Conversion is needed for the API response. You call ReefAPI with your x-api-key header, and the playground can run live examples before you create a production key.
How fresh is the File Conversion data?
The page example is captured from a live pdf_extract_text call, and production requests fetch live data through ReefAPI rather than a static sample.
How many credits does the File Conversion API use?
File Conversion actions currently cost 1-4 credits per successful call. Failed or blocked calls are free, and all APIs draw from one credit pool.
Can I call File Conversion from an AI assistant or MCP client?
Yes. Connect ReefAPI once through MCP and your assistant can call file-convert actions with the same key, credit pool and JSON envelope used by normal REST requests.
Is the File Conversion API a File Conversion scraper?
It is the managed alternative to a DIY File Conversion scraper. Instead of building and maintaining your own scraper — proxies, headless browsers, captcha and constant breakage — you call one ReefAPI endpoint and get the same file conversion back as clean JSON.