# Ein PDF an einer Seite aufteilen

Teilen Sie ein PDF an einer Trennstelle in zwei Dokumente auf: alles vor der Trennseite, dann ab der Trennseite.

Teilen Sie ein PDF-Dokument an einer Trennstelle in zwei Dokumente auf: Die
Seiten vor der Trennseite bilden den ersten Teil, und die Trennseite sowie
alles danach bilden den zweiten Teil. Diese Aktion gibt mehrere Dokumente
zurück (hier genau zwei Teile), verpackt in eine einzige Antwort gemäß dem
Header `Accept`. Die API ist *stateless*: Ihr Dokument wird in der Region
verarbeitet und niemals gespeichert.

## Endpoint

<Endpoint method="POST" path="/v1/split_at_page" />

In allen Regionen verfügbar. Hinweise zu Routing und Datenresidenz finden Sie
unter [Regionen und Datenresidenz](/docs/api/regions-and-data-residency).

| Region                 | URL                                                 |
| ---------------------- | --------------------------------------------------- |
| Global                 | `https://api.pdfblocks.com/v1/split_at_page`        |
| USA                    | `https://us.api.pdfblocks.com/v1/split_at_page`     |
| HIPAA USA              | `https://hipaa.api.pdfblocks.com/v1/split_at_page`  |
| Europäische Union      | `https://eu.api.pdfblocks.com/v1/split_at_page`     |
| Vereinigtes Königreich | `https://uk.api.pdfblocks.com/v1/split_at_page`     |
| Kanada                 | `https://ca.api.pdfblocks.com/v1/split_at_page`     |
| Australien             | `https://au.api.pdfblocks.com/v1/split_at_page`     |
| Japan                  | `https://jp.api.pdfblocks.com/v1/split_at_page`     |
| Indien                 | `https://in.api.pdfblocks.com/v1/split_at_page`     |
| Brasilien              | `https://br.api.pdfblocks.com/v1/split_at_page`     |

## Authentifizierung

