- Calls Box Doc Gen to merge the data into an offer letter template.
- Listens for a Doc Gen completion webhook and records the generated PDF.
- Creates a Box Sign request so an HR approver reviews the letter before the candidate signs.
Clone the working sample
What you are building
By the end of this tutorial, you have a working Node.js service that:- Accepts offer data from an applicant tracking system (ATS) or HR webhook.
- Validates the payload and calls Box Doc Gen to merge data into an offer letter template.
- Listens for a Doc Gen completion webhook and records the generated PDF file ID.
- Creates a Box Sign request with an HR approver and the candidate as signers.
- Exposes endpoints to trigger generation, send for signature, and check offer letter status.
Prerequisites
Before you start, make sure you have the following:- Node.js 18 or higher.
- A Box Enterprise Advanced account with entitlement and enabled in the Admin Console. Box Doc Gen is not available on free developer accounts.
- A Box application configured with Client Credentials Grant authentication, authorized in the Admin Console. See for setup details.
- The Box enterprise ID for your account (
BOX_ENTERPRISE_ID). The Client Credentials Grant app authenticates as the enterprise service account. Find it in the Developer Console under your app’s General Settings, or in the Admin Console.
Step-by-step process
This solution uses three Box Platform capabilities:Enable Box Doc Gen and Box Sign
Create Box folders
Offer Letter TemplateGenerated Offer LettersSigned Offer Letters
https://app.box.com/folder/123456789 → 123456789). You need these values for the project variables BOX_DOCGEN_DESTINATION_FOLDER_ID and BOX_SIGN_PARENT_FOLDER_ID.Collaborate the app’s service account into the template, generated-offer, and signed-offer folders with Editor access. Service accounts do not automatically have access to user-owned content. You can find the service account address (AutomationUser_...@boxdevedition.com) in the Developer Console under your app’s General Settings.Create an offer letter template
- Open the Automate tab in Box.
- Navigate to the Doc Gen tab.
- Select the Employee Offer Letter template.
- Select a destination folder for the template and generated documents.
- Select Generate Document, then save the template file ID from the page or from the URL.
validateOffer function checks in a later step: id, country, contractDate, deliveryTerms, companyName, baseSalary, salaryDetails, salaryModel, employee.address, employee.dob, employee.email, employee.name, company.address, company.designatedSigner, company.name, company.designation, company.department, position, department, and startDate.Create and configure your Box application
- Enable the Read all files and folders, Write all files and folders, Manage Doc Gen, Manage signature requests, and Manage webhooks scopes.
- Save your changes and authorize the app in the Developer Console in App Details section under Status.
Set up the development environment
- Open your terminal and create a new project directory:
- Initialize
package.jsonand enable ES modules. The service usesimport/exportsyntax, so Node needs"type": "module"to run the files:
- Install the required packages:
- Create a
.envfile to store your credentials, then add the following content. Replace the placeholder values with your credentials and folder IDs from the Box Developer Console:
PUBLIC_BASE_URL to the tunnel URL. In production, verify webhook signatures. See .Create configuration and storage helpers
config.js file and add the following code. It loads environment variables used throughout the service:store.js with a simple in-memory store for the demo. Replace this with a database before you deploy to production.box-client.js and add a function that creates a Box client authenticated with Client Credentials Grant:Validate offer data
offer-letter-data.js with functions that validate incoming offer payloads before you call Doc Gen. The buildOfferLetterData function is a pass-through hook you can extend to map or transform fields before Doc Gen merges them into the template.Generate offer letters with Box Doc Gen
box-docgen.js with functions that start document generation and parse webhook payloads:Send offer letters for signature with Box Sign
box-sign.js with functions that collaborate the HR approver on the generated file and create a Box Sign request. In this example, the HR team member acts as an approver and reviews the documents, so they can double-check the offer details. Once this is approved in Box, the candidate receives the offer letter in their mailbox, with a custom email message valid for 14 days:Build the Express server
server.js to orchestrate the workflow. The server loads the Box configuration from environment variables, and creates a Box SDK client. It then exposes the REST endpoints:store.js module is for demos only — replace it with a database for production before you deploy.Configure the Doc Gen webhook
DOCGEN_DOCUMENT_GENERATION_SUCCEEDED trigger is file-only; registering it on a folder returns a 400 invalid_parameter error. For more options, see .Configure a V2 Box webhook for your app:- Define the URL where webhook payloads are sent.
- Select the Box Doc Gen template document as the trigger.
- Enable the Document Generation Succeeded trigger (
DOCGEN_DOCUMENT_GENERATION_SUCCEEDED).
$BOX_ACCESS_TOKEN with a valid access token from your CCG-authenticated client:Test the application
.env file, then run:created, sent, viewed, signed, declined, and expired.Check the result:GET /offer-letterslists all in-memory offer records and their statuses.GET /offer-letters/:id/sign-requestreturns the latest Box Sign status for an offer.- The HR approver receives the document first. After approval, the candidate receives the offer letter by email.
Troubleshooting
404 Not Found when generating documents
404 Not Found when generating documents
Offer letter PDF is not ready yet (409)
Offer letter PDF is not ready yet (409)
DOCGEN_DOCUMENT_GENERATION_SUCCEEDED trigger, and that your server is reachable at the configured URL.Missing offer fields validation error
Missing offer fields validation error
required array in validateOffer and make sure nested fields such as employee.email are present.The candidate does not receive a signing email
The candidate does not receive a signing email
employee.email in the offer payload. This value is used as the Box Sign recipient.Missing required environment variables
Missing required environment variables
.env includes BOX_CLIENT_ID, BOX_CLIENT_SECRET, BOX_ENTERPRISE_ID, BOX_DOCGEN_TEMPLATE_FILE_ID, BOX_DOCGEN_DESTINATION_FOLDER_ID, and BOX_SIGN_PARENT_FOLDER_ID.Other use cases
The same Box Doc Gen and Box Sign pattern applies to other workflows that need both document generation and approval or signature:Scaling to production
Replace in-memory storage
Replace in-memory storage
store.js module loses data on restart. Persist offer records in a database so you can correlate Doc Gen batch IDs, generated file IDs, and Box Sign request IDs across restarts and retries.Verify webhook signatures
Verify webhook signatures
Customize Box Sign workflow
Customize Box Sign workflow
signers array and other Box Sign request parameters. See .Harden webhook and API handling
Harden webhook and API handling
