PDF4me JavaScript SDK Começando
O pdf4me pacote em npm é o oficial TypeScript/JavaScript ESM cliente para o PDF4me REST APIEle fornece 106 ações distribuídas em 18 módulosConverter, otimizar, mesclar, dividir, aplicar carimbos e extrair conteúdo de documentos com funções assíncronas e resultados tipados. Os tipos são fornecidos dentro do pacote, portanto TypeScript projetos não precisam de separação @types instalar.
Informações sobre o pacote
| Campo | Valor |
|---|---|
| Nome do pacote | pdf4me |
| Versão atual | 10.0.1 (publicado em 14/09/2026) |
| Licença | MIT |
| Node.js apoiar | >=22, declarado em engines |
| Formato do módulo | ESM apenas ("type": "module") |
| Tipos | Agrupado (dist/index.d.ts) |
| Efeitos colaterais | Nenhum ("sideEffects": false) |
| Ações | 106 em 18 subcaminhos de importação |
| Dependências de tempo de execução | Cinco Microsoft Kiota pacotes (abstrações mais o JSON, serializadores de formulário, texto e multipart) |
| Fonte | github.com/pdf4me/pdf4me-clientapi-javascript |
| npm | npmjs.com/package/pdf4me |
Pré-requisitos
- Node.js 22 ou mais recente.
- A PDF4me conta e API chave.
- Um projeto que pode usar ESM
importsintaxe ("type": "module"em seupackage.json, ou.mjsarquivos).
Instalar
- npm
- pnpm
- Yarn
npm install pdf4me@^10
pnpm add pdf4me@^10
yarn add pdf4me@^10
O ^10 A amplitude importa. Um ^9 intervalo de dependência será não Baixe a versão 10 separadamente, pois ela é uma reescrita com alterações incompatíveis com versões anteriores. Veja Atualizando da versão 9.x abaixo.
:::aviso Node.js São necessários 22 anos, mas npm apenas avisa
engines declara node: ">=22"e por padrão npm Emite um aviso em vez de um erro em caso de incompatibilidade. Um projeto ainda em execução. Node.js A versão 18 instalará a versão 10 com sucesso, mas falhará em tempo de execução. Verifique. node --versionantes de enviar.
:::
Para trabalhar a partir de um checkout de origem em vez do registro, execute o seguinte comando: npm install e npm run build dentro do diretório do pacote, execute npm install /absolute/path/to/pdf4me a partir do diretório do seu aplicativo.
Autenticar
Defina seu API chave no ambiente:
- Bash / Zsh
- PowerShell
- Windows CMD
export PDF4ME_API_KEY="your-api-key"
$env:PDF4ME_API_KEY = "your-api-key"
set PDF4ME_API_KEY=your-api-key
O cliente envia a chave como um Authorization: Basic <apiKey> O cabeçalho é adicionado a cada requisição. A biblioteca não registra credenciais nem o conteúdo do documento. Criar um cliente com uma chave em branco gera um erro. TypeError imediatamente, antes de qualquer chamada de rede.
Início rápido
Salvar isso como optimize-pdf.mjs e coloque um input.pdf no mesmo diretório de trabalho. O exemplo carrega o PDF para otimização e salva o resultado como optimized.pdf.
import { readFile, writeFile } from "node:fs/promises";
import { Pdf4meClient } from "pdf4me";
import { optimize } from "pdf4me/optimize";
const apiKey = process.env.PDF4ME_API_KEY;
if (!apiKey) {
throw new Error("Set PDF4ME_API_KEY before running this example.");
}
const client = new Pdf4meClient(apiKey);
const data = await readFile("input.pdf");
const result = await optimize(client, data, { docName: "input.pdf" });
await writeFile("optimized.pdf", result);
console.log("Saved optimized.pdf");
Execute com:
node optimize-pdf.mjs
As mesmas importações funcionam em TypeScript ESM projetos, com tipos incluídos no pacote.
Três coisas a observar:
- Um cliente, muitas ações.
new Pdf4meClient(apiKey)Contém a configuração.fetchpossui o pool de conexões, portanto não háclose()Método para chamar e nada para liberar quando terminar. - As ações são funções independentes, não métodos do cliente. Cada um é importado de seu próprio subcaminho (
pdf4me/optimize,pdf4me/merge-split,pdf4me/edit) e chamado comoaction(client, source, options). - A ordem dos argumentos é fixa. Primeiro o cliente reutilizável, em seguida o conteúdo de origem quando a ação exigir um, e por último um objeto de opções.
O que o diretório raiz do pacote exporta
O subcaminho raiz (pdf4me) carrega o cliente e seus tipos de suporte. As ações nunca residem aqui.
| Exportar | Tipo | Propósito |
|---|---|---|
Pdf4meClient | aula | Contém o API Configurações de teclas e transporte; passadas como primeiro argumento para cada ação. |
Pdf4meException | aula | Lançada quando o serviço retorna uma falha. |
Pdf4meTimeoutError | aula | Lançado quando o limite de tempo de uma solicitação ou tarefa é atingido. |
Pdf4meClientOptions | tipo | O objeto de opções aceito pelo construtor do cliente |
DocumentSource | tipo | Uint8Array | string — o formato aceito do conteúdo de origem |
DEFAULT_BASE_URL | constante | https://api.pdf4me.com |
DEFAULT_TIMEOUT | constante | 100000 |
DEFAULT_MAX_WAIT | constante | 300000 |
DEFAULT_POLL_INTERVAL | constante | 10000 |
Solicitações e resultados
Cada ação é submetida. isAsync: true e aguarda o resultado final. Um imediato HTTP 200 retornos imediatamente. Um HTTP 202 retorna um ID de trabalho, que o cliente então consulta em GetActionStatus até que o trabalho termine. Seu código vê um await de qualquer jeito.
O que você passa em
DocumentSource é Uint8Array | string, que abrange quatro formas práticas:
| Formulário de origem | Notas |
|---|---|
Uint8Array | Inclui Node.js Buffer, que subclasses Uint8ArrayOs bytes são codificados em base64 para você, em blocos delimitados, para que documentos grandes não sobrecarreguem a pilha. |
| string base64 | Passou direto. |
pdf4meblobid://... | Uma referência a conteúdo já detido por PDF4me. |
| URL | O serviço busca o documento automaticamente. |
Conteúdo vazio é rejeitado localmente com um TypeError em vez de ser enviado.
Ações com múltiplas entradas aceitam matrizes ordenadas. addAttachmentToPdf é a exceção: leva um attachments Mapeamento de objetos que associam nomes de arquivos ao conteúdo.
O que você recebe de volta
| Tipo de resultado | Tipo | Exemplo |
|---|---|---|
| Ações de arquivo | Uint8Array | Aceito diretamente por Node.js writeFile |
| JSON ações | Modelos tipificados | DocMetadata, SplitPdfRes |
Os modelos e as constantes de enumeração são exportados tanto do próprio módulo da ação quanto do pdf4me/models subcaminho. Os campos de resposta desconhecidos são mantidos em additionalData, então um mais novo API O campo nunca é abandonado silenciosamente.
Mais duas ligações
import { merge } from "pdf4me/merge-split";
import { stamp, StampAlignX } from "pdf4me/edit";
const merged = await merge(client, [firstPdf, secondPdf]);
const stamped = await stamp(client, merged, {
text: "DRAFT",
alignX: StampAlignX.Center,
});
StampAlignX.Center é uma constante tipada, portanto seu editor completa automaticamente os valores válidos e tsc Detecta erros de digitação antes mesmo do envio da solicitação.
Opções e valores padrão
Todas as interfaces de opções são exportadas, por exemplo. OptimizeOptionsVale a pena conhecer dois comportamentos:
- Os valores padrão são aplicados quando uma opção é ausenteO perfil de otimização padrão é
MaxUm explícitonullfaz não Selecione um valor padrão. - Toda ação aceita
extra, um objeto serializado como campos de solicitação adicionais. Use o APIuse os próprios nomes de campo e evite chaves que as opções de ação já fornecem.
Configuração do cliente
const client = new Pdf4meClient(apiKey, {
baseUrl: "https://api.pdf4me.com",
timeout: 100_000,
maxWait: 300_000,
pollInterval: 10_000,
});
O Python O cliente usa segundos para as mesmas configurações. Se você estiver portando código entre os dois. SDKs, redimensione a cada duração.
| Opção | Padrão | O que isso significa |
|---|---|---|
baseUrl | https://api.pdf4me.com | O API host para onde cada solicitação é enviada |
timeout | 100000 EM | Cada solicitação individual, incluindo a leitura do seu conteúdo. |
maxWait | 300000 EM | Consultas após o envio inicial da tarefa, incluindo solicitações de status em andamento. |
pollInterval | 10000 EM | A lacuna de fallback entre as verificações de status |
fetch | globalThis.fetch | Um transporte personalizado, útil para testes ou configuração de proxy. |
Cada valor padrão também é exportado como uma constante (DEFAULT_TIMEOUT e amigos), para que você possa dimensionar a partir do valor enviado em vez de codificar um número fixo.
O construtor valida o que você passa:
baseUrldeve ser umhttp:ouhttps:URL Sem credenciais, string de consulta ou fragmento. Qualquer outra coisa gera um erro.TypeError.timeout,maxWait, epollIntervalcada um deve ser um número finito positivo de milissegundos não maior que2147483647Qualquer outra coisa gera um problema.RangeError.
Numérico e HTTP-data Retry-After Os valores do serviço controlam a frequência de sondagem; pollInterval é usado apenas quando o serviço não envia um. Se a próxima pesquisa fosse ocorrer após o maxWait Com o prazo apertado, o cliente desiste imediatamente em vez de esperar o orçamento restante acabar.
:::cuidado Redirecionamentos são rejeitados
O cliente define redirect: "error"Se você rotear o tráfego por meio de um proxy que responde com um código 3xx, aponte baseUrlno destino final, em vez de depender do redirecionamento ser seguido.
:::
Erros
| Arremessado | Quando |
|---|---|
Pdf4meException | O serviço retornou uma falha. Suporta message, responseStatusCode, traceId, e responseHeaders. |
Pdf4meTimeoutError | Um limite de tempo de solicitação (timeout) ou um limite de tempo de trabalho (maxWait) foi alcançado. |
TypeError | Entrada local inválida: um espaço em branco API chave, uma má baseUrlou conteúdo de documento vazio. |
RangeError | Uma opção de duração fora do intervalo aceito. |
Ordinário Error | Um 202 cujo corpo não carregava nada utilizável jobIdou um JSON ação que retornou um resultado vazio. |
| Erros de rede | Propagado de fetch Inalterado. |
Pdf4meException.message é retirado do próprio serviço message campo quando presente, recorrendo ao HTTP texto de status. Cite o traceId Ao entrar em contato com o suporte, o sistema identifica o problema exato a ser resolvido pelo serviço.
import { Pdf4meException, Pdf4meTimeoutError } from "pdf4me";
import { optimize } from "pdf4me/optimize";
try {
const result = await optimize(client, data, { docName: "input.pdf" });
} catch (error) {
if (error instanceof Pdf4meTimeoutError) {
// The job exceeded maxWait. Retry, or raise maxWait for large documents.
} else if (error instanceof Pdf4meException) {
console.error(error.responseStatusCode, error.traceId);
} else {
throw error;
}
}
Os 18 módulos
Cada módulo possui seu próprio subcaminho de importação, portanto, os bundlers e editores carregam apenas o que você utiliza. O pacote define os conjuntos. "sideEffects": false, que permite que os bundlers descartem completamente os módulos não utilizados.
Algumas ações estão em um módulo cujo nome você talvez não imagine — OCR está em find-search, PDF/A a criação está em convert, e pdf4me Contém uma única ação de hiperlink. A tabela abaixo lista todas as ações exportadas para que você não precise adivinhar.
| Importar subcaminho | Ações | Funções exportadas |
|---|---|---|
pdf4me/ai-document-extraction | 14 | aiDocumentParser, processBankCheque, processBankStatement, processContract, processCreditCard, processHealthCard, processInvoice, processMarriageCertificate, processMortgageDocument, processOrder, processPayStub, processReceipt, processShippingLabel, processTaxDocument |
pdf4me/barcode | 7 | addBarcode, createBarcode, createSwissQrBill, readBarcodes, readSwissQrBill, createEpcQrCode, readBarcodesFromImage |
pdf4me/convert | 13 | convertHtmlToPdf, convertJsonToExcel, convertMdToPdf, convertPdfToExcel, convertPdfToPowerpoint, convertPdfToWord, convertToPdf, convertUrlToPdf, convertVisio, convertWordToPdfForm, createPdfA, flattenPdf, linearizePdf |
pdf4me/edit | 7 | addAttachmentToPdf, addHtmlHeaderFooter, imageStamp, addMargin, addPageNumber, stamp, signPdf |
pdf4me/excel | 1 | findAndReplaceTextInExcel |
pdf4me/extract | 8 | classifyDocument, extractAttachmentFromPdf, extractPdfFormData, extractResources, extractTableFromPdf, extractTextByExpression, extractTextFromWord, parseDocument |
pdf4me/find-search | 2 | findAndReplace, convertOcrPdf |
pdf4me/forms | 2 | addFormField, fillPdfForm |
pdf4me/generate | 6 | enableTrackingChangesInWord, generateDocumentSingle, generateDocumentMultiple, getTrackingChangesInWord, replaceTextWithImageInWord, generateDocumentSingleV2 |
pdf4me/image | 13 | addImageWatermarkToImage, addTextWatermarkToImage, compressImage, convertImageFormat, createImages, cropImage, flipImage, getImageMetadata, imageExtractText, removeExifTagsFromImage, resizeImage, rotateImage, rotateImageByExifData |
pdf4me/merge-split | 5 | merge, mergeOverlay, splitPdf, splitPdfByBarcode, splitByText |
pdf4me/optimize | 1 | optimize |
pdf4me/organize | 5 | deleteBlankPages, deletePages, extractPages, rotate, rotatePage |
pdf4me/pdf | 16 | getPdfMetadata, repairPdf, createHyperlinkAnnotation, deleteHyperlinkAnnotation, digitalSignPdf, extractHyperlinkAnnotation, getDocumentByText, getTextAndCoordinates, getTextByPosition, highlightText, mergeV3, prepareForPrint, replaceTextWithImage, resizePdf, setPdfMetadata, signDocument |
pdf4me/pdf4me | 1 | updateHyperlinkAnnotation |
pdf4me/security | 2 | protect, unlock |
pdf4me/word | 2 | disableTrackingChangesInWord, findAndReplaceTextInWord |
pdf4me/zugferd | 1 | createZugferdInvoice |
Outros dois subdiretórios ficam ao lado dos módulos de ação: a raiz do pacote (pdf4me), abordado acima, e pdf4me/models, que reexporta cada modelo e constante de enumeração.
Para obter informações sobre os parâmetros e o formato da resposta de cada ação, consulte o PDF4me REST API referência ou as declarações de tipo geradas em node_modules/pdf4me/dist/.
Atualizando da versão 9.x
A versão 10 é uma reescrita. Para permanecer na linha 9.x, fixe pdf4me@^9.10.15.
Duas alterações interrompem todas as chamadas.
Você os encontrará imediatamente, pois nada compila ou funciona até que sejam corrigidos.
1. ESM apenas. require("pdf4me") não resolve mais. Use import.
2. Um cliente mais ações independentes. pdf4me.createClient(key), que retornava um único objeto de métodos, é substituído por new Pdf4meClient(key) além de funções de ação importadas de subcaminhos e chamadas como action(client, source, options).
// 9.x
const pdf4me = require("pdf4me");
const client = pdf4me.createClient(key);
const result = await client.optimize(/* ... */);
// 10
import { Pdf4meClient } from "pdf4me";
import { optimize } from "pdf4me/optimize";
const client = new Pdf4meClient(key);
const result = await optimize(client, data, { docName: "input.pdf" });
Três alterações compilam e executam, mas apresentam comportamento inesperado.
Essas são as que devem ser verificadas manualmente, porque nada indicará que estão erradas.
1. Resultados binários são Uint8Array, não Buffer. Buffer subclasses Uint8Array, então writeFile E os amigos ainda trabalham. Mas Buffer-apenas métodos produzem absurdos silenciosamente em vez de lançar:
result.toString("base64"); // 9.x: base64. 10: "0,255,65,128"
Buffer.from(result).toString("base64"); // do this instead
2. Todas as ações geram pesquisas de opinião. A versão 10 envia isAsync: true e realiza pesquisas até que o trabalho seja concluído, portanto, uma chamada que antes era de uma única ida e volta agora pode bloquear por até maxWait (padrão 300000 ms) e pode lançar Pdf4meTimeoutError — um modo de falha que a versão 9.x não possuía.
3. Os redirecionamentos são rejeitados. A versão 9.x seguiu-os; a versão 10 define redirect: "error"Se você rotear o tráfego por meio de um proxy que responde com códigos 3xx, aponte para o endereço IP correto. baseUrl no destino final.
Também vale a pena saber
- Node.js 22 agora é obrigatório e declarado em
engines, mas npm Por padrão, apenas emite um aviso em caso de incompatibilidade. - Criação de miniaturas (
createThumbnail/createThumbnails) e PDF/A validação (validate/validateDocument) ter Não existe versão equivalente à 10., porque a v2 API não os expõe. - A licença mudou de ISC para MIT.
O mapeamento completo, método por método, incluindo renomeações e o integrationConfig Substituição, enviada junto com o pacote. Leia mais em node_modules/pdf4me/MIGRATION.md após a instalação.
Solução de problemas
Error [ERR_REQUIRE_ESM] ou require() of ES Module ... not supported. A versão 10 é ESM somente. Adicionar "type": "module" para o seu package.json, renomeie o arquivo de entrada para .mjsou alfinete pdf4me@^9.10.15 se o projeto não puder avançar CommonJS ainda.
ERR_MODULE_NOT_FOUND para pdf4me/optimize. As importações de subcaminhos são resolvidas por meio do pacote. exports mapa, que requer um mapa razoavelmente atualizado Node.js e o agrupador. Confirme. node --version relatórios 22 ou mais recentes, e que você está importando o subcaminho exatamente como está escrito na tabela de módulos (por exemplo pdf4me/merge-split(com hífen).
A saída em Base64 tem a seguinte aparência: "0,255,65,128". Você ligou .toString("base64") em um Uint8ArrayPrimeiro, embrulhe: Buffer.from(result).toString("base64").
Pdf4meTimeoutError em documentos grandes. O trabalho superou as expectativas. maxWait, que por padrão é 300000 ms. Gere-o no cliente, por exemplo. new Pdf4meClient(apiKey, { maxWait: 900_000 })e confirme timeout ainda é grande o suficiente para ler o corpo da resposta. Observe que ambos os valores são limitados a 2147483647 EM.
Um 401 em Pdf4meException.responseStatusCode. O API A chave está presente, mas foi rejeitada. Gere-a novamente em PDF4me painel e confirme se a variável de ambiente está realmente visível para o processo — set no Windows CMD não persiste entre sessões, então use setx por um valor permanente.
TypeError: an API key is required. O construtor recebeu uma string vazia ou composta apenas por espaços em branco, geralmente porque process.env.PDF4ME_API_KEY estava indefinido. Verifique a variável antes de construir o cliente, como faz o guia de início rápido.
TypeError: document content is empty. O Uint8Array ou a string que você passou tem comprimento zero. Esta é uma verificação local, portanto nenhuma solicitação foi enviada — verifique se o arquivo foi lido com sucesso.
As solicitações falham devido à presença de um proxy corporativo. O cliente define redirect: "error" e não seguirá o 3xx de um proxy. Ponto baseUrl no destino final, ou forneça um personalizado fetch que cuida do seu transporte.
createThumbnail ou validate Não é exportado. Ambos foram removidos na versão 10, porque a v2 API Não os expõe. Não há substituto direto; permaneça na versão 9.x se você depende deles.