@anvilco/anvil

中文文档
4.2.0发布于 2026/11/03MITTypeScriptESM + CJS构建来源已验证近 30 天下载 27万

Anvil API 客户端

中文使用文档
文档目录12 节
  1. 使用量
  2. 类型脚本
  3. API 密码
  4. 实例方法
  5. 分类方法
  6. 选项
  7. 常数
  8. 错误
  9. 费率限制
  10. API 文档
  11. 实例
  12. 发展

Horizontal Lockupblack Horizontal Lockup copywhite

节点的 Anvil API 客户端

此库将允许您与 安维尔API 在JavaScript / 节点JS.

安维尔 为所有文件提供方便的API.

  1. PDF 填补 API - 填写一个PDF模板,其中包含网络请求和结构化的JSON数据.
  2. PDF 生成 API - 发送标记下来或HTML和Anvil会把它变成PDF.
  3. Etch 电子签名与 API - 可自定义的、可嵌入的、带有API的电子签名平台,以控制签名过程的端到端.
  4. 工作流量(w/ API) - Webforms + PDF + 有强大的无码构建器的电子符号. 轻松地收集结构化数据,生成PDF,并请求签名.

学着点 Anvil 开发者页面见 API 指南 编辑 参考图表QL 用于完整文档.

使用量

这个库和Anvil API是打算用于服务器或类似服务器的环境. 它会在浏览器环境中失败.

要求节点20或更后.

yarn add @anvilco/anvil

它作为普通JS模块或ES模块工作,在JavaScript或TypeScript中:

const Anvil = require('@anvilco/anvil')
// or
import Anvil from '@anvilco/anvil'

类型脚本

客户类型来自 @anvilco/types,它来自Anvil API的GraphQL schema和OpenAPI spec并安装在客户端中。 这个 variables 图QL方法及其有效载荷 fillPDF 财务报告和审定财务报表 generatePDF 从它们中键入,所以一个拼写错误或缺少的参数是一个编译错误。 对于您自己的询问以及API返回的种类,请使用它 GraphQL 名称空间 :

import type { GraphQL } from '@anvilco/types'

type Packet = GraphQL.Type<'EtchPacket'>
type PacketArgs = GraphQL.MutationArgs<'createEtchPacket'>

论点 createEtchPacket graphQL 计划只能调用 JSON 键入,并按名称导出以单独构建它们:

import type { EtchSigner } from '@anvilco/anvil'

const signer: EtchSigner = {
  id: 'signer1',
  name: 'Sally Signer',
  email: '[email protected]',
  signerType: 'embedded',
  fields: [{ fileId: 'lease', fieldId: 'signature1' }],
}

如果你通过自己的 mutation 至方法,其变量可能不同于API对该变异的参数;如果 TypeScript 对象,则将其投放.

npm install @anvilco/anvil

一个将 JSON 转换为已填充的 PDF 的基本实例, 然后将 PDF 保存为文件 :

import fs from 'fs'
import Anvil from '@anvilco/anvil'

// The ID of the PDF template to fill
const pdfTemplateID = 'kA6Da9CuGqUtc6QiBDRR'
// Your API key from your Anvil organization settings
const apiKey = '7j2JuUWmN4fGjBxsCltWaybHOEy3UEtt'

// JSON data to fill the PDF
const exampleData = {
  "title": "My PDF Title",
  "fontSize": 10,
  "textColor": "#CC0000",
  "data": {
    "someFieldId": "Hello World!"
  }
}
const anvilClient = new Anvil({ apiKey })
const { statusCode, data } = await anvilClient.fillPDF(pdfTemplateID, exampleData)

// By default, if the PDF has been published then the published version is what will
// be filled. If the PDF has not been published, then the most recent version will
// be filled. 
// 
// However, a version number can also be passed in that will be used retrieve and
// fill a specific version of the PDF.
// You can also use the constant `Anvil.VERSION_LATEST` (or `-1`) to fill the most 
// recent version of your PDF, whether that version has been published or not.
// Use this if you'd like to fill out a draft version of your template/PDF.
const options = { versionNumber: Anvil.VERSION_LATEST }
const { statusCode, data } = await anvilClient.fillPDF(pdfTemplateID, exampleData, options)

