# Upload a PDF

Base URL `https://api.accessful.de/api/v1/upload-service`. Every request needs the `X-API-Key` header — see [Authentication](https://docs.accessful.de/authentication/).

```http
POST /pdf/upload
Content-Type: multipart/form-data
```

| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| `files` | file | **yes** | One or more PDFs (`application/pdf`). |
| `webhookUrl` | string | no | Callback URL for [webhook](https://docs.accessful.de/webhooks/) events. |
| `secret` | string | no | Your HMAC signing secret (required for webhooks). |
| `folder-name` | string | no | Optional folder to group the case. |

**`200 OK`**

```json
{
  "successfulUploads": ["7c2f1e4a-9b0d-4a1e-8f3c-2d6b5a9e1c40"],
  "duplicateFiles": [{ "fileName": "document.pdf", "fileHash": "ab12cd34…" }],
  "message": "Upload completed successfully. Uploaded 1 files. 1 duplicates found.",
  "callbackUrl": "https://your-app.example.com/hooks/accessful"
}
```

- `successfulUploads` — one **`caseId`** per accepted file. Track and download by this ID.
- `duplicateFiles` — files skipped because the same content was already uploaded under your key.

Errors: `400` (non-PDF file or invalid webhook URL), `413` ([too large](https://docs.accessful.de/limits/)).
Quota is checked **after** upload — an exhausted quota does not fail this call; the job
ends in the `quota_exceeded` [status](https://docs.accessful.de/reference/job-status/) instead. See [Limits](https://docs.accessful.de/limits/#rate-limits--concurrency).