@maramia/maradocs-sdk-ts
v1.4.0
Published
TypeScript SDK for MaraDocs API (https://maradocs.io)
Readme
MaraDocs TypeScript SDK
MaraDocs.io is a comprehensive document preparation tool that easily extracts documents from images typically sent by email. It transforms trashy photos into nice and usable pdfs and delivers virus checks, pdf conversion, ai text recognition and pdf compression along the way. Check out MaraDocs at https://maradocs.io.
The MaraDocs API is the interface to use all of MaraDocs magic document functions in your own automation tools. This is the Official TypeScript SDK for the MaraDocs API.
Installation
npm install @maramia/maradocs-sdk-tsor with pnpm:
pnpm add @maramia/maradocs-sdk-tsDocumentation
Full API documentation: api.maradocs.io
Quick Start
import { MaraDocsServer, MaraDocsClient } from "@maramia/maradocs-sdk-ts";
// Server-side: create workspace and send workspace_secret to client
const server = new MaraDocsServer({ secretKey: process.env.MARADOCS_SECRET_KEY! });
const ws = await server.workspace.create({});
// Client-side: OCR documents and combine into single PDF
const client = new MaraDocsClient({ workspaceSecret: ws.workspace_secret });
const imgPdf = await client.flow.ocrImg(imageFile); // image → searchable PDF
const pdfPdf = await client.flow.ocrPdf(pdfFile); // PDF → searchable PDF
const combined = await client.pdf.compose({ pdfs: [{ pdf_handle: imgPdf }, { pdf_handle: pdfPdf }] });
const blob = await client.data.downloadPdf({ pdf_handle: combined.pdf_handle });Clients
| Client | Use Case | Authentication |
|--------|----------|----------------|
| MaraDocsClient | Client-side (browser) document processing | Workspace secret |
| MaraDocsServer | Server-side workspace management | Secret key |
Error Handling
All errors from incorrect API usage are returned as 400 Bad Request.
Insufficient credits are returned as 402 Payment Required.
Validation errors are returned as 422 Unprocessable Entity.
Internal errors are returned as 500 Internal Server Error.
API errors throw an ApiErrorException with both machine-readable codes and human-readable messages:
import { ApiErrorException } from "@maramia/maradocs-sdk-ts/models/errors";
try {
await client.pdf.compose({ pdfs: [{ pdf_handle: pdf, pages: [{ page_number: 999 }] }] });
} catch (e) {
if (e instanceof ApiErrorException) {
console.log(e.apiError.code); // e.g. 300 (PDF_PAGE_OUT_OF_RANGE)
console.log(e.apiError.message); // human-readable explanation
}
}See errors.ts for all error codes.
API Reference
Server Operations (server.workspace)
| Method | Description |
|--------|-------------|
| workspace.create | Create a new workspace |
| workspace.delete | Delete a workspace |
PDF Operations (client.pdf)
| Method | Description |
|--------|-------------|
| validate | Validate PDF (virus scan + encoding check) |
| compose | Merge/split PDFs by selecting pages |
| optimize | Reduce file size |
| rotate | Rotate specific pages |
| toImg | Render pages as images |
| orientation | Detect and fix page orientation |
| ocrToPdf | Create searchable PDF with text layer |
Image Operations (client.img)
| Method | Description |
|--------|-------------|
| validate | Validate image |
| thumbnail | Create thumbnail |
| findDocuments | Detect documents in photo |
| extractQuadrilateral | Extract and correct perspective |
| orientation | Detect and fix orientation |
| rotate | Rotate by 0°/90°/180°/270° |
| toJpeg | Convert to JPEG |
| toPng | Convert to PNG |
| toPdf | Convert to PDF |
| ocrToPdf | OCR to searchable PDF |
HTML Operations (client.html)
| Method | Description |
|--------|-------------|
| validate | Validate HTML |
| toPdf | Convert to PDF |
Email Operations (client.email)
| Method | Description |
|--------|-------------|
| validate | Parse and validate .eml/.msg files and extract attachments |
| toHtml | Render validated email to HTML |
| toPdf | Render validated email to PDF |
Video Operations (client.video)
| Method | Description |
|--------|-------------|
| validate | Validate video |
Validation returns source video/audio metadata and a discriminated result (Ok, Error, or Virus). Use okVideo to extract the handle on success.
Audio Operations (client.audio)
| Method | Description |
|--------|-------------|
| validate | Validate audio |
Validation returns source audio metadata and a discriminated result (Ok, Error, or Virus). Use okAudio to extract the handle on success.
Data Operations (client.data)
| Method | Description |
|--------|-------------|
| createUpload | Mint a proxy-only upload capability (proxy_url + unvalidated_file_handle) |
| upload | Upload file via first-party presigned POST (optional onProgress callback) |
| mimeType | Detect MIME type |
| createDownloadPdf / Jpeg / Png / Odt / Unvalidated | Mint a proxy-only download capability (proxy_url) |
| downloadPdf | Download PDF as Blob via first-party SSE-C URL (optional onProgress) |
| downloadJpeg | Download JPEG as Blob (optional onProgress) |
| downloadPng | Download PNG as Blob (optional onProgress) |
| downloadOdt | Download ODT as Blob (optional onProgress) |
| downloadMp4 | Download video as MP4 as Blob (optional onProgress) |
| downloadMp3 | Download audio as MP3 as Blob (optional onProgress) |
| downloadWav | Download audio as WAV as Blob (optional onProgress) |
| downloadFlac | Download audio as FLAC as Blob (optional onProgress) |
| downloadUnvalidated | Download unvalidated file, e.g. email body (optional onProgress) |
create* methods are for unauthenticated third parties — they always mint proxy_url and never expose SSE-C fields. upload / download* are first-party only:
const { proxy_url, unvalidated_file_handle } = await client.data.createUpload({
size: file.size,
name: file.name,
});
// Third party: PUT proxy_url with raw body and Content-Length === size
// Integrator: validate(unvalidated_file_handle) after upload
const { proxy_url: downloadUrl } = await client.data.createDownloadPdf({
pdf_handle,
});
// Third party: GET downloadUrl (no SSE-C headers)Validation and helpers
Uploaded files must be validated before use. Validation responses are discriminated unions (Ok, Error, or Virus). Use the okPdf, okImg, okHtml, okEmail, okVideo, and okAudio helpers to extract the handle from a successful response—they throw ValidationErrorException or ValidationVirusException on failure:
import { okPdf } from "@maramia/maradocs-sdk-ts/models/pdf";
import { okImg } from "@maramia/maradocs-sdk-ts/models/img";
import { okHtml } from "@maramia/maradocs-sdk-ts/models/html";
import { okEmail } from "@maramia/maradocs-sdk-ts/models/email";
import { okVideo } from "@maramia/maradocs-sdk-ts/models/video";
import { okAudio } from "@maramia/maradocs-sdk-ts/models/audio";
const validated = await client.pdf.validate({ unvalidated_file_handle: uploaded.unvalidated_file_handle });
const pdfHandle = okPdf(validated); // throws if validation failedExamples
Merge/Split PDFs
import { okPdf } from "@maramia/maradocs-sdk-ts/models/pdf";
// Upload PDFs
const uploadedPdf1 = await client.data.upload(pdf1File);
const uploadedPdf2 = await client.data.upload(pdf2File);
// Validate PDFs (throws on virus or validation error)
const validatedPdf1 = await client.pdf.validate({ unvalidated_file_handle: uploadedPdf1.unvalidated_file_handle });
const validatedPdf2 = await client.pdf.validate({ unvalidated_file_handle: uploadedPdf2.unvalidated_file_handle });
const pdf1 = okPdf(validatedPdf1);
const pdf2 = okPdf(validatedPdf2);
// Merge PDFs
const composed = await client.pdf.compose({
pdfs: [
{ pdf_handle: pdf1, pages: [{ page_number: 0 }, { page_number: 2 }] },
{ pdf_handle: pdf2 }, // all pages
],
});
// Download merged PDF
const mergedPdf = await client.data.downloadPdf({ pdf_handle: composed.pdf_handle });Validate and Download Video
import { okVideo } from "@maramia/maradocs-sdk-ts/models/video";
// Upload and validate
const uploaded = await client.data.upload(videoFile);
const validated = await client.video.validate({
unvalidated_file_handle: uploaded.unvalidated_file_handle,
});
const videoHandle = okVideo(validated);
// Download as MP4 (transcodes with optional CFR, audio codec, and bitrate settings)
const mp4Blob = await client.data.downloadMp4(
{ video_handle: videoHandle },
(percent) => console.log(`Download ${percent}%`),
);Validate and Download Audio
import { okAudio } from "@maramia/maradocs-sdk-ts/models/audio";
// Upload and validate
const uploaded = await client.data.upload(audioFile);
const validated = await client.audio.validate({
unvalidated_file_handle: uploaded.unvalidated_file_handle,
});
const audioHandle = okAudio(validated);
// Download in a chosen format (MP3, WAV, or FLAC)
const mp3Blob = await client.data.downloadMp3({ audio_handle: audioHandle });
const wavBlob = await client.data.downloadWav({ audio_handle: audioHandle, bit_depth: "S24" });
const flacBlob = await client.data.downloadFlac({ audio_handle: audioHandle, compression_level: 8 });Low-Level Image Processing
For fine-grained control (instead of flow.ocrImg) and without using the okImg helper
// Upload and validate
const uploaded = await client.data.upload(imageFile);
const validated = await client.img.validate({
unvalidated_file_handle: uploaded.unvalidated_file_handle,
});
if (validated.response.class_name !== "ImgValidateResponseOk") {
throw new Error("Validation failed");
}
const imgHandle = validated.response.img_handle;
// Find and extract document
const docs = await client.img.findDocuments({ img_handle: imgHandle });
if (docs.documents.length > 0) {
const extracted = await client.img.extractQuadrilateral({
img_handle: imgHandle,
quadrilateral: docs.documents[0].quadrilateral,
});
// Continue with extracted.img_handle...
}