# Quitar páginas de un PDF

Quite una selección de páginas de un PDF con el parámetro pages. Siempre queda al menos una página, así que la selección no puede abarcar todo el documento.

Quite una o más páginas de un documento PDF. Seleccione las páginas que se
descartan con el parámetro [`pages`](#seleccionar-páginas); como debe quedar al
menos una página, la selección no puede cubrirlas todas. La API es
*stateless*: su documento se procesa en la región y nunca se almacena.

## Endpoint

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

Disponible en todas las regiones. Consulte [Regiones y residencia de
datos](/docs/api/regions-and-data-residency) para el enrutamiento y la
residencia de datos.

| Región           | URL                                                 |
| ---------------- | --------------------------------------------------- |
| Global           | `https://api.pdfblocks.com/v1/remove_pages`         |
| Estados Unidos   | `https://us.api.pdfblocks.com/v1/remove_pages`      |
| HIPAA de EE. UU. | `https://hipaa.api.pdfblocks.com/v1/remove_pages`   |
| Unión Europea    | `https://eu.api.pdfblocks.com/v1/remove_pages`      |
| Reino Unido      | `https://uk.api.pdfblocks.com/v1/remove_pages`      |
| Canadá           | `https://ca.api.pdfblocks.com/v1/remove_pages`      |
| Australia        | `https://au.api.pdfblocks.com/v1/remove_pages`      |
| Japón            | `https://jp.api.pdfblocks.com/v1/remove_pages`      |
| India            | `https://in.api.pdfblocks.com/v1/remove_pages`      |
| Brasil           | `https://br.api.pdfblocks.com/v1/remove_pages`      |

## Autenticación

Autentique cada solicitud con su clave de API secreta en la cabecera
`X-API-Key`, por HTTPS. Cree y administre sus claves desde el
[dashboard](https://dashboard.pdfblocks.com). Consulte
[Autenticación](/docs/api/authentication) para más detalles.

## Solicitud

El endpoint acepta un cuerpo de solicitud `multipart/form-data`.

<ParamField name="file" type="file" required>
  El documento PDF de entrada.
</ParamField>

<ParamField name="pages" type="string" required>
  Las páginas que se quitarán, escritas como un [rango de
  páginas](#seleccionar-páginas) tipo `2,4..6`. La selección no puede cubrir
  todas las páginas: debe quedar al menos una. Máximo 1000 caracteres.
</ParamField>

### Seleccionar páginas

El parámetro `pages` recibe una lista separada por comas de números de página
en base 1 y de rangos. Se trata como un **conjunto**: el orden y los
duplicados se ignoran, y las páginas que quedan conservan su orden original
en el documento.

| Patrón    | Quita                                      |
| --------- | ------------------------------------------ |
| `1`       | Solo la primera página                     |
| `1..3,5`  | Las páginas 1, 2, 3 y 5                    |
| `2..`     | De la página 2 a la última                 |
| `..-2`    | De la primera página a la penúltima        |
| `-1`      | La última página                           |

Consulte [Seleccionar páginas](/docs/api/selecting-pages) para ver la
referencia completa.

<Note>
  La selección es un **conjunto** y debe dejar al menos una página. Una
  selección que cubra todas las páginas se rechaza con un `400`.
</Note>

## Ejemplos

Quite la página 2 y las páginas 4 a 6 de un PDF:

<CodeGroup>

```bash title="cURL"
curl https://api.pdfblocks.com/v1/remove_pages \
  -H 'X-API-Key: your_api_key' \
  -F file=@input.pdf \
  -F pages='2,4..6' \
  -o trimmed.pdf
```

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

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

response.raise_for_status()
with open('trimmed.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('pages', '2,4..6');

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

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

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

$pdf = curl_exec($ch);
if (curl_getinfo($ch, CURLINFO_HTTP_CODE) === 200) {
    file_put_contents('trimmed.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/remove_pages', form: {
    file: HTTP::FormData::File.new('input.pdf'),
    pages: '2,4..6',
  })

File.write('trimmed.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("pages", "2,4..6")
	form.Close()

	req, _ := http.NewRequest("POST", "https://api.pdfblocks.com/v1/remove_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("trimmed.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("2,4..6"), "pages" },
};

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

</CodeGroup>

## Respuesta

Si todo va bien, la respuesta es `200 OK` con el PDF recortado como cuerpo:

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

Las páginas restantes conservan su orden original: solo se descartan las
páginas seleccionadas. Escriba el cuerpo directamente en un archivo, como
hacen los ejemplos anteriores; en nuestro lado no se almacena nada.

## Errores

Las solicitudes fallidas devuelven un cuerpo `application/problem+json`. El
error más habitual en este endpoint es un `400`, que se devuelve cuando `pages`
está mal formado o quitaría todas las páginas: el objeto `errors` nombra cada
campo:

```json
{
  "type": "https://www.pdfblocks.com/docs/api/v1/error/400",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "errors": {
    "pages": ["At least one page must remain, so the selection cannot cover every page."]
  }
}
```

Una `X-API-Key` ausente o no válida devuelve un `401`. Consulte
[Errores](/docs/api/errors) para ver todos los códigos de estado y la forma
completa de la respuesta.

## Recetas

Variantes habituales. Despliegue una para verla en todos los lenguajes.

<AccordionGroup>

<Accordion title="Descartar la última página">

<CodeGroup>

```bash title="cURL"
curl https://api.pdfblocks.com/v1/remove_pages \
  -H 'X-API-Key: your_api_key' \
  -F file=@input.pdf \
  -F pages='-1' \
  -o without-last.pdf
```

```python title="Python"
import requests

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

response.raise_for_status()
with open('without-last.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('pages', '-1');

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

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

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

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

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

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

File.write('without-last.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("pages", "-1")
	form.Close()

	req, _ := http.NewRequest("POST", "https://api.pdfblocks.com/v1/remove_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("without-last.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("-1"), "pages" },
};

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

</CodeGroup>

</Accordion>

<Accordion title="Quitar la portada">

<CodeGroup>

```bash title="cURL"
curl https://api.pdfblocks.com/v1/remove_pages \
  -H 'X-API-Key: your_api_key' \
  -F file=@input.pdf \
  -F pages='1' \
  -o no-cover.pdf
```

```python title="Python"
import requests

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

response.raise_for_status()
with open('no-cover.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('pages', '1');

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

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

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

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

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

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

File.write('no-cover.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("pages", "1")
	form.Close()

	req, _ := http.NewRequest("POST", "https://api.pdfblocks.com/v1/remove_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("no-cover.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("1"), "pages" },
};

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

</CodeGroup>

</Accordion>

</AccordionGroup>

## Acciones relacionadas

<CardGroup cols={2}>

<Card title="Extraer páginas" href="/docs/api/extract-pages-from-pdf">
  Conserve páginas en lugar de descartarlas.
</Card>

<Card title="Reordenar páginas" href="/docs/api/reorder-pages-of-pdf">
  Reorganice las páginas restantes.
</Card>

<Card title="Invertir páginas" href="/docs/api/reverse-pages-of-pdf">
  Invierta el orden de las páginas.
</Card>

<Card title="Girar páginas" href="/docs/api/rotate-pages-in-pdf">
  Gire las páginas seleccionadas.
</Card>

</CardGroup>
