# Diviser un PDF par taille de fichier

Divisez un PDF en documents plus petits, chacun ne dépassant pas une taille maximale en octets.

Divisez un document PDF en plusieurs documents plus petits, chacun ne dépassant
pas une taille de fichier maximale en octets. Cette action renvoie plusieurs
documents, empaquetés dans une seule réponse selon l’en-tête `Accept`. L’API est
*stateless* : votre document est traité dans sa région et n’est jamais stocké.

## Endpoint

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

Disponible dans toutes les régions. Voir [Régions et résidence des
données](/docs/api/regions-and-data-residency) pour le routage et la résidence
des données.

| Région           | URL                                              |
| ---------------- | ------------------------------------------------ |
| Global           | `https://api.pdfblocks.com/v1/split_by_size`     |
| États-Unis       | `https://us.api.pdfblocks.com/v1/split_by_size`  |
| HIPAA États-Unis | `https://hipaa.api.pdfblocks.com/v1/split_by_size` |
| Union européenne | `https://eu.api.pdfblocks.com/v1/split_by_size`  |
| Royaume-Uni      | `https://uk.api.pdfblocks.com/v1/split_by_size`  |
| Canada           | `https://ca.api.pdfblocks.com/v1/split_by_size`  |
| Australie        | `https://au.api.pdfblocks.com/v1/split_by_size`  |
| Japon            | `https://jp.api.pdfblocks.com/v1/split_by_size`  |
| Inde             | `https://in.api.pdfblocks.com/v1/split_by_size`  |
| Brésil           | `https://br.api.pdfblocks.com/v1/split_by_size`  |

## Authentification