console.log(statusCode) // => 200

// Data will be the filled PDF raw bytes
fs.writeFileSync('output.pdf', data, { encoding: null })

API 密码

方法名称

每一种名称有缩写的方法,也都可以用平地骆驼案的缩写来称呼,反之亦然. 使用您喜欢的任意一种方法;它们都是相同的方法.

fillPDFfillPdf
generatePDFgeneratePdf
generateEtchSignUrlgenerateEtchSignURL
requestGraphQLrequestGraphql 或者说 requestGraphQl
requestRESTrequestRest
prepareGraphQLFileprepareGraphqlFile 或者说 prepareGraphQlFile

这个 baseURL 选项也被接受为 baseUrl。 。 。 .

实例方法

新安维尔( 选项)

创建 Anvil 客户端实例 .

  • options (目标) - 选项 以Anvil客户为例.
const anvilClient = new Anvil({ apiKey: 'abc123' })

fillPDF(pdf TemplateID, 有效载荷[, 选项])

以 JSON 数据填入 PDF 模板.

首先,你需要拥有 上传到 Anvil 的 PDF您可以在 PDF 模板的页面上找到 PDF 模板的ID :

PDF Template ID

如果您已经拥有安维尔页面的URL, ID也在那里 : https://app.useanvil.com/org/<your-org-slug>/pdf/<pdf-template-id>

一个例子是:

const fs = require('fs')

// PDF template you uploaded to Anvil
const pdfTemplateID = 'kA6Da9CuGqUtc6QiBDRR'

// Your API key from your Anvil organization settings
const apiKey = '7j2JuUWmN4fGjBxsCltWaybHOEy3UEtt'

// JSON data to fill the PDF
const payload = {
  "title": "My PDF Title",
  "fontSize": 10,
  "textColor": "#CC0000",
  "data": {
    "someFieldId": "Hello World!"
  }
}
// The 'options' parameter is optional
const options = {
  "dataType": "buffer"
}
const anvilClient = new Anvil({ apiKey })
const { statusCode, data } = await anvilClient.fillPDF(pdfTemplateID, payload, options)

