# Text to PDF

Use `/textToPdf` for logs, code snippets, Markdown, or other plain text whose whitespace and line breaks need to remain intact.

## Endpoint

```
POST /textToPdf
```

## Authentication

Send a valid API key or OAuth token in the `Authorization` header:

```
Authorization: Bearer YOUR_API_KEY
```

See [Authentication](https://pdf-mcp.io/docs/authentication) for details.

---

## Request body

**Content-Type:** `application/json` or `multipart/form-data`

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `text` | string | Yes | Plain text content to convert to PDF |
| `font_size` | integer | No | Font size in points (default: `12`) |
| `filename` | string | No | Output filename (default: `document.pdf`) |
| `storage` | object | No | Storage options for the generated PDF (see below) |
| `return_binary` | boolean | No | Return PDF binary even when using storage (default: `false`) |

### Field details

**text** (required)

The plain text content to render as a PDF. The text is rendered with:
- Monospace font (Courier New) for consistent character width
- 1.5 line height for readability
- Whitespace preservation (`white-space: pre-wrap`)
- 2cm page margins
- Automatic HTML entity escaping (`<`, `>`, `&`)

**font_size** (optional)

The font size in points for the text content. If not provided, defaults to `12`. Common sizes:
- `10` - Compact, good for code or logs
- `12` - Standard (default)
- `14` - Larger, better readability

**filename** (optional)

The filename for the downloaded PDF. If not provided, defaults to `document.pdf`. The `.pdf` extension is automatically appended if not present.

### Storage options

Control how the generated PDF is stored and returned.

| Field | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| `storage.mode` | string | No | `memory` | Storage mode: `memory`, `default`, or `byob` |
| `storage.filename` | string | No | endpoint default | Custom filename (auto-suffixed with timestamp if duplicate) |
| `storage.expires_in` | integer | No | 3600 | Signed URL expiry in seconds (60-604800) |
| `storage.retention_days` | integer | No | 14 | Auto-delete document after N days (1-365) |

**Storage modes:**

- **memory**: Return PDF bytes directly in response (no persistence). This is the default for REST API calls.
- **default**: Store in pdf-mcp S3 bucket, return JSON with document metadata and signed URL.
- **byob**: Store in your own S3 bucket (requires [BYOB configuration](https://pdf-mcp.io/docs/storage-modes)).

---

## Request examples

### Basic JSON conversion

```bash
curl -X POST https://api.pdf-mcp.io/textToPdf \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Hello, World!\n\nThis is a plain text document.\nLine breaks are preserved."
  }' \
  --output document.pdf
```

### Code with a custom font size

```bash
curl -X POST https://api.pdf-mcp.io/textToPdf \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "function greet(name) {\n    console.log(\"Hello, \" + name);\n}\n\ngreet(\"World\");",
    "font_size": 10,
    "filename": "code-snippet.pdf"
  }' \
  --output code-snippet.pdf
```

### Log file export

```bash
curl -X POST https://api.pdf-mcp.io/textToPdf \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "[2024-01-15 10:30:00] INFO  Server started\n[2024-01-15 10:30:01] INFO  Connected to database\n[2024-01-15 10:30:02] WARN  Cache miss for key: user_123",
    "font_size": 10,
    "filename": "server-logs.pdf"
  }' \
  --output server-logs.pdf
```

### Form data

```bash
curl -X POST https://api.pdf-mcp.io/textToPdf \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "text=This is plain text content sent via form data." \
  -F "font_size=12" \
  -F "filename=form-output.pdf" \
  --output form-output.pdf
```

### Persistent storage

```bash
curl -X POST https://api.pdf-mcp.io/textToPdf \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Server Log Export\n\n[2024-01-15 10:30:00] INFO  Server started\n[2024-01-15 10:30:01] INFO  Connected to database",
    "font_size": 10,
    "storage": {
      "mode": "default",
      "filename": "server-logs.pdf",
      "expires_in": 86400,
      "retention_days": 30
    }
  }'
```

---

## Response

### Success (memory mode)

When `storage.mode` is `memory` or not provided, returns the PDF as a binary file download.

**Headers:**
```
Content-Type: application/pdf
Content-Disposition: attachment; filename="document.pdf"
```

### Success (with storage)

When `storage.mode` is `default` or `byob`, returns JSON with document metadata and a signed download URL:

```json
{
  "success": true,
  "document_id": "550e8400-e29b-41d4-a716-446655440000",
  "url": "https://s3.eu-central-1.amazonaws.com/...",
  "filename": "server-logs.pdf",
  "file_size_bytes": 12345,
  "page_count": 1,
  "storage_mode": "default",
  "expires_at": "2024-02-15T10:30:00Z",
  "signed_url_expires_at": "2024-01-16T10:30:00Z"
}
```

| Field | Type | Description |
|-------|------|-------------|
| `success` | boolean | Always `true` on success |
| `document_id` | string | UUID of the stored document |
| `url` | string | Presigned URL for downloading the PDF |
| `filename` | string | Document filename |
| `file_size_bytes` | integer | Size of the PDF in bytes |
| `page_count` | integer | Number of pages in the PDF |
| `storage_mode` | string | Storage mode used (`default` or `byob`) |
| `expires_at` | string | Auto-deletion timestamp (ISO 8601), if retention is set |
| `signed_url_expires_at` | string | Expiration time of the signed URL (ISO 8601) |

### Error

```json
{
  "error": "Failed to convert text to PDF",
  "message": "Error description"
}
```

**Status codes:**

| Code | Description |
|------|-------------|
| 200 | Success - PDF returned or stored |
| 400 | Bad Request - Invalid input or BYOB not configured |
| 401 | Unauthorized - Missing or invalid Authorization header |
| 402 | Payment Required - Insufficient credits |
| 403 | Forbidden - Invalid API key or OAuth token |
| 500 | Internal Server Error - PDF generation failed |
| 502 | Bad Gateway - Storage operation failed (S3 upload or URL generation) |

---

## Output formatting

The generated PDF uses the following default styling:

```css
body {
    font-family: 'Courier New', Courier, monospace;
    font-size: 12pt;  /* or your specified font_size */
    line-height: 1.5;
    white-space: pre-wrap;
    margin: 2cm;
}
```

### Whitespace handling

- **Line breaks**: Preserved (`\n` creates new lines)
- **Spaces**: Multiple spaces are preserved
- **Tabs**: Rendered as spaces
- **Long lines**: Wrap to fit page width

### Character escaping

HTML special characters are automatically escaped:
- `<` becomes `&lt;`
- `>` becomes `&gt;`
- `&` becomes `&amp;`

Escaping prevents HTML-like content from being interpreted as markup, so it appears as provided.

---

## Examples

### Code documentation

```bash
curl -X POST https://api.pdf-mcp.io/textToPdf \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "# API Reference\n\n## Endpoints\n\nGET  /users\nPOST /users\nGET  /users/:id\nPUT  /users/:id",
    "font_size": 11,
    "filename": "api-reference.pdf"
  }' \
  --output api-reference.pdf
```

### Data export

```bash
curl -X POST https://api.pdf-mcp.io/textToPdf \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Name          Email                  Status\n--------------------------------------------------\nJohn Doe      john@example.com       Active\nJane Smith    jane@example.com       Pending",
    "font_size": 10,
    "filename": "users-export.pdf"
  }' \
  --output users-export.pdf
```

---

## Python example

```python
import requests

API_KEY = "YOUR_API_KEY"
API_URL = "https://api.pdf-mcp.io/textToPdf"

response = requests.post(
    API_URL,
    headers={
        "Authorization": f"Bearer {API_KEY}",
        "Content-Type": "application/json"
    },
    json={
        "text": "Hello from Python!\n\nThis text document was generated via the API.",
        "font_size": 12,
        "filename": "python-output.pdf"
    }
)

if response.status_code == 200:
    with open("output.pdf", "wb") as f:
        f.write(response.content)
    print("PDF saved successfully!")
else:
    print(f"Error: {response.status_code}")
```

---

## Node.js example

```javascript
const fs = require('fs');

const API_KEY = 'YOUR_API_KEY';
const API_URL = 'https://api.pdf-mcp.io/textToPdf';

async function generatePdf() {
  const response = await fetch(API_URL, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      text: 'Hello from Node.js!\n\nThis text document was generated via the API.',
      font_size: 12,
      filename: 'nodejs-output.pdf'
    })
  });

  if (response.ok) {
    const buffer = await response.arrayBuffer();
    fs.writeFileSync('output.pdf', Buffer.from(buffer));
    console.log('PDF saved successfully!');
  } else {
    console.error('Error:', response.status);
  }
}

generatePdf();
```

---

## Implementation notes

### Prepare the content
- Use `\n` for line breaks in your text
- For multi-line strings in programming languages, use raw strings or template literals
- Escape JSON special characters properly when embedding in curl commands

### Choose a font size
- Use smaller fonts (`10pt`) for dense content like logs or code
- Use larger fonts (`14pt`) for documents meant to be printed or read on paper
- Test with a sample to find the right balance for your content

### Page layout
- Text wraps automatically at page margins
- Very long single lines will wrap to fit
- Consider breaking long content into logical sections with blank lines

---

## Related endpoints

- [HTML to PDF](https://pdf-mcp.io/docs/api-html-to-pdf): convert styled HTML
- [Image to PDF](https://pdf-mcp.io/docs/api-image-to-pdf): convert images to PDF
- [Merge PDFs](https://pdf-mcp.io/docs/api-merge-pdfs): combine multiple PDFs

## Credit usage

Each request costs **0.01 credits**, regardless of page count.
