Download the packet
Once every signer has finished, the completed files are available through Anvil's downloadDocuments endpoint. It returns a ZIP file containing the signed PDFs for the packet. The Node client takes the documentGroupEid and a dataType (buffer, arrayBuffer, or stream).
import fs from 'node:fs'
import Anvil from '@anvilco/anvil'
const anvilClient = new Anvil({ apiKey: process.env.ANVIL_API_KEY })
// documentGroupEid arrives in the etchPacketComplete webhook payload,
// or you can pull it from your createEtchPacket response.
const documentGroupEid = 'GqqU9OKLhmnGBeCusRRa'
const { data, errors } = await anvilClient.downloadDocuments(
documentGroupEid,
{ dataType: 'stream' },
)
if (errors) {
console.error(errors)
return
}
data.pipe(fs.createWriteStream(`./${documentGroupEid}.zip`))Find the documentGroupEid
The documentGroupEid is not the same value as etchPacketEid, which is the most common reason this call fails with a not-found error. When you create the packet, ask for the documentGroup eid in the response query so you can persist it alongside the packet:
const responseQuery = `{
eid
documentGroup { eid status }
signers { eid }
}`
const { data } = await anvilClient.createEtchPacket({
variables: { /* files, signers, ... */ },
responseQuery,
})
const documentGroupEid = data.data.createEtchPacket.documentGroup.eidCall it after the packet completes
Wait for the etchPacketComplete webhook (which fires once all parties have signed) before calling downloadDocuments. If you call it earlier or inside a signerComplete handler, you will get whatever has been signed so far, which is useful for in-progress audits but not for handing the customer their final contract. If webhooks are not an option, query the documentGroup status until it reads completed.
Common gotchas
Use dataType 'stream' for large packets so you do not buffer many megabytes in memory; the default is buffer, which is fine for one or two PDFs. Test packets created with isTest true also work with downloadDocuments and do not consume billable credits, so use them to wire up the pipeline before going to production. The same method exists in the Python, Ruby, PHP, and .NET clients, listed on the Anvil open source page.
Back to All Questions