npm package: @maramia/maradocs-sdk-ts
Description: TypeScript SDK for MaraDocs API (https://maradocs.io)
Author: Maramia GmbH
Latest version: 1.2.0

# 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](https://api.maradocs.io).

## Installation

```bash
npm install @maramia/maradocs-sdk-ts
```

or with pnpm:

```bash
pnpm add @maramia/maradocs-sdk-ts
```

## Documentation

Full API documentation: [api.maradocs.io](https://api.maradocs.io)

## Quick Start

```typescript
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:

```typescript
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](https://github.com/maramia/maradocs-sdk-typescript/blob/main/src/models/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 |

### Data Operations (`client.data`)

| Method | Description |
|--------|-------------|
| `upload` | Upload file (optional `onProgress` callback) |
| `mimeType` | Detect MIME type |
| `downloadPdf` | Download PDF as Blob (optional `onProgress`) |
| `downloadJpeg` | Download JPEG as Blob (optional `onProgress`) |
| `downloadPng` | Download PNG as Blob (optional `onProgress`) |
| `downloadOdt` | Download ODT as Blob (optional `onProgress`) |
| `downloadUnvalidated` | Download unvalidated file, e.g. email body (optional `onProgress`) |



## Validation and helpers

Uploaded files must be validated before use. Validation responses are discriminated unions (`Ok`, `Error`, or `Virus`). Use the `okPdf`, `okImg`, `okHtml`, and `okEmail` helpers to extract the handle from a successful response—they throw `ValidationErrorException` or `ValidationVirusException` on failure:

```typescript
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";

const validated = await client.pdf.validate({ unvalidated_file_handle: uploaded.unvalidated_file_handle });
const pdfHandle = okPdf(validated);  // throws if validation failed
```

## Examples

### Merge/Split PDFs

```typescript
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 });
```

### Low-Level Image Processing

For fine-grained control (instead of `flow.ocrImg`) and without using the `okImg` helper

```typescript
// 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...
}
```