Authentifiez chaque requête avec votre clé d’API secrète dans l’en-tête
`X-API-Key`, en HTTPS. Créez et gérez vos clés depuis le
[dashboard](https://dashboard.pdfblocks.com). Voir
[Authentification](/docs/api/authentication) pour le détail.

## Requête

L’endpoint accepte un corps de requête `multipart/form-data`.

<ParamField name="file" type="file" required>
  Le document PDF d’entrée.
</ParamField>

<ParamField name="maximum_bytes" type="integer" required>
  La taille maximale, en octets, de chaque PDF de sortie. Doit être supérieure ou
  égale à `1`.
</ParamField>

## Exemples

Divisez un document de sorte que chaque partie fasse au plus 1 Mo :

<CodeGroup>

```bash title="cURL"
curl https://api.pdfblocks.com/v1/split_by_size \
  -H 'X-API-Key: your_api_key' \
  -F file=@input.pdf \
  -F maximum_bytes=1048576 \
  -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_by_size',
        headers={'X-API-Key': 'your_api_key'},
        files={'file': file},
        data={'maximum_bytes': 1048576},  # 1 MB
    )

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('maximum_bytes', '1048576'); // 1 MB

const response = await fetch('https://api.pdfblocks.com/v1/split_by_size', {
  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_by_size');
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'),
        'maximum_bytes' => '1048576', // 1 MB
    ],
]);

$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_by_size', form: {
    file: HTTP::FormData::File.new('input.pdf'),
    maximum_bytes: '1048576', # 1 MB
  })

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("maximum_bytes", "1048576") // 1 MB
	form.Close()

	req, _ := http.NewRequest("POST", "https://api.pdfblocks.com/v1/split_by_size", &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("1048576"), "maximum_bytes" }, // 1 MB
};

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

</CodeGroup>

## Réponse

Cette action renvoie plusieurs documents, empaquetés dans une seule réponse
selon l’en-tête de requête `Accept` : voir
[Formats de réponse et négociation de contenu](/docs/api/response-formats) pour
la référence complète de la négociation. Sans en-tête `Accept`, une archive ZIP
est renvoyée par défaut :

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

Sélectionnez l’empaquetage avec l’en-tête `Accept` :

| En-tête `Accept`     | Réponse                                                         |
| -------------------- | -------------------------------------------------------------- |
| *(aucun envoyé)*     | `application/zip` : la valeur par défaut                       |
| `application/zip`    | Une archive ZIP des PDF de sortie                              |
| `application/json`   | Une enveloppe JSON de documents encodés en base64              |
| `multipart/mixed`    | Un PDF par partie                                              |
| toute autre valeur   | `406 Not Acceptable`                                            |

Les documents de sortie sont nommés `00001.pdf`, `00002.pdf`, et ainsi de suite,
dans l’ordre.

<Note>
  Chaque partie est remplie jusqu’à juste en dessous de `maximum_bytes`, d’après
  la taille de la sortie générée, de sorte que les parties approchent la limite
  sans jamais la dépasser. L’exception est une page dont la taille dépasse déjà à
  elle seule `maximum_bytes` : elle est renvoyée comme une partie à elle seule
  qui dépasse la limite, car une page n’est jamais divisée.
</Note>

<Tip>
  Pour du code de bout en bout qui appelle une action de division et dépaquette
  chaque format, qu’il s’agisse d’extraire le ZIP, de décoder l’enveloppe JSON ou
  de lire les parties multipart, voir le guide [Diviser un PDF et traiter la
  sortie](/docs/api/splitting-a-pdf).
</Tip>

## Erreurs

Les requêtes en échec renvoient un corps `application/problem+json`. La plus
courante sur cet endpoint est une `400`, renvoyée lorsque `maximum_bytes` est
absent ou inférieur à `1`, ou lorsque `file` n’est pas un PDF lisible : l’objet
`errors` nomme chaque champ :

```json
{
  "type": "https://www.pdfblocks.com/docs/api/v1/error/400",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "errors": {
    "maximum_bytes": ["The field maximum_bytes must be greater than or equal to 1."]
  }
}
```

Si l’en-tête `Accept` ne correspond à aucun des types `application/zip`,
`application/json` ou `multipart/mixed`, par exemple `Accept: application/pdf`,
l’API répond `406 Not Acceptable`. Omettez `Accept` pour prendre le ZIP par
défaut, ou demandez l’un des types de médias pris en charge. Une `X-API-Key`
absente ou non valide renvoie une `401`. Voir [Erreurs](/docs/api/errors) pour
tous les codes de statut et la forme complète de la réponse.

## Recettes

Une variante courante. Dépliez-la pour la voir dans tous les langages.

<AccordionGroup>

<Accordion title="Recevoir les parties dans une enveloppe JSON">

Envoyez `Accept: application/json` pour obtenir toutes les parties en ligne dans
une seule réponse, puis décodez en base64 le `content` de chaque entrée vers un
fichier nommé d’après son `name` :

<CodeGroup>

```bash title="cURL"
curl https://api.pdfblocks.com/v1/split_by_size \
  -H 'X-API-Key: your_api_key' \
  -H 'Accept: application/json' \
  -F file=@input.pdf \
  -F maximum_bytes=1048576 \
  | 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_by_size',
        headers={
            'X-API-Key': 'your_api_key',
            'Accept': 'application/json',
        },
        files={'file': file},
        data={'maximum_bytes': 1048576},
    )

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('maximum_bytes', '1048576');

const response = await fetch('https://api.pdfblocks.com/v1/split_by_size', {
  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_by_size');
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'),
        'maximum_bytes' => '1048576',
    ],
]);

$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_by_size', form: {
    file: HTTP::FormData::File.new('input.pdf'),
    maximum_bytes: '1048576',
  })

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("maximum_bytes", "1048576")
	form.Close()

	req, _ := http.NewRequest("POST", "https://api.pdfblocks.com/v1/split_by_size", &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("1048576"), "maximum_bytes" },
};

var response = await client.PostAsync(
    "https://api.pdfblocks.com/v1/split_by_size", 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>

## Actions associées

<CardGroup cols={2}>

<Card title="Diviser par nombre de pages" href="/docs/api/split-pdf-by-page-count">
  Divisez par nombre de pages plutôt que par octets.
</Card>

<Card title="Diviser à une page" href="/docs/api/split-pdf-at-page">
  Divisez en deux documents à un point de coupure.
</Card>

<Card title="Diviser en groupes de pages" href="/docs/api/split-pdf-into-page-groups">
  Définissez à la main des groupes de pages arbitraires.
</Card>

<Card title="Extraire des pages" href="/docs/api/extract-pages-from-pdf">
  Conservez une plage de pages.
</Card>

</CardGroup>
