# PagesApi

The Manage Pages panel, headless: the panel's actions do what these members do. Every member that changes the pages (`insert`, `delete`, `move`, `rotate`, `setRotation`, `duplicate`, `import`) needs the license's `edit-pages` feature, as the panel does, and `extract` needs `export`; without them they refuse with `FEATURE_NOT_LICENSED`, before the document's own permissions and signature checks. Each change is made to the open document at once, and a viewer showing it records an undo step; the panel's changes become one undo step on **Apply changes**, and **Cancel** undoes them.

On a certified document, every write the certification forbids rejects with `INVALID_STATE` unless the call passes `invalidateSignatures: true` — the certification is then broken for good and nothing is asked again (see [Document features](https://kernstra.com/docs/web-sdk/guides/document-features)). On a progressive document every write, and `extract`, rejects with `INVALID_STATE` until `doc.whenFullyLoaded()` resolves.

Page boxes are [`Rect`](https://kernstra.com/docs/web-sdk/api/types#ty-rect)s in page space: PDF points, the origin at the page's bottom-left corner, `y` growing upwards, unturned by the page's rotation. Page sizes are in points too.

- Kind: namespace
- Access: `doc.pages`

## Usage

```ts
await doc.pages.insert({ position: { after: 0 }, size: { width: 612, height: 792 } }); // US Letter, page 2
await doc.pages.rotate(0, 90);
await doc.pages.setRotation(1, 0); // upright, whatever it was
await doc.pages.move(3, 0);

const coverAndTerms = await doc.pages.extract([0, 4]);
// .slice() gives an ArrayBuffer-backed copy, which TypeScript 5.7+ requires of a request body.
await fetch('/upload', { method: 'PUT', body: coverAndTerms.slice() });
```

## Reading

### `count`

```ts
get count(): number
```

Number of pages the document has now. A getter: answers at once, and throws `DOCUMENT_CLOSED` on a closed document.

- Kind: getter
- Since: 1.0.0

Returns `number`

Throws:

- `DOCUMENT_CLOSED` — read on a closed document.

```ts
const last = doc.pages.count - 1;
```

Page: https://kernstra.com/docs/web-sdk/api/doc-pages/count

### `boxes`

```ts
boxes(pageIndex: number): Promise<PageBoxes>
```

The page's MediaBox / CropBox / BleedBox / TrimBox / ArtBox, read without loading it.

- Kind: method
- Since: 1.0.0

| Parameter | Type | Description |
| --- | --- | --- |
| `pageIndex` | `number` | Zero-based page index. |

Returns `Promise<PageBoxes>`: `{ mediaBox, cropBox, trimBox, bleedBox, artBox }`, every box a `Rect` in page space, resolved as a reader resolves it: the MediaBox is the full sheet (US Letter when the file has none); the CropBox is what renders (the MediaBox when the file declares none); the TrimBox, BleedBox and ArtBox fall back to the CropBox.

Throws:

- `INVALID_ARGUMENT` — a page index out of range.
- `DOCUMENT_CLOSED` — the document has been closed.

```ts
const { cropBox } = await doc.pages.boxes(0);
console.log(cropBox.width, cropBox.height); // points
```

Page: https://kernstra.com/docs/web-sdk/api/doc-pages/boxes

### `getRotation`

```ts
getRotation(pageIndex: number): Promise<PageOrientation>
```

The page's rotation as the file holds it: `0`, `90`, `180` or `270`.

- Kind: method
- Since: 1.0.0

| Parameter | Type | Description |
| --- | --- | --- |
| `pageIndex` | `number` | Zero-based page index. |

Returns `Promise<PageOrientation>`: `0`, `90`, `180` or `270`.

Throws:

- `INVALID_ARGUMENT` — a page index out of range.
- `DOCUMENT_CLOSED` — the document has been closed.

```ts
const upright = (await doc.pages.getRotation(0)) === 0;
```

Page: https://kernstra.com/docs/web-sdk/api/doc-pages/getrotation

## Structure

### `insert`

```ts
insert(options?: InsertPageOptions): Promise<number>
```

Inserts a blank page. Needs the `edit-pages` feature.

- Kind: method
- Since: 1.0.0

| Parameter | Type | Description |
| --- | --- | --- |
| `options?` | `InsertPageOptions` | `position` is `{ after }` or `{ before }` (zero-based); omit to append. `size` is `{ width, height }` in points, default A4. `invalidateSignatures` breaks a certification that forbids the change. |

Returns `Promise<number>`: The index the new page landed at.

Throws:

- `FEATURE_NOT_LICENSED` — the license lacks `edit-pages`.
- `INVALID_ARGUMENT` — the position is not a whole number (one past the ends is clamped).
- `PAGE_ERROR` — the page tree is nested too deeply, or the page could not be created.
- `DOCUMENT_CLOSED` — the document has been closed.
- `INVALID_STATE` — a certified document whose certification forbids it, unless `options.invalidateSignatures`; or a progressive document still downloading.

```ts
await doc.pages.insert({ position: { after: 0 } }); // second page, A4
await doc.pages.insert({ size: { width: 612, height: 792 } }); // US Letter, at the end
```

Page: https://kernstra.com/docs/web-sdk/api/doc-pages/insert

### `delete`

```ts
delete(pageIndex: number, options?: SignedDocumentOptions): Promise<void>
```

Deletes a page. Refused with `INVALID_ARGUMENT` when it would empty the document. Needs the `edit-pages` feature.

- Kind: method
- Since: 1.0.0

| Parameter | Type | Description |
| --- | --- | --- |
| `pageIndex` | `number` | Zero-based page index. |
| `options?` | `SignedDocumentOptions` | `{ invalidateSignatures? }`. |

Returns `Promise<void>`

Throws:

- `INVALID_ARGUMENT` — a page index out of range, or deleting the only page.
- `PAGE_ERROR` — the page tree is nested too deeply.
- `FEATURE_NOT_LICENSED` — the license lacks `edit-pages`.
- `DOCUMENT_CLOSED` — the document has been closed.
- `INVALID_STATE` — a certified document whose certification forbids it, unless `options.invalidateSignatures`; or a progressive document still downloading.

```ts
await doc.pages.delete(doc.pages.count - 1); // drop the last page
```

Page: https://kernstra.com/docs/web-sdk/api/doc-pages/delete

### `move`

```ts
move(from: number, to: number, options?: SignedDocumentOptions): Promise<void>
```

Moves a page to a new index. Needs the `edit-pages` feature.

- Kind: method
- Since: 1.0.0

| Parameter | Type | Description |
| --- | --- | --- |
| `from` | `number` | Current zero-based index. |
| `to` | `number` | The index it should occupy afterwards. |
| `options?` | `SignedDocumentOptions` | `{ invalidateSignatures? }`. |

Returns `Promise<void>`

Throws:

- `INVALID_ARGUMENT` — a page index or the destination out of range.
- `PAGE_ERROR` — the page could not be moved, or the page tree is nested too deeply.
- `FEATURE_NOT_LICENSED` — the license lacks `edit-pages`.
- `DOCUMENT_CLOSED` — the document has been closed.
- `INVALID_STATE` — a certified document whose certification forbids it, unless `options.invalidateSignatures`; or a progressive document still downloading.

```ts
await doc.pages.move(3, 0); // make page 4 the cover
```

Page: https://kernstra.com/docs/web-sdk/api/doc-pages/move

### `rotate`

```ts
rotate(pageIndex: number, by: PageTurn, options?: SignedDocumentOptions): Promise<void>
```

Turns the page by `by` clockwise degrees from where it stands. Needs the `edit-pages` feature.

- Kind: method
- Since: 1.0.0

| Parameter | Type | Description |
| --- | --- | --- |
| `pageIndex` | `number` | Zero-based page index. |
| `by` | `PageTurn` | Clockwise degrees from where the page stands: `90`, `180`, `270`, or negative for counter-clockwise. |
| `options?` | `SignedDocumentOptions` | `{ invalidateSignatures? }`. |

Returns `Promise<void>`

Throws:

- `INVALID_ARGUMENT` — a page index out of range, or `by` is `0` or anything but a multiple of 90.
- `PAGE_ERROR` — the page could not be loaded.
- `FEATURE_NOT_LICENSED` — the license lacks `edit-pages`.
- `DOCUMENT_CLOSED` — the document has been closed.
- `INVALID_STATE` — a certified document whose certification forbids it, unless `options.invalidateSignatures`; or a progressive document still downloading.

```ts
await doc.pages.rotate(0, 90);
await doc.pages.rotate(1, -90); // counter-clockwise
```

Page: https://kernstra.com/docs/web-sdk/api/doc-pages/rotate

### `setRotation`

```ts
setRotation(pageIndex: number, rotation: PageOrientation, options?: SignedDocumentOptions): Promise<void>
```

Sets the page's rotation outright. Needs the `edit-pages` feature.

- Kind: method
- Since: 1.0.0

| Parameter | Type | Description |
| --- | --- | --- |
| `pageIndex` | `number` | Zero-based page index. |
| `rotation` | `PageOrientation` | `0`, `90`, `180` or `270` clockwise degrees, as the file will hold it. |
| `options?` | `SignedDocumentOptions` | `{ invalidateSignatures? }`. |

Returns `Promise<void>`

Throws:

- `INVALID_ARGUMENT` — a page index out of range, or a rotation that is not 0, 90, 180 or 270.
- `PAGE_ERROR` — the page could not be loaded.
- `FEATURE_NOT_LICENSED` — the license lacks `edit-pages`.
- `DOCUMENT_CLOSED` — the document has been closed.
- `INVALID_STATE` — a certified document whose certification forbids it, unless `options.invalidateSignatures`; or a progressive document still downloading.

```ts
await doc.pages.setRotation(1, 0); // upright, whatever it was
```

Page: https://kernstra.com/docs/web-sdk/api/doc-pages/setrotation

### `duplicate`

```ts
duplicate(pageIndex: number, options?: SignedDocumentOptions): Promise<number>
```

Copies a page and inserts the copy right after it. The copy's form fields are its original's: filling one fills both (left outside the form: a signature field's copy, and every copy in an encrypted document or one with a signed field). Needs the `edit-pages` feature.

- Kind: method
- Since: 1.0.0

| Parameter | Type | Description |
| --- | --- | --- |
| `pageIndex` | `number` | Zero-based page index. |
| `options?` | `SignedDocumentOptions` | `{ invalidateSignatures? }`. |

Returns `Promise<number>`: The copy's index.

Throws:

- `INVALID_ARGUMENT` — a page index out of range.
- `PAGE_ERROR` — the page tree is nested too deeply, or the page could not be copied.
- `FEATURE_NOT_LICENSED` — the license lacks `edit-pages`.
- `DOCUMENT_CLOSED` — the document has been closed.
- `INVALID_STATE` — a certified document whose certification forbids it, unless `options.invalidateSignatures`; or a progressive document still downloading.

```ts
const copyIndex = await doc.pages.duplicate(0);
```

Page: https://kernstra.com/docs/web-sdk/api/doc-pages/duplicate

## Import and extract

### `extract`

```ts
extract(indices: number[]): Promise<Uint8Array>
```

Builds a **new** PDF from those pages, in that order. The source is untouched. A page with form fields comes out flattened, as it prints: its fields do not go to another document. The new document gets a creation date. Needs the `export` feature.

- Kind: method
- Since: 1.0.0

| Parameter | Type | Description |
| --- | --- | --- |
| `indices` | `number[]` | Zero-based page indices, in the order they should appear. |

Returns `Promise<Uint8Array>`: The new PDF's bytes.

Throws:

- `INVALID_ARGUMENT` — no pages, or a page the document lacks.
- `PAGE_ERROR` — the pages could not be copied.
- `EXPORT_FAILED` — a page with form fields could not be flattened, or the new document could not be watermarked or serialized.
- `FEATURE_NOT_LICENSED` — the license lacks `export`.
- `DOCUMENT_CLOSED` — the document has been closed.
- `INVALID_STATE` — a progressive document still downloading.

```ts
const firstTwo = await doc.pages.extract([0, 1]);
```

Page: https://kernstra.com/docs/web-sdk/api/doc-pages/extract

### `import`

```ts
import(bytes: Uint8Array, options?: ImportPagesOptions): Promise<number>
```

Inserts every page of another PDF. A page with form fields comes in flattened, as it prints: its fields do not join this document's form. Needs the `edit-pages` feature.

Importing is a load for the license, once the imported file has opened: under a stopped license (paused, revoked, expired, a copied or forged key) it is refused with `LICENSE_REQUIRED`, as opening a document is.

- Kind: method
- Since: 1.0.0

| Parameter | Type | Description |
| --- | --- | --- |
| `bytes` | `Uint8Array` | The source PDF. |
| `options?` | `ImportPagesOptions` | `position` (`{ after }` or `{ before }`; appended when omitted), `password` (the source's, if it is encrypted) and `invalidateSignatures`. |

Returns `Promise<number>`: How many pages came in.

Throws:

- `FEATURE_NOT_LICENSED` — the license lacks `edit-pages`.
- `LICENSE_REQUIRED` — the license is stopped.
- `FORMAT_ERROR` — the imported bytes are not a PDF, or a corrupt one.
- `PASSWORD_ERROR` — the imported file needs a password, or `options.password` is wrong.
- `SECURITY_ERROR` — the imported file is encrypted with a security handler the SDK cannot open.
- `INVALID_ARGUMENT` — the position is not a whole number (one past the ends is clamped).
- `PAGE_ERROR` — a page could not be copied in, its form fields could not be flattened, or the page tree is nested too deeply.
- `DOCUMENT_CLOSED` — the document has been closed.
- `INVALID_STATE` — a certified document whose certification forbids it, unless `options.invalidateSignatures`; or a progressive document still downloading.

```ts
const other = new Uint8Array(await (await fetch('/terms.pdf')).arrayBuffer());
const added = await doc.pages.import(other); // appended at the end
```

Page: https://kernstra.com/docs/web-sdk/api/doc-pages/import

Web page: https://kernstra.com/docs/web-sdk/api/doc-pages
