|
| 1 | +--- |
| 2 | +title: TypeScript SDK |
| 3 | +sidebarTitle: TypeScript |
| 4 | +description: Generate, certify, redact, and merge PDFs from TypeScript with the hosted API. Zero-dependency client that works in Node.js, Deno, Bun, and edge runtimes. |
| 5 | +--- |
| 6 | + |
| 7 | +## Installation |
| 8 | + |
| 9 | +```bash |
| 10 | +npm install @formepdf/sdk |
| 11 | +``` |
| 12 | + |
| 13 | +## Usage |
| 14 | + |
| 15 | +Create templates in the [dashboard](https://app.formepdf.com), then render them with data: |
| 16 | + |
| 17 | +```typescript |
| 18 | +import { Forme } from "@formepdf/sdk"; |
| 19 | + |
| 20 | +const forme = new Forme("forme_sk_..."); |
| 21 | + |
| 22 | +const pdf = await forme.render("invoice", { |
| 23 | + customer: "Acme Corp", |
| 24 | + items: [{ name: "Widget", qty: 5, price: 49 }], |
| 25 | + total: 245, |
| 26 | +}); |
| 27 | + |
| 28 | +await fs.writeFile("invoice.pdf", pdf); |
| 29 | +``` |
| 30 | + |
| 31 | +### Client options |
| 32 | + |
| 33 | +```typescript |
| 34 | +const forme = new Forme("forme_sk_...", { |
| 35 | + baseUrl: "https://custom-api.example.com", // optional |
| 36 | +}); |
| 37 | +``` |
| 38 | + |
| 39 | +### Methods |
| 40 | + |
| 41 | +| Method | Description | Returns | |
| 42 | +|--------|-------------|---------| |
| 43 | +| `render(slug, data, options?)` | Synchronous render | `Promise<Uint8Array \| { url: string }>` | |
| 44 | +| `renderAsync(slug, data, options?)` | Start async render job | `Promise<{ jobId, status }>` | |
| 45 | +| `getJob(jobId)` | Poll async job status | `Promise<JobResult>` | |
| 46 | +| `merge(pdfs)` | Merge multiple PDFs | `Promise<Uint8Array>` | |
| 47 | +| `certify(pdf, options)` | Certify a PDF with X.509 certificate | `Promise<Uint8Array>` | |
| 48 | +| `redact(pdf, options)` | Redact content from a PDF | `Promise<Uint8Array>` | |
| 49 | +| `extract(pdf)` | Extract embedded data | `Promise<unknown \| null>` | |
| 50 | + |
| 51 | +--- |
| 52 | + |
| 53 | +## Render to S3 |
| 54 | + |
| 55 | +```typescript |
| 56 | +const result = await forme.render("invoice", data, { |
| 57 | + s3: { |
| 58 | + bucket: "my-bucket", |
| 59 | + key: "invoices/001.pdf", |
| 60 | + accessKeyId: "AKIA...", |
| 61 | + secretAccessKey: "...", |
| 62 | + region: "us-east-1", |
| 63 | + }, |
| 64 | +}); |
| 65 | +// result = { url: "https://my-bucket.s3.amazonaws.com/invoices/001.pdf" } |
| 66 | +``` |
| 67 | + |
| 68 | +## Async rendering |
| 69 | + |
| 70 | +```typescript |
| 71 | +const { jobId } = await forme.renderAsync("invoice", data, { |
| 72 | + webhookUrl: "https://example.com/webhook", |
| 73 | +}); |
| 74 | + |
| 75 | +// Poll for completion |
| 76 | +const job = await forme.getJob(jobId); |
| 77 | +if (job.status === "completed") { |
| 78 | + const pdf = Buffer.from(job.pdfBase64!, "base64"); |
| 79 | +} |
| 80 | +``` |
| 81 | + |
| 82 | +## Certify |
| 83 | + |
| 84 | +```typescript |
| 85 | +import { readFileSync } from "fs"; |
| 86 | + |
| 87 | +const certified = await forme.certify(pdfBytes, { |
| 88 | + certificate: readFileSync("cert.pem", "utf-8"), |
| 89 | + privateKey: readFileSync("key.pem", "utf-8"), |
| 90 | + reason: "Approved", |
| 91 | +}); |
| 92 | +``` |
| 93 | + |
| 94 | +Or use a saved certificate on the hosted API: |
| 95 | + |
| 96 | +```typescript |
| 97 | +const certified = await forme.certify(pdfBytes, { |
| 98 | + certificateId: "cert_abc123", |
| 99 | +}); |
| 100 | +``` |
| 101 | + |
| 102 | +## Redact |
| 103 | + |
| 104 | +```typescript |
| 105 | +// By text pattern |
| 106 | +const redacted = await forme.redact(pdfBytes, { |
| 107 | + patterns: [ |
| 108 | + { pattern: "Jane Doe", pattern_type: "Literal" }, |
| 109 | + { pattern: "\\d{3}-\\d{2}-\\d{4}", pattern_type: "Regex" }, |
| 110 | + ], |
| 111 | +}); |
| 112 | + |
| 113 | +// By built-in presets |
| 114 | +const redacted = await forme.redact(pdfBytes, { |
| 115 | + presets: ["ssn", "email", "phone"], |
| 116 | +}); |
| 117 | + |
| 118 | +// By saved redaction template |
| 119 | +const redacted = await forme.redact(pdfBytes, { |
| 120 | + template: "hipaa-patient-record", |
| 121 | +}); |
| 122 | +``` |
| 123 | + |
| 124 | +## Merge |
| 125 | + |
| 126 | +```typescript |
| 127 | +const merged = await forme.merge([pdf1, pdf2, pdf3]); |
| 128 | +``` |
| 129 | + |
| 130 | +## Extract embedded data |
| 131 | + |
| 132 | +```typescript |
| 133 | +const data = await forme.extract(pdfBytes); |
| 134 | +if (data) { |
| 135 | + console.log(data); // the JSON that was embedded at render time |
| 136 | +} |
| 137 | +``` |
| 138 | + |
| 139 | +## Error handling |
| 140 | + |
| 141 | +```typescript |
| 142 | +import { Forme, FormeError } from "@formepdf/sdk"; |
| 143 | + |
| 144 | +try { |
| 145 | + const pdf = await forme.render("invoice", data); |
| 146 | +} catch (err) { |
| 147 | + if (err instanceof FormeError) { |
| 148 | + console.error(`Error ${err.status}: ${err.message}`); |
| 149 | + } |
| 150 | +} |
| 151 | +``` |
0 commit comments