> This page is for version v2026-02-09 (default).
> For other versions, use one of these documentation indexes:
> - v2026-02-09 (default): https://docs.extend.ai/2026-02-09/llms.txt
> - v2025-04-21: https://docs.extend.ai/2025-04-21/llms.txt
> - v2024-12-23: https://docs.extend.ai/2024-12-23/llms.txt

> ## Documentation Index
> Fetch the complete documentation index at: https://docs.extend.ai/llms.txt
> Use this file to discover all available pages before exploring further.
>
> ## API version
> The current API version is `2026-02-09`, served at the site root (no version prefix in URLs).
> If this page URL contains `/2025-04-21/` or `/2024-12-23/`, you are reading an older API version.
> Prefer the current docs at https://docs.extend.ai/llms.txt unless the user explicitly needs that older version.
> Do not treat older-version pages as the source of truth for new integrations.

# Password-Protected Files

> Process password-protected PDFs by supplying the file password in your API request.

Extend supports processing password-protected PDF files. You can provide the file's password directly in your API request so that Extend can unlock and process the document.

---

## Providing a Password via URL

When providing a file by URL (in parse, extract, classify, split, edit, or workflow runs), include the password in the `settings` object on the file input:

```json
{
  "file": {
    "url": "https://example.com/protected.pdf",
    "name": "protected.pdf",
    "settings": {
      "password": "your-file-password"
    }
  }
}
```

#### Python

```python
from extend_ai import Extend

client = Extend()

response = client.parse(
    file={
        "url": "https://example.com/protected.pdf",
        "name": "protected.pdf",
        "settings": {"password": "your-file-password"},
    },
    config={"target": "markdown"},
)
```

#### TypeScript

```typescript
import { ExtendClient } from "extend-ai";

const client = new ExtendClient();

const response = await client.parse({
  file: {
    url: "https://example.com/protected.pdf",
    name: "protected.pdf",
    settings: { password: "your-file-password" },
  },
  config: { target: "markdown" },
});
```

#### Java

```java
import ai.extend.ExtendClient;
import ai.extend.requests.ParseRequest;
import ai.extend.types.FileFromUrl;
import ai.extend.types.FileFromUrlSettings;
import ai.extend.types.ParseConfig;
import ai.extend.types.ParseConfigTarget;
import ai.extend.types.ParseRequestFile;
import ai.extend.types.ParseRun;

ExtendClient client = ExtendClient.builder().build();

ParseRun response = client.parse(ParseRequest.builder()
    .file(ParseRequestFile.of(FileFromUrl.builder()
        .url("https://example.com/protected.pdf")
        .name("protected.pdf")
        .settings(FileFromUrlSettings.builder().password("your-file-password").build())
        .build()))
    .config(ParseConfig.builder().target(ParseConfigTarget.MARKDOWN).build())
    .build());
```

#### Go

```go
c := client.NewClient()

response, err := c.Parse(context.TODO(), &extend.ParseRequest{
	File: &extend.ParseRequestFile{
		FileFromURL: &extend.FileFromURL{
			URL:      "https://example.com/protected.pdf",
			Name:     extend.String("protected.pdf"),
			Settings: &extend.FileFromURLSettings{Password: extend.String("your-file-password")},
		},
	},
	Config: &extend.ParseConfig{Target: extend.ParseConfigTargetMarkdown.Ptr()},
})
if err != nil {
	log.Fatal(err)
}
```

#### cURL

```bash
curl -X POST https://api.extend.ai/parse \
  -H "Authorization: Bearer $EXTEND_API_KEY" \
  -H "x-extend-api-version: 2026-02-09" \
  -H "Content-Type: application/json" \
  -d '{
    "file": {
      "url": "https://example.com/protected.pdf",
      "name": "protected.pdf",
      "settings": { "password": "your-file-password" }
    },
    "config": { "target": "markdown" }
  }'
```

The `settings` object is available on URL-based file inputs across all run endpoints:

| Endpoint                                 | Supports `settings.password` |
| ---------------------------------------- | ---------------------------- |
| `POST /parse` / `POST /parse_runs`       | ✅                            |
| `POST /extract` / `POST /extract_runs`   | ✅                            |
| `POST /classify` / `POST /classify_runs` | ✅                            |
| `POST /split` / `POST /split_runs`       | ✅                            |
| `POST /edit` / `POST /edit_runs`         | ✅                            |
| Workflow runs                            | ✅                            |

> **Note**
>
> Password is only applicable to URL-based file inputs. When referencing a previously uploaded file by `id`, the file was already uploaded (and optionally password-unlocked) at upload time.

---

## Providing a Password When Uploading a File

When uploading a file via `POST /files/upload`, include the password as a `password` field in the `multipart/form-data` request:

#### Python

```python
with open("protected.pdf", "rb") as f:
    uploaded = client.files.upload(file=f, password="your-file-password")

# uploaded.id can now be used in subsequent requests via file={"id": uploaded.id}
```

#### TypeScript

```typescript
import { createReadStream } from "fs";

const uploaded = await client.files.upload(createReadStream("protected.pdf"), {
  password: "your-file-password",
});

// uploaded.id can now be used in subsequent requests via file: { id: uploaded.id }
```

#### Java

```java
import ai.extend.requests.FilesUploadRequest;
import ai.extend.types.File;

File uploaded = client.files().upload(
    new java.io.File("protected.pdf"),
    FilesUploadRequest.builder().password("your-file-password").build());

// uploaded.getId() can now be used in subsequent requests via FileFromId
```

#### Go

```go
f, err := os.Open("protected.pdf")
if err != nil {
	log.Fatal(err)
}
defer f.Close()

uploaded, err := c.Files.Upload(context.TODO(), f, &extend.FilesUploadRequest{
	Password: extend.String("your-file-password"),
})
if err != nil {
	log.Fatal(err)
}

// uploaded.ID can now be used in subsequent requests via FileFromID
```

#### cURL

```bash
curl -X POST https://api.extend.ai/files/upload \
  -H "Authorization: Bearer $EXTEND_API_KEY" \
  -H "x-extend-api-version: 2026-02-09" \
  -F "file=@protected.pdf" \
  -F "password=your-file-password"
```

---

## Error Handling

If you attempt to process a password-protected file without providing a password, the API returns a `PASSWORD_PROTECTED_FILE` error:

```json
{
  "code": "PASSWORD_PROTECTED_FILE",
  "message": "The file is password protected and cannot be parsed.",
  "requestId": "req_abc123",
  "retryable": false
}
```