// Be sure to write the file as raw bytes
fs.writeFileSync('filled.pdf', data, { encoding: null })
  • pdfTemplateID (String) - 来自Anvil UI的您 PDF 模板的ID
  • payload (Object) - 将填充PDF模板的JSON数据
    • title (叫声) - 选项 设定编码为 PDF 文档的标题
    • fontSize (数目) - 选项 设置所有已填入文本的字体大小 。 默认为10.
    • color (叫声) - 选项 设置所有已填入文本的文本颜色 。 默认为深蓝色.
    • data (Object) - 填充PDF的数据. 此对象中的密钥将对应 PDF 中的字段ID 。 这些字段ID及其类型可以在Anvil仪表板上的PDF模板页面上找到.
      • 举个例子 { "someFieldId": "Hello World!" }
  • options (目标) - 选项 请求的任何其他备选方案
    • dataType (Enum[标]- 选项 设置类型 data 已解决时返回的值 Promise默认为 'buffer'不过 'arrayBuffer' 财务报告和审定财务报表 'stream' 也得到支持.
    • versionNumber (数目) - 选项 要填充的PDF模板版本. 默认为最近发布的版本,或者模板从未发布的最新版本. 见 常数。 。 。 .
    • throwOnError (布鲁伦) - 选项 覆盖客户端 throwOnError 为此请求.
  • 回返a Promise 决心 Object
    • statusCode (数目) - HTTP状态代码; 200 是成功的
    • data (Buffer QQ ArrayBuffer QQ Stream) - 已填充的PDF的原始二进制数据如果成功的话. 要么是一个缓冲器, 缓冲器, 要么是一个流,取决于 dataType 选项.
    • errors (天体阵列) - 如果状态为 QQ 400, 将会存在 。 参见错误
      • message (叫声)
生成PDF( 负载[, 选项])

从您的 HTML 和 CSS 或标记下动态生成一个新的 PDF .

可用于协议、发票、披露或任何其他文本重的文件。 这不需要您在Anvil UI中做任何事情,除了设置您的 API 密钥, 只要发送数据, 得到一个 PDF 。 见 生成 PDF 文档 详细情况.

看看我们 HTML 发票模板 用于完整 HTML 到 PDF 示例.

一个例子是:

const fs = require('fs')

// Your API key from your Anvil organization settings
const apiKey = '7j2JuUWmN4fGjBxsCltWaybHOEy3UEtt'

// An example using an HTML to PDF payload
const payload = {
  title: 'Example',
  type: 'html',
  data: {
    html: `
      <h1 class='header-one'>What is Lorem Ipsum?</h1>
      <p>
        Lorem Ipsum is simply dummy text...
      </p>
      <h3 class='header-two'>Where does it come from?</h3>
      <p>
        Contrary to popular belief, Lorem Ipsum is not simply <i>random text</i>
      </p>
    `,
    css: `
      body { font-size: 14px; color: #171717; }
      .header-one { text-decoration: underline; }
      .header-two { font-style: underline; }
    `,
  },
}

// An example using a Markdown payload
const payload = {
  title: 'Example Invoice',
  data: [{
    label: 'Name',
    content: 'Sally Jones',
  }, {
    content: 'Lorem **ipsum** dolor sit _amet_',
  }, {
    table: {
      firstRowHeaders: true,
      rows: [
        ['Description', 'Quantity', 'Price'],
        ['4x Large Widgets', '4', '$40.00'],
        ['10x Medium Sized Widgets in dark blue', '10', '$100.00'],
        ['10x Small Widgets in white', '6', '$60.00'],
      ],
    },
  }],
}
// The 'options' parameter is optional
const options = {
  "dataType": "buffer"
}
const anvilClient = new Anvil({ apiKey })
const { statusCode, data } = await anvilClient.generatePDF(payload, options)

// Be sure to write the file as raw bytes
fs.writeFileSync('generated.pdf', data, { encoding: null })
  • payload (Object) - 将填充PDF模板的JSON数据
    • title (叫声) - 选项 设定编码为 PDF 文档的标题
    • data (Array of Objects) - 生成PDF的数据. 见 文档 用于所有被支持的对象
      • 举个例子 [{ "label": "Hello World!", "content": "Test" }]
  • options (目标) - 选项 请求的任何其他备选方案
    • dataType (Enum[标]- 选项 设置类型 data 已解决时返回的值 Promise默认为 'buffer'不过 'arrayBuffer' 财务报告和审定财务报表 'stream' 也得到支持.
    • throwOnError (布鲁伦) - 选项 覆盖客户端 throwOnError 为此请求.
  • 回返a Promise 决心 Object
    • statusCode (数目) - HTTP状态代码; 200 是成功的
    • data (Buffer QQ ArrayBuffer QQ Stream) - 已填充的PDF的原始二进制数据如果成功的话. 要么是一个缓冲器, 缓冲器, 要么是一个流,取决于 dataType 选项.
    • errors (天体阵列) - 如果状态为 QQ 400, 将会存在 。 参见错误
      • message (叫声)
创建 EtchPacket( 选项)

创建 Etch 包并选择将其发送给第一个签名者.

const anvilClient = new Anvil({ apiKey })

const { statusCode, data, errors } = await anvilClient.createEtchPacket({
  variables: {
    name: 'Example packet',
    // Test packets use development signatures and are not billed
    isTest: true,
    // Send it to the first signer right away
    isDraft: false,
    files: [{
      id: 'uploadedNDA',
      title: 'Demo NDA',
      file: Anvil.prepareGraphQLFile('./nda.pdf'),
      fields: [{
        id: 'signatureOne',
        type: 'signature',
        pageNum: 0,
        rect: { x: 100, y: 100, width: 150, height: 30 },
      }],
    }],
    signers: [{
      id: 'signerOne',
      name: 'Sally Signer',
      email: '[email protected]',
      // 'embedded' signers sign in your app with a URL from generateEtchSignUrl.
      // The default, 'email', sends them an email.
      signerType: 'embedded',
      fields: [{ fileId: 'uploadedNDA', fieldId: 'signatureOne' }],
    }],
  },
})

const etchPacket = data.data.createEtchPacket
const signerEid = etchPacket.documentGroup.signers[0].eid
  • options (object) - 有下列结构的物体:
    • variables (目标) API 文档 区域。 见 实例 区域.
    • responseQuery (叫声) - 选项 一个 GraphQL 符合要求的查询, 用于突变响应中想要的数据 。 可忽略使用默认值 .
    • mutation (叫声) - 选项 如果您想要完全控制 GraphQL 突变, 您可以通过一个 GraphQL 突变符合字符串, 用于突变调用 。 此字符串还应包括您的响应查询, 如 responseQuery 如果 mutation 通过。 示例
        mutation CreateEtchPacket (
          $name: String,
          ...
        ) {
          createEtchPacket (
            name: $name,
            ...
          ) {
            id
            eid
            ...
          }
        }
      
获取 EtchPacket( 选项)

得到一个小包的细节.

const { statusCode, data, errors } = await anvilClient.getEtchPacket({
  variables: { eid: etchPacketEid },
})
const { status, documentGroup } = data.data.etchPacket
  • options (object) - 有下列结构的物体:
    • variables (目标) - 要求 eid
      • eid (String) - 您的 Etch 包装 eid
    • responseQuery (叫声) - 选项 一个 GraphQL 查询符合要求的查询,用于查询答复中想要的数据 。 可忽略使用默认值 .
生成 Etch SignUrl( 选项)

为 Etch Packet 签名程序创建 Etch 标志 URL 。 Etch Packet 及其签名人必须已经创建,数据包必须已经发送,签名人必须是 embedded 签名者.

const { statusCode, url, errors } = await anvilClient.generateEtchSignUrl({
  variables: {
    signerEid,
    // Your ID for the user who will be signing
    clientUserId: 'user-123',
  },
})
// Send your user to `url` to sign
  • options (object) - 有下列结构的物体:
    • variables (目标) - 要求 clientUserId 财务报告和审定财务报表 signerEid
      • clientUserId (String) - 您将签名的用户的ID
      • signerEid (String) - Etch Packet 签名器的eid,在反应中发现 createEtchPacket 实例方法
  • 回返a Promise 决心 Object
    • statusCode (数目) - HTTP状态代码; 200 是成功的
    • url (String) - 签名的 URL
    • errors (Array of Objects) - 如果有问题将会出现. 见 错误
下载文件( 文档GroupEid [, 选项])

返回 Zip 文件格式中文档GroupEid 指定的文档组的缓冲、矩阵缓冲或流.

const { statusCode, data, errors } = await anvilClient.downloadDocuments(documentGroupEid)
fs.writeFileSync('documents.zip', data, { encoding: null })

// Or stream it
const { data: stream } = await anvilClient.downloadDocuments(documentGroupEid, { dataType: 'stream' })
stream.pipe(fs.createWriteStream('documents.zip'))
  • documentGroupEid (字符串) - 要下载的文档组的 eid
  • options (目标) - 选项 请求的任何其他备选方案
    • dataType (Enum[标]- 选项 设置类型 data 已解决时返回的值 Promise默认为 'buffer'不过 'arrayBuffer' 财务报告和审定财务报表 'stream' 也得到支持.
    • throwOnError (布鲁伦) - 选项 覆盖客户端 throwOnError 为此请求.
  • 回返a Promise 决心 Object
    • statusCode (数量) - HTTP 状态代码, 200 是成功的
    • response (object) - 由客户端向Anvil app请求而产生的响应对象
    • data (Buffer QQ ArrayBuffer QQ Stream) - 如果成功,则下载文件的原始二进制数据. 将采用缓冲、缓冲或流等形式,取决于 dataType 选项.
    • errors (天体阵列) - 如果状态为 QQ 400, 将会存在 。 参见错误
      • message (叫声)
伪造提交( 选项)

在 Workflow 中创建或更新对 Webform 的提交,与填写和提交 Webform 的人相同。 Webform在API中被称作"福格斯".

const { statusCode, data, errors } = await anvilClient.forgeSubmit({
  variables: {
    // The webform's eid
    forgeEid: 'your-forge-eid',
    // Keys are the IDs of the webform's fields
    payload: {
      name: 'Sally Jones',
      email: '[email protected]',
    },
    isTest: true,
  },
})
const submission = data.data.forgeSubmit
const weldDataEid = submission.weldData.eid
  • options (object) - 有下列结构的物体:
    • variables (目标) - 要求 forgeEid 财务报告和审定财务报表 payload。通过 weldDataEid 财务报告和审定财务报表 submissionEid 更新现有呈件。 见 参考图表QL 用于所有变量.
    • responseQuery (叫声) - 选项 一个 GraphQL 符合要求的查询, 用于突变响应中想要的数据 。 可忽略使用默认值 .
    • mutation (叫声) - 选项 你自己的完整的GraphQL突变. responseQuery 如果通过,则忽略.
  • 回返a Promise 决心 Object 与 statusCode, (中文(简体) ), data 财务报告和审定财务报表 errors一样 请求GraphQL
删除WeldData( 选项)

删除工作流程呈件(a) WeldData还有里面的一切.

const { statusCode, data, errors } = await anvilClient.removeWeldData({
  variables: { eid: weldDataEid },
})
const removed = data.data.removeWeldData // true
  • options (object) - 有下列结构的物体:
    • variables (目标) - 要求 eid
      • eid (String) - 要删除的 WeldData 的 eid
    • mutation (叫声) - 选项 你自己的完整的GraphQL突变.
  • 回返a Promise 决心 Object 与 statusCode, (中文(简体) ), data 财务报告和审定财务报表 errors一样 请求GraphQL
请求GraphQL( queryInfo[, 选项])

对于查询和突变的倒置功能,在此客户端中没有专门的功能.

见 参考图表QL 关于所有可能查询的清单

const result = await client.requestGraphQL({
  query: `
    query WeldDataQuery ($eid: String!) {
      weldData (eid: $eid) {
        eid
        isComplete
        isTest
      }
    }
  `,
  variables: { eid: 'nxflNZqxDUbltLUbYWK' },
})
const { statusCode, data, errors } = result

if (errors) {
  // GraphQL errors (with a 200 statusCode) or HTTP errors. See Errors.
} else {
  const weldData = data.data.weldData
}
  • queryInfo (目标)
    • query (String) - GraphQL 查询或突变来运行. 见 参考图表QL 关于所有可能查询的清单
    • variables (Object) - 用于查询的图形QL变量。 要上传的文件可以在这里的任何地方;参见 准备 GraphQLFile。 。 。 .
  • options (目标) - 选项 请求的任何其他备选方案
    • throwOnError (布鲁伦) - 选项 覆盖客户端 throwOnError 为此请求.
  • 回返a Promise 决心 Object
    • statusCode (数字) - HTTP状态代码. 图QL 错误带回 200;只有当请求本身有问题时,例如,它有错误或未经授权,您才会看到其他代码.
    • data (对象) - 无出错时显示
      • data (对象) - 包含查询的实际结果
        • [queryName] (Object) - 使用查询或突变名称来引用您要求的数据!
    • errors (Array of Objects) - 当出现 GraphQL 或 HTTP 错误时显示 。 见 错误
requestREST( url, 获取选项[, 客户端选项])

REST端点的倒置函数,在此客户端中没有专门的函数.

见 参考图表QL 关于所有可能查询的清单

const result = await this.requestREST(
  `/api/v1/fill/${pdfTemplateID}.pdf`,
  {
    method: 'POST',
    body: JSON.stringify(payload),
    headers: {
      'Content-Type': 'application/json',
    },
  },
  {
    dataType: 'stream',
  },
)
  • url (String) - 从基站URL的URL. 譬如说. /api/v1/fill
  • fetchOptions (对象) - 转到 获取。客户端使用 未编辑是因为 fetch。 。 。 .
  • clientOptions (目标) - 选项 请求的任何其他备选方案
    • dataType (Enum[标]- 选项 设置类型 data 已解决时返回的值 Promise默认为 'buffer', (中文(简体) ), 'arrayBuffer', (中文(简体) ), 'stream',以及 'json' 也得到支持.
    • throwOnError (布鲁伦) - 选项 覆盖客户端 throwOnError 为此请求.
  • 回返a Promise 决心 Object
    • statusCode (数目) - HTTP状态代码; 200 是成功的
    • data (Buffer QQ ArrayBuffer QQ Stream) - 已填充的PDF的原始二进制数据如果成功的话. 要么是一个缓冲器, 缓冲器, 要么是一个流,取决于 dataType 选项.
    • errors (天体阵列) - 如果状态为 QQ 400, 将会存在 。 参见错误
      • message (叫声)

分类方法

准备 GraphQLFile( path OrStream like Thing [, 选项])

一个很好的助手来准备 文件 上传并使用 GraphQL API 。 默认情况下, 这将以多段上传方式上传您的文件 jaidenseric / GraphQL 多部分请求光谱。作为路径或流提供的文件会被流到API,而不是首先被读入内存。 如果一项请求必须重新审理(见 费率限制),作为路径、文件流或 Buffer 被再次发送; 任何其他流只能被读取一次, 所以重试失败时会出现错误 。 注:请见下文某些可能需要手动提供 filename。 。 。 .

  • pathOrSupportedInstance (String QQ File Blob QQ Stream QQ BUFER) - 可以是几种事物之一. 下面列出所支持的,按偏好顺序排列:
    1. A 类 File 举个例子.
    2. A 类 Blob 举个例子.
    3. A 类 string 这是要使用的文件的路径.
    4. A 类 ReadStream 或
      1. A 类 path 属性( 通常在从本地文件系统中装入流时会出现)
      2. A 类 filename b. 《公约》 options 参数.
    5. A 类 Buffer 实例 filename b. 《公约》 options 参数.
  • options (Object) - 在提供某些类型的值作为第一个参数时可能需要的选项. 譬如说, Blobs, (中文(简体) ), Buffer和某些类型的 ReadStreams 上传时不会知道文件名称或名称.
    • filename (String) - 覆盖上传文件的文件名 。 如果提供通用的 ReadStream 或缓冲, 您需要在此提供文件名
    • mimetype (String) - 可选的 mime 类型, 以指定可使用的文件 string 路径, Buffer 或者说 ReadStream 作为第一个参数提供.
  • 返回 a Object 被客户端强制使用,以对抗我们的GraphQL API Upload 需要类型.

选项

Anvil客户端的选项. 每个选项密钥后显示默认值 .

{
  // One of apiKey or accessToken is required. See Authentication.
  apiKey: <your_api_key>,
  accessToken: <oauth_access_token>,

  // Where to send requests. See baseURL. Also accepted as baseUrl.
  baseURL: 'https://app.useanvil.com',

  // Sent as the User-Agent header
  userAgent: 'Anvil API Client/<version>',

  // How many requests to allow per requestLimitMS until the first response from
  // the API tells the client your actual limits. See Rate Limits.
  requestLimit: 1,
  requestLimitMS: 1000,

  // An undici Dispatcher to send requests with, e.g. to use a proxy:
  // new ProxyAgent('http://proxy.example.com:8080'). Defaults to the client's own Agent.
  dispatcher: <undici_dispatcher>,

  // Reject with an AnvilRequestError when the API responds with an error, rather
  // than resolve with `errors`. See throwOnError.
  throwOnError: false,
}
认证

使用 API 密钥或 OAuth 访问令牌认证 .

API 密钥 : 在您的 Anvil 组织设置中查找您的 API 密钥 。 请求使用 HTTP 基本认证 : Basic base64(apiKey + ':')。 。 。 .

const anvilClient = new Anvil({ apiKey: 'your-api-key' })

OAuth 访问令牌 : 请求使用 Bearer 认证 。 Anvil的进入标志是JWT,它们作为-is发送: Bearer <accessToken>。任何其他种类的代号为 Base64 编码: Bearer base64(accessToken)。 。 。 .

const anvilClient = new Anvil({ accessToken: 'your-oauth-access-token' })

如果你通过两者 accessToken 已使用.

基础URL

默认, 请求去生产, https://app.useanvil.com设置 baseURL 让他们去别的地方 所有请求都前往主机:

  • 瑞丝: {baseURL}/api/v1/...
  • 图QL : {baseURL}/graphql
  • 文件下载: {baseURL}/api/document-group/{eid}.zip
const anvilClient = new Anvil({
  apiKey: 'your-api-key',
  baseURL: 'https://anvil.example.com',
})

别包括尾部斜线.

常数

  • Anvil.VERSION_LATEST (单位:千美元)-1- 与我们一起 fillPDF是因为 versionNumber 选项,填写已发布或不发布的PDF模板的最新版本。 用来填稿.
  • Anvil.VERSION_LATEST_PUBLISHED (单位:千美元)-2) - 填充最新发布的版本. 与离开不同 versionNumber 中,如果模板从未发布,则返回错误.

错误

默认情况下,客户端的方法不会因为API对问题的反应而拒绝. 相反,他们以 errors 数组与 statusCode每个项目都有: message页:1 name或者两者兼有 让他们拒绝,你应当开口 throwOnError。 。 。 .

const { statusCode, data, errors } = await anvilClient.fillPDF(pdfTemplateID, payload)
if (errors) {
  console.log(statusCode, errors)
}

errors 看起来像其中之一:

  • 图QL 错误,如API返回的,经常带有 200 statusCode数字 :
    [{ message: 'Not Found', path: ['etchPacket'], locations: [{ line: 2, column: 3 }] }]
    
  • 一个 REST 错误 . 校验错误没有 message,但列出每个问题字段:
    [{ name: 'AssertionError', message: 'PDF did not generate properly from given HTML!' }]
    [{ name: 'ValidationError', status: 400, fields: [{ message: 'Required', property: 'data' }] }]
    
  • 一个不是JSON的反应像一个 502 从代理。 这个 name 财务报告和审定财务报表 message 是 HTTP 状态文本 :
    [{ name: 'Bad Gateway', message: 'Bad Gateway' }]
    
  • 无法解析的JSON反应. 这是解析错误的 name, (中文(简体) ), message, (中文(简体) ), code, (中文(简体) ), cause 财务报告和审定财务报表 stack数字 :
    [{ name: 'SyntaxError', message: 'Unexpected end of JSON input', stack: '...' }]
    

当一个请求完全无法提出时,例如由于网络出错,这些方法确实拒绝了. 这些是 fetch 错误,详情见 cause数字 :

try {
  await anvilClient.fillPDF(pdfTemplateID, payload)
} catch (error) {
  console.log(error.message) // 'fetch failed'
  console.log(error.cause.code) // e.g. 'ECONNREFUSED'
}

如果连接在全响应到达之前关闭,则返回二进制数据的方法(如 fillPDF 或者说 downloadDocuments拒绝方式 TypeError: terminated。返回 JSON 的答案是 errors: [{ name: 'TypeError', message: 'terminated' }]。 。 。 .

它们也会为无效的参数投出, 就像一个不支持的参数 dataType。 。 。 .

抛出错误

过 throwOnError: true 和拒绝的方法 AnvilRequestError 只要他们能解决 errors那边 try编号 :catch 处理各种故障。 默认关闭;随着关闭,方法行为如上.

const Anvil = require('@anvilco/anvil')
const { AnvilRequestError } = Anvil
// Or: import Anvil, { AnvilRequestError } from '@anvilco/anvil'

const anvilClient = new Anvil({ apiKey, throwOnError: true })

try {
  const { data } = await anvilClient.fillPDF(pdfTemplateID, payload)
  fs.writeFileSync('filled.pdf', data, { encoding: null })
} catch (error) {
  if (error instanceof AnvilRequestError) {
    console.log(error.message) // e.g. '400: ValidationError (data: Required)'
    console.log(error.statusCode, error.errors)
  } else {
    throw error // e.g. 'fetch failed'
  }
}

成功的请求解决 就像它与 throwOnError 关闭.

fillPDF, (中文(简体) ), generatePDF, (中文(简体) ), downloadDocuments, (中文(简体) ), requestGraphQL 财务报告和审定财务报表 requestREST 还接受 throwOnError 在他们的选项中,要覆盖客户端对一个请求的设置:

const { statusCode, errors } = await anvilClient.fillPDF(pdfTemplateID, payload, { throwOnError: false })

一个 AnvilRequestError 拥有:

  • name (叫声) - 'AnvilRequestError'
  • message (String) - 状态代码,然后每个错误的 name 财务报告和审定财务报表 message字段,由 '; '。例如, '400: ValidationError (data: Required)' 或者说 '200: Not Found; Forbidden'。 。 。 .
  • statusCode (数字) - HTTP状态代码. 图QL 错误通常带一个 200。 。 。 .
  • errors (物体阵列) - errors 这种方法会解决的 见上.
  • data (Object) - API在错误同时返回的任何数据, 否则 undefined。一个 GraphQL 请求可以部分成功;这是 GraphQL 响应 data,因此查询的结果是: error.data.etchPacket没有 data.data.etchPacket 就像当一个请求成功.
  • response (回复) - 获取 Response,例如: 费率限制 头. 其体相已已诵.

所有拒绝的东西 throwOnError 关闭仍然以同样的方式拒绝它: 网络错误,一个二进制响应被切短(TypeError: terminated),和无效参数。 JSON的答复被缩短,这将解决 errors: [{ name: 'TypeError', message: 'terminated' }],以 AnvilRequestErrorA级 429 仍然被重审,而不是扔.

费率限制

我们的API已经设置了要求的费率限制. 此客户端最初提出的要求将会从 X-RateLimit-Limit 财务报告和审定财务报表 X-RateLimit-Interval-Ms 响应头,然后自动处理随后对您的请求的节奏。 在等待第一次答复时提出的任何请求,将在发出之前等待.

和 API 一样, 客户端通过滑动窗口计算请求: 它只在 X-RateLimit-Limit 请求已在最后 X-RateLimit-Interval-Ms。 。 。 .

如果这个客户仍然收到 429 Too Many Requests 错误响应,它将等待在 Retry-After 头,外加50ms,然后重试请求.

见 Anvil API 文件 关于费率限额的具体细节的更多信息.

API 文档

我们的普通 API 文档可以找到 这里. 它是有关我们API及其能力的最新信息的最佳资源.

见 PDF 填补 API 文档 欲了解更多关于 fillPDF 方法.

实例

这个 实例 文件夹在 JavaScript 和 TypeScript 有完整,可操作的例子: 填充 PDF , 从 Markdown 或 HTML 生成 PDF , 用模板或上传的 PDF 电子签名, 用签名文件下载后嵌入签名.

发展

见 捐款额 如何运行测试 并发布一个发布.

版本与发布记录

@anvilco/anvil 共发布 44 个版本,首次发布于 2020/02/06;过去 12 个月发布了 4 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
4.2.0latest2026/11/034 天前
4.1.12026/10/309 天前
4.1.02026/10/2217 天前
4.0.02026/10/1523 天前
3.3.22025/03/101.7 年前
3.3.12024/10/052 年前

其他发布通道:beta → 3.2.0-beta.1。

关于 @anvilco/anvil 的常见问题

@anvilco/anvil 是什么?

Anvil API 客户端

如何安装 @anvilco/anvil?

在项目目录运行 npm install @anvilco/anvil,或使用 pnpm add / yarn add / bun add。

@anvilco/anvil 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@anvilco/anvil 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@anvilco/anvil 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@anvilco/anvil 可以商用吗?

@anvilco/anvil 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@anvilco/anvil 的下载量有多少?

根据 npm 官方下载统计,@anvilco/anvil 在 2026/10/06 – 2026/11/04 这 30 天内被下载 269,630 次,日均约 8,988 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@anvilco/anvil 还在维护吗?

最新版本 4.2.0 发布于 2026/11/03(4 天前);至今共发布 44 个版本,其中过去 12 个月发布了 4 个;首次发布于 2020/02/06。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。