# Ruotare le pagine di un PDF

Ruotare le pagine selezionate di un PDF di un angolo fisso, in senso orario o antiorario.

Ruotare le pagine di un documento PDF di un angolo fisso. Gli angoli positivi
ruotano in senso orario, quelli negativi in senso antiorario. Per impostazione
predefinita vengono ruotate tutte le pagine: utilizzare il parametro
[`pages`](#selezionare-le-pagine) per agire solo su un sottoinsieme. L’API è
*stateless*: il documento viene elaborato nella regione e non viene mai
memorizzato.

## Endpoint

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

Disponibile in tutte le regioni. Vedere [Regioni e residenza dei
dati](/docs/api/regions-and-data-residency) per il routing e la residenza dei
dati.

| Regione           | URL                                               |
| ----------------- | ------------------------------------------------- |
| Globale           | `https://api.pdfblocks.com/v1/rotate_pages`       |
| Stati Uniti       | `https://us.api.pdfblocks.com/v1/rotate_pages`    |
| HIPAA Stati Uniti | `https://hipaa.api.pdfblocks.com/v1/rotate_pages` |
| Unione europea    | `https://eu.api.pdfblocks.com/v1/rotate_pages`    |
| Regno Unito       | `https://uk.api.pdfblocks.com/v1/rotate_pages`    |
| Canada            | `https://ca.api.pdfblocks.com/v1/rotate_pages`    |
| Australia         | `https://au.api.pdfblocks.com/v1/rotate_pages`    |
| Giappone          | `https://jp.api.pdfblocks.com/v1/rotate_pages`    |
| India             | `https://in.api.pdfblocks.com/v1/rotate_pages`    |
| Brasile           | `https://br.api.pdfblocks.com/v1/rotate_pages`    |

## Autenticazione

Autenticare ogni richiesta con la chiave API segreta nell’intestazione
`X-API-Key`, tramite HTTPS. Le chiavi si creano e si gestiscono dalla
[dashboard](https://dashboard.pdfblocks.com). Vedere
[Autenticazione](/docs/api/authentication) per i dettagli.

## Richiesta

L’endpoint accetta un corpo della richiesta `multipart/form-data`.

<ParamField name="file" type="file" required>
  Il documento PDF di input.
</ParamField>

<ParamField name="angle" type="integer" required>
  La rotazione da applicare, in gradi. Uno degli [angoli
  validi](#angoli-di-rotazione). I valori positivi ruotano in senso orario,
  quelli negativi in senso antiorario.
</ParamField>

<ParamField name="pages" type="string">
  Le pagine da ruotare, scritte come [intervallo di
  pagine](#selezionare-le-pagine), ad esempio `1..3,5`. Se omesso, vengono
  ruotate tutte le pagine. Massimo 1000 caratteri.
</ParamField>

### Angoli di rotazione

Passare al parametro `angle` uno dei valori seguenti.

| Angolo  | Rotazione                                       |
| ------- | ----------------------------------------------- |
| `0`     | Nessuna rotazione                               |
| `90`    | 90° in senso orario                             |
| `180`   | 180°                                            |
| `270`   | 270° in senso orario (90° in senso antiorario)  |
| `-90`   | 90° in senso antiorario                         |
| `-180`  | 180°                                            |
| `-270`  | 270° in senso antiorario (90° in senso orario)  |

Gli angoli positivi ruotano in senso orario, quelli negativi in senso
antiorario; ogni rotazione si somma alla rotazione attuale della pagina.

### Selezionare le pagine

Il parametro `pages` accetta un elenco di numeri di pagina in base 1 e di
intervalli, separati da virgole. Viene trattato come un **insieme**: l’ordine e
i duplicati sono ignorati e le pagine vengono sempre ruotate nell’ordine del
documento.

| Schema      | Seleziona                                  |
| ----------- | ------------------------------------------ |
| *(omesso)*  | Tutte le pagine                            |
| `1`         | Solo la prima pagina                       |
| `1..3,5`    | Le pagine 1, 2, 3 e 5                      |
| `2..`       | Dalla pagina 2 all’ultima pagina           |
| `..-2`      | Dalla prima pagina alla penultima          |
| `-1`        | L’ultima pagina                            |

Vedere [Selezionare le pagine](/docs/api/selecting-pages) per il riferimento
completo.

## Esempi

Ruotare le prime tre pagine di 90° in senso orario:

<CodeGroup>

```bash title="cURL"
curl https://api.pdfblocks.com/v1/rotate_pages \
  -H 'X-API-Key: your_api_key' \
  -F file=@input.pdf \
  -F angle=90 \
  -F pages='1..3' \
  -o rotated.pdf
```

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

with open('input.pdf', 'rb') as file:
    response = requests.post(
        'https://api.pdfblocks.com/v1/rotate_pages',
        headers={'X-API-Key': 'your_api_key'},
        files={'file': file},
        data={
            'angle': 90,
            'pages': '1..3',
        },
    )

response.raise_for_status()
with open('rotated.pdf', '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('angle', '90');
body.set('pages', '1..3');

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

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

```php title="PHP"
<?php
$ch = curl_init('https://api.pdfblocks.com/v1/rotate_pages');
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'),
        'angle' => '90',
        'pages' => '1..3',
    ],
]);

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

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

response = HTTP
  .headers('X-API-Key' => 'your_api_key')
  .post('https://api.pdfblocks.com/v1/rotate_pages', form: {
    file: HTTP::FormData::File.new('input.pdf'),
    angle: '90',
    pages: '1..3',
  })

File.write('rotated.pdf', 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("angle", "90")
	form.WriteField("pages", "1..3")
	form.Close()

	req, _ := http.NewRequest("POST", "https://api.pdfblocks.com/v1/rotate_pages", &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("rotated.pdf")
	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("90"), "angle" },
    { new StringContent("1..3"), "pages" },
};

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

</CodeGroup>

## Risposta

In caso di successo, la risposta è `200 OK` e il corpo contiene il PDF ruotato:

```http
HTTP/1.1 200 OK
Content-Type: application/pdf
Content-Length: 48213
```

L’output conserva le stesse pagine e lo stesso contenuto dell’input: cambia solo
la rotazione delle pagine selezionate. Scrivere il corpo direttamente in un
file, come fanno gli esempi qui sopra; non viene memorizzato nulla dalla nostra
parte.

## Errori

Le richieste non riuscite restituiscono un corpo `application/problem+json`.
L’errore più frequente su questo endpoint è un `400`, restituito quando `angle`
non è uno dei valori supportati o `file` non è un PDF leggibile. L’oggetto
`errors` indica ciascun campo:

```json
{
  "type": "https://www.pdfblocks.com/docs/api/v1/error/400",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "errors": {
    "angle": ["The angle must be one of 0, 90, 180, 270, -90, -180, -270."]
  }
}
```

Una `X-API-Key` mancante o non valida restituisce un `401`. Vedere
[Errori](/docs/api/errors) per tutti i codici di stato e la forma completa della
risposta.

## Ricette

Varianti comuni. Espanderne una per vederla in tutti i linguaggi.

<AccordionGroup>

<Accordion title="Raddrizzare una scansione in orizzontale">

<CodeGroup>

```bash title="cURL"
curl https://api.pdfblocks.com/v1/rotate_pages \
  -H 'X-API-Key: your_api_key' \
  -F file=@input.pdf \
  -F angle=90 \
  -o upright.pdf
```

```python title="Python"
import requests

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

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

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

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

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

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

```php title="PHP"
<?php
$ch = curl_init('https://api.pdfblocks.com/v1/rotate_pages');
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'),
        'angle' => '90',
    ],
]);

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

```ruby title="Ruby"
require 'http'

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

File.write('upright.pdf', 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("angle", "90")
	form.Close()

	req, _ := http.NewRequest("POST", "https://api.pdfblocks.com/v1/rotate_pages", &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("upright.pdf")
	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("90"), "angle" },
};

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

</CodeGroup>

</Accordion>

<Accordion title="Capovolgere tutte le pagine di 180°">

<CodeGroup>

```bash title="cURL"
curl https://api.pdfblocks.com/v1/rotate_pages \
  -H 'X-API-Key: your_api_key' \
  -F file=@input.pdf \
  -F angle=180 \
  -o flipped.pdf
```

```python title="Python"
import requests

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

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

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

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

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

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

```php title="PHP"
<?php
$ch = curl_init('https://api.pdfblocks.com/v1/rotate_pages');
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'),
        'angle' => '180',
    ],
]);

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

```ruby title="Ruby"
require 'http'

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

File.write('flipped.pdf', 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("angle", "180")
	form.Close()

	req, _ := http.NewRequest("POST", "https://api.pdfblocks.com/v1/rotate_pages", &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("flipped.pdf")
	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("180"), "angle" },
};

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

</CodeGroup>

</Accordion>

</AccordionGroup>

## Azioni correlate

<CardGroup cols={2}>

<Card title="Invertire le pagine" href="/docs/api/reverse-pages-of-pdf">
  Invertire l’ordine delle pagine.
</Card>

<Card title="Riordinare le pagine" href="/docs/api/reorder-pages-of-pdf">
  Riorganizzare le pagine in qualsiasi ordine.
</Card>

<Card title="Estrarre pagine" href="/docs/api/extract-pages-from-pdf">
  Estrarre un sottoinsieme di pagine.
</Card>

<Card title="Rimuovere pagine" href="/docs/api/remove-pages-from-pdf">
  Scartare pagine dal documento.
</Card>

</CardGroup>