Authentifizieren Sie jede Anfrage mit Ihrem geheimen API-Schlüssel im Header
`X-API-Key`, über HTTPS. Schlüssel erstellen und verwalten Sie im
[Dashboard](https://dashboard.pdfblocks.com). Einzelheiten finden Sie unter
[Authentifizierung](/docs/api/authentication).

## Anfrage

Der Endpoint nimmt einen Anfragetext vom Typ `multipart/form-data` entgegen.

<ParamField name="file" type="file" required>
  Das PDF-Eingabedokument.
</ParamField>

<ParamField name="page" type="integer" required>
  Die Seitenzahl, mit der der zweite Teil beginnt. Muss zwischen `2` und der
  Seitenanzahl des Dokuments liegen, damit beide Teile Seiten enthalten.
</ParamField>

## Beispiele

Teilen Sie ein Dokument an Seite 5 in zwei Teile auf:

<CodeGroup>

```bash title="cURL"
curl https://api.pdfblocks.com/v1/split_at_page \
  -H 'X-API-Key: your_api_key' \
  -F file=@input.pdf \
  -F page=5 \
  -o parts.zip
```

```python title="Python"
# pip install requests
import requests

with open('input.pdf', 'rb') as file:
    response = requests.post(
        'https://api.pdfblocks.com/v1/split_at_page',
        headers={'X-API-Key': 'your_api_key'},
        files={'file': file},
        data={'page': 5},
    )

response.raise_for_status()
with open('parts.zip', 'wb') as output:
    output.write(response.content)
```

```javascript title="Node.js"
// Node.js 18+
import { readFile, writeFile } from 'node:fs/promises';

const body = new FormData();
body.set('file', new Blob([await readFile('input.pdf')]), 'input.pdf');
body.set('page', '5');

const response = await fetch('https://api.pdfblocks.com/v1/split_at_page', {
  method: 'POST',
  headers: { 'X-API-Key': 'your_api_key' },
  body,
});

if (!response.ok) throw new Error(`Request failed: ${response.status}`);
await writeFile('parts.zip', Buffer.from(await response.arrayBuffer()));
```

```php title="PHP"
<?php
$ch = curl_init('https://api.pdfblocks.com/v1/split_at_page');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ['X-API-Key: your_api_key'],
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => [
        'file' => new CURLFile('input.pdf', 'application/pdf'),
        'page' => '5',
    ],
]);

$zip = curl_exec($ch);
if (curl_getinfo($ch, CURLINFO_HTTP_CODE) === 200) {
    file_put_contents('parts.zip', $zip);
}
```

```ruby title="Ruby"
# gem install http
require 'http'

response = HTTP
  .headers('X-API-Key' => 'your_api_key')
  .post('https://api.pdfblocks.com/v1/split_at_page', form: {
    file: HTTP::FormData::File.new('input.pdf'),
    page: '5',
  })

File.write('parts.zip', response.body) if response.status.success?
```

```go title="Go"
package main

import (
	"bytes"
	"io"
	"mime/multipart"
	"net/http"
	"os"
)

func main() {
	var buf bytes.Buffer
	form := multipart.NewWriter(&buf)

	file, _ := os.Open("input.pdf")
	defer file.Close()
	part, _ := form.CreateFormFile("file", "input.pdf")
	io.Copy(part, file)

	form.WriteField("page", "5")
	form.Close()

	req, _ := http.NewRequest("POST", "https://api.pdfblocks.com/v1/split_at_page", &buf)
	req.Header.Set("Content-Type", form.FormDataContentType())
	req.Header.Set("X-API-Key", "your_api_key")

	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()

	out, _ := os.Create("parts.zip")
	defer out.Close()
	io.Copy(out, res.Body)
}
```

```csharp title="C#"
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "your_api_key");

using var form = new MultipartFormDataContent
{
    { new ByteArrayContent(File.ReadAllBytes("input.pdf")), "file", "input.pdf" },
    { new StringContent("5"), "page" },
};

var response = await client.PostAsync(
    "https://api.pdfblocks.com/v1/split_at_page", form);
response.EnsureSuccessStatusCode();
await File.WriteAllBytesAsync(
    "parts.zip", await response.Content.ReadAsByteArrayAsync());
```

</CodeGroup>

Das ZIP enthält genau zwei Dokumente: `00001.pdf` enthält die Seiten 1 bis 4,
und `00002.pdf` enthält Seite 5 bis zum Ende.

## Antwort

Diese Aktion gibt mehrere Dokumente zurück, verpackt in eine einzige Antwort
gemäß dem Anfrage-Header `Accept`. Siehe [Antwortformate und
Inhaltsaushandlung](/docs/api/response-formats) für die vollständige Referenz
zur Aushandlung. Ohne den Header `Accept` ist ein ZIP-Archiv die Voreinstellung:

```http
HTTP/1.1 200 OK
Content-Type: application/zip
```

Wählen Sie die Verpackung über den Header `Accept`:

| Header `Accept`      | Antwort                                                         |
| -------------------- | -------------------------------------------------------------- |
| *(nicht gesendet)*   | `application/zip`, die Voreinstellung                          |
| `application/zip`    | Ein ZIP-Archiv der Ausgabe-PDFs                                |
| `application/json`   | Ein JSON-Umschlag mit base64-kodierten Dokumenten              |
| `multipart/mixed`    | Ein PDF pro Teil                                               |
| alles andere         | `406 Not Acceptable`                                            |

Die Ausgabe besteht immer aus genau zwei Dokumenten mit den Namen `00001.pdf`
(die Seiten vor der Trennseite) und `00002.pdf` (die Trennseite und alles
danach).

<Tip>
  Vollständigen Code, der eine Aktion zum Aufteilen aufruft und jedes Format
  entpackt (das ZIP extrahieren, den JSON-Umschlag dekodieren oder die
  Multipart-Teile lesen), finden Sie im Leitfaden [Ein PDF
  aufteilen](/docs/api/splitting-a-pdf).
</Tip>

## Fehler

Fehlgeschlagene Anfragen geben einen Text vom Typ `application/problem+json`
zurück. Der häufigste Fehler an diesem Endpoint ist `400`, der zurückgegeben
wird, wenn `page` fehlt oder außerhalb des zulässigen Bereichs liegt oder wenn
`file` kein lesbares PDF ist. Das Objekt `errors` benennt jedes Feld:

```json
{
  "type": "https://www.pdfblocks.com/docs/api/v1/error/400",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "errors": {
    "page": ["The field page must be between 2 and the number of pages in the document."]
  }
}
```

Wenn der Header `Accept` keinem der Typen `application/zip`,
`application/json` oder `multipart/mixed` entspricht (zum Beispiel
`Accept: application/pdf`), antwortet die API mit `406 Not Acceptable`. Lassen
Sie `Accept` weg, um die ZIP-Voreinstellung zu erhalten, oder fordern Sie einen
der unterstützten Medientypen an. Ein fehlender oder ungültiger `X-API-Key` gibt einen `401` zurück. Alle
Statuscodes und die vollständige Form der Antwort finden Sie unter
[Fehler](/docs/api/errors).

## Rezepte

Eine häufige Variante. Klappen Sie sie auf, um den Code in allen Sprachen zu
sehen.

<AccordionGroup>

<Accordion title="Die Teile als JSON-Umschlag empfangen">

Senden Sie `Accept: application/json`, um alle Teile inline in einer einzigen
Antwort zu erhalten, und dekodieren Sie dann den `content` jedes Eintrags aus
Base64 in eine Datei, die nach seinem `name` benannt ist:

<CodeGroup>

```bash title="cURL"
curl https://api.pdfblocks.com/v1/split_at_page \
  -H 'X-API-Key: your_api_key' \
  -H 'Accept: application/json' \
  -F file=@input.pdf \
  -F page=5 \
  | jq -r '.documents[] | .name + " " + .content' \
  | while read -r name content; do
      echo "$content" | base64 --decode > "$name"
    done
```

```python title="Python"
# pip install requests
import base64
import requests

with open('input.pdf', 'rb') as file:
    response = requests.post(
        'https://api.pdfblocks.com/v1/split_at_page',
        headers={
            'X-API-Key': 'your_api_key',
            'Accept': 'application/json',
        },
        files={'file': file},
        data={'page': 5},
    )

response.raise_for_status()
for document in response.json()['documents']:
    with open(document['name'], 'wb') as output:
        output.write(base64.b64decode(document['content']))
```

```javascript title="Node.js"
// Node.js 18+
import { readFile, writeFile } from 'node:fs/promises';

const body = new FormData();
body.set('file', new Blob([await readFile('input.pdf')]), 'input.pdf');
body.set('page', '5');

const response = await fetch('https://api.pdfblocks.com/v1/split_at_page', {
  method: 'POST',
  headers: { 'X-API-Key': 'your_api_key', Accept: 'application/json' },
  body,
});

if (!response.ok) throw new Error(`Request failed: ${response.status}`);
const { documents } = await response.json();
for (const doc of documents) {
  await writeFile(doc.name, Buffer.from(doc.content, 'base64'));
}
```

```php title="PHP"
<?php
$ch = curl_init('https://api.pdfblocks.com/v1/split_at_page');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'X-API-Key: your_api_key',
        'Accept: application/json',
    ],
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => [
        'file' => new CURLFile('input.pdf', 'application/pdf'),
        'page' => '5',
    ],
]);

$body = curl_exec($ch);
if (curl_getinfo($ch, CURLINFO_HTTP_CODE) === 200) {
    foreach (json_decode($body, true)['documents'] as $document) {
        file_put_contents($document['name'], base64_decode($document['content']));
    }
}
```

```ruby title="Ruby"
# gem install http
require 'base64'
require 'http'
require 'json'

response = HTTP
  .headers('X-API-Key' => 'your_api_key', 'Accept' => 'application/json')
  .post('https://api.pdfblocks.com/v1/split_at_page', form: {
    file: HTTP::FormData::File.new('input.pdf'),
    page: '5',
  })

if response.status.success?
  JSON.parse(response.body)['documents'].each do |document|
    File.write(document['name'], Base64.decode64(document['content']))
  end
end
```

```go title="Go"
package main

import (
	"bytes"
	"encoding/base64"
	"encoding/json"
	"io"
	"mime/multipart"
	"net/http"
	"os"
)

func main() {
	var buf bytes.Buffer
	form := multipart.NewWriter(&buf)

	file, _ := os.Open("input.pdf")
	defer file.Close()
	part, _ := form.CreateFormFile("file", "input.pdf")
	io.Copy(part, file)

	form.WriteField("page", "5")
	form.Close()

	req, _ := http.NewRequest("POST", "https://api.pdfblocks.com/v1/split_at_page", &buf)
	req.Header.Set("Content-Type", form.FormDataContentType())
	req.Header.Set("X-API-Key", "your_api_key")
	req.Header.Set("Accept", "application/json")

	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()

	var result struct {
		Documents []struct {
			Name    string `json:"name"`
			Content string `json:"content"`
		} `json:"documents"`
	}
	json.NewDecoder(res.Body).Decode(&result)

	for _, doc := range result.Documents {
		data, _ := base64.StdEncoding.DecodeString(doc.Content)
		os.WriteFile(doc.Name, data, 0644)
	}
}
```

```csharp title="C#"
using System.Text.Json;

using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "your_api_key");
client.DefaultRequestHeaders.Add("Accept", "application/json");

using var form = new MultipartFormDataContent
{
    { new ByteArrayContent(File.ReadAllBytes("input.pdf")), "file", "input.pdf" },
    { new StringContent("5"), "page" },
};

var response = await client.PostAsync(
    "https://api.pdfblocks.com/v1/split_at_page", form);
response.EnsureSuccessStatusCode();

using var json = JsonDocument.Parse(
    await response.Content.ReadAsStringAsync());
foreach (var document in json.RootElement.GetProperty("documents").EnumerateArray())
{
    var name = document.GetProperty("name").GetString()!;
    var content = document.GetProperty("content").GetString()!;
    await File.WriteAllBytesAsync(name, Convert.FromBase64String(content));
}
```

</CodeGroup>

</Accordion>

</AccordionGroup>

## Verwandte Aktionen

<CardGroup cols={2}>

<Card title="Nach Seitenanzahl aufteilen" href="/docs/api/split-pdf-by-page-count">
  In Blöcke fester Größe aufteilen.
</Card>

<Card title="Nach Dateigröße aufteilen" href="/docs/api/split-pdf-by-file-size">
  Jeden Teil auf eine Größe in Bytes begrenzen.
</Card>

<Card title="Seiten extrahieren" href="/docs/api/extract-pages-from-pdf">
  Nur einen Teil des Dokuments behalten.
</Card>

<Card title="In Seitengruppen aufteilen" href="/docs/api/split-pdf-into-page-groups">
  Beliebige Seitengruppen von Hand festlegen.
</Card>

</CardGroup>
