Create a Bundle Document from HTML
Generate a PDF from HTML and send it for electronic signature in a single Blueink API call — no need to render the PDF yourself, host it, or upload it as a file. Provide HTML (with optional CSS for layout and data-blu-* annotations for signature, initial, date, and form fields), and Blueink converts the HTML to a PDF and detects the fields automatically.
This is useful for dynamically generating signable documents from templates, building HTML forms that map directly to e-signature fields, and any workflow where the source-of-truth document lives in HTML rather than as a pre-rendered PDF.
This guide describes how to create a Bundle Document from HTML and documents the rules Blueink uses to convert your HTML to a PDF and extract form fields.
Basic Usage
When creating a new Bundle in Blueink via the Create Bundle endpoint (POST /api/v2/bundles/), you can create a document from HTML by including a file_html parameter on any document. The value should be the escaped HTML of your document.
Field Detection Mode
The optional html_fields_mode parameter on the document object controls how form fields are extracted from the HTML:
"blueink"(default) — Detects form elements anddata-blu-*annotations and converts them to Blueink fields, as described in this guide."none"— Skip field detection entirely. The HTML is rendered to a PDF and attached to the document, but no fields are created. Use this when you intend to add fields via the API (e.g., viafieldsin the Create Bundle request) or via Auto Placement.
1. HTML Structure Requirements
Page Size & Layout
Do NOT combine @page { margin } with .page { padding } — this causes double pages!
Option A: Zero page margin (Recommended)
@page {
size: A4;
margin: 0; /* No page margin - padding is handled by .page */
}
.page {
width: 210mm;
min-height: 297mm;
padding: 20mm; /* Content padding inside the page */
margin: 0 auto;
box-sizing: border-box; /* Include padding in dimensions */
}
.page:not(:last-child) {
page-break-after: always;
}
Option B: Page margin with adjusted height
@page {
size: A4;
margin: 20mm; /* 20mm margin on all sides */
}
.page {
width: 170mm; /* 210mm - 40mm (left + right margin) */
min-height: 257mm; /* 297mm - 40mm (top + bottom margin) */
padding: 0; /* No padding - margin handles spacing */
margin: 0 auto;
}
.page:not(:last-child) {
page-break-after: always;
}
Common Mistake: Double Pages
If your 5-page HTML produces 10 PDF pages, check for this issue:
/* ❌ WRONG - causes double pages */
@page { margin: 20mm; }
.page { min-height: 297mm; padding: 20mm; }
/* ✅ CORRECT - use one or the other */
@page { margin: 0; }
.page { min-height: 297mm; padding: 20mm; box-sizing: border-box; }
Print Media Styles
@media print {
body {
padding: 0;
margin: 0;
background: #FFFFFF;
}
.page {
margin: 0;
width: 100%;
min-height: auto;
box-shadow: none;
}
}
2. Form Field Detection
Field Detection from HTML Form Elements
| Element | Blueink Field | Default Validation | Example |
|---|---|---|---|
<input type="text"> | Text | None | <input type="text" name="first_name"> |
<input type="email"> | Text | Valid Email | <input type="email" name="email"> |
<input type="tel"> | Text | Valid Phone | <input type="tel" name="phone"> |
<input type="number"> | Text | Numbers Only | <input type="number" name="age"> |
<input type="url"> | Text | None | <input type="url" name="website"> |
<input type="search"> | Text | None | <input type="search" name="q"> |
<input type="password"> | Text | None | <input type="password" name="pwd"> |
<input type="checkbox"> | Checkbox | None | <input type="checkbox" name="agree"> |
<input type="radio"> | Checkbox Group (cbg) | None | <input type="radio" name="option" value="a"> |
<textarea> | Multiline Text | None | <textarea name="notes"></textarea> |
<select> | Dropdown | None | <select name="country"><option>...</option></select> |
For Date fields (dat) and Signing Date / Timestamp fields (tms), use data-blu-field-kind on any element. See Field Kind below.
Radio buttons that share the same name attribute are automatically grouped into a single Checkbox Group field (kind cbg), with the group key derived from the shared name.
A <select> element with no <option> children is silently skipped.
To ignore a form element in the HTML, add a data-blu-ignore attribute with any non-empty value.
<input type="text" data-blu-ignore="1" />
Unsupported Elements (Skipped)
These input types are skipped during field detection:
<input type="button"><input type="submit"><input type="reset"><input type="image"><input type="date">— usedata-blu-field-kind="dat"on any element to create a Date field instead
Signature, Initial and Signing Date Fields
Signature, Initial and Signing Date fields are detected by CSS class or by including a data-blu-field-kind attribute. When both are present on the same element, data-blu-field-kind takes precedence; the CSS classes are a convenience/legacy path used when data-blu-field-kind is absent.
<!-- Any of these classes / attributes will be detected as a Signature field -->
<div class="blu-signature-field"></div>
<div class="blu-signature"></div>
<div class="blu-sign"></div>
<div data-blu-field-kind="sig"></div>
<!-- Any of these classes / attributes will be detected as an Initials field -->
<div class="blu-initial-field"></div>
<div class="blu-initial"></div>
<div data-blu-field-kind="ini"></div>
<!-- Any of these classes / attributes will be detected as a Signing Date field -->
<div class="blu-signing-date"></div>
<div data-blu-field-kind="tms"></div>
3. Specifying Other Field Attributes
You can set additional field parameters by adding data attributes to an element. All attributes start with data-blu-.
3.a. Field Kind
Use the data-blu-field-kind attribute for explicit field type declaration. The allowed field kinds match the values for kind in the documentation for fields in the Create Bundle request in the API Reference.
| Kind | Field Type |
|---|---|
sig | Signature |
ini | Initials |
tms | Signing Date / Timestamp |
dat | Date |
inp | Single-line Text |
txt | Multi-line Text |
sel | Dropdown |
chk | Checkbox |
cbg | Checkbox Group |
<input type="text" name="first_name" data-blu-field-kind="inp">
<select name="country" data-blu-field-kind="sel">
<input type="checkbox" name="agree" data-blu-field-kind="chk">
<textarea name="notes" data-blu-field-kind="txt"></textarea>
<div class="signature-field" data-blu-field-kind="sig">Sign Here</div>
<div data-blu-field-kind="dat" data-blu-field-format="MM/DD/YYYY"></div>
3.b. Other Field Attributes
- Label:
data-blu-field-label-- the label for the field, shown to signers. Note that if a label is not provided via this attribute, Blueink will attempt to detect the label from the surrounding HTML. See "Detecting Field Labels" below. - Format:
data-blu-field-format-- a format string for Date (dat) or Signing Timestamp (tms) fields. - Required:
data-blu-field-required-- set to1ortrue(case-insensitive) to mark the field as required. Any other value -- includingyes,on,0,false, or omitting the attribute -- leaves the field as not required. - Initial Value:
data-blu-field-value-- the initial value for the field. Alternatively, the value can be set via thevalueattribute for form fields. Thedata-blu-field-valueattribute takes precedence over thevalueattribute. - Validation Pattern:
data-blu-field-v-pattern-- one of the named validation patterns listed in the API Reference. - Min Length:
data-blu-field-v-min-- the minimum length for the field. - Max Length:
data-blu-field-v-max-- the maximum length for the field. - Group:
data-blu-field-group-- the group name for fields that participate in a Checkbox Group (cbg). Multiple checkboxes that share the same group name are combined into a single Checkbox Group field. (For radio buttons, the sharednameattribute serves the same purpose automatically.) - Editors:
data-blu-field-editors-- a comma-separated list of editor names. These are a list of Signer keys, as specified in the documentation foreditorsin the Create Bundle request in the API Reference. The comma separated list can contain spaces (which are ignored). If no editor names are provided, the field will be read-only.
Detecting Field Labels
If a field label is not provided via data-blu-field-label, Blueink will attempt to detect the label from the surrounding HTML. The label search proceeds as follows. This applies for valid form tags (input, select, textarea) as well as for other tags (e.g. div) identified as fields via data-blu-field-kind.
- A
<label>tag with aforattribute matching the field'sid. - Enclosing
<label>tag (if any). - Preceding sibling
<label>tag. - The text of the nearest preceding
<span>,<div>, or<p>element with a non-empty text shorter than 100 characters. - The field's
nameattribute, as a final fallback.
To prevent Blueink from detecting a label, add the attribute data-blu-field-label="" to the field element.
Field IDs
Each detected field is assigned an ID derived from the source element. Blueink uses the element's name attribute, falling back to the id attribute, and finally to a generated identifier if neither is present. Characters that are reserved in PDF AcroForm field names -- (, ), <, >, [, ], {, }, /, % -- are replaced with underscores in the generated field key.
4. Field Layout
Blueink inspects the placement and dimensions of the field element in the HTML to determine the placement of the field on the PDF. It is important that the field element occupies the same space in the HTML as it will in the PDF. Technically, the element must generate a CSS box in the layout (i.e., it must participate in the render tree).
In practice, this means the element should have a display property of block, inline-block, flex, or grid. inline can work, but is less reliable as an inline element will collapse to zero width if it has no content.
Specifying a position of absolute or fixed will also work.
These attributes are also acceptable, but can make debugging your HTML more difficult. In both cases, the element will still occupy space in the layout, but will not be visible in the browser.
visibility: hiddenopacity: 0
5. Best Practices
- Use semantic HTML - Proper form elements for better field detection
- Set page breaks - Use
.pageclass withpage-break-after: always - Avoid double margins - Use either
@page { margin }OR.page { padding }, not both - Use box-sizing - Add
box-sizing: border-boxto include padding in dimensions - Test print styles - Ensure
@media printstyles work correctly - No JavaScript - All
<script>tags and event handlers are removed for security
6. Example HTML Template
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Form Template</title>
<style>
@page {
size: A4;
margin: 0; /* Zero margin - padding handled by .page */
}
body {
margin: 0;
padding: 0;
background: #f5f5f5;
}
.page {
width: 210mm;
min-height: 297mm;
padding: 20mm;
margin: 0 auto;
background: white;
box-sizing: border-box; /* Include padding in dimensions */
}
.page:not(:last-child) {
page-break-after: always;
}
.blu-signature-field {
border: 2px dashed #999;
min-height: 80px;
}
@media print {
body { background: white; }
.page { margin: 0; box-shadow: none; }
}
</style>
</head>
<body>
<div class="page">
<h1>Form Title</h1>
<label>Name:</label>
<input type="text" name="name" data-blu-field-kind="inp">
<label>Signature:</label>
<div class="blu-signature-field"></div>
</div>
</body>
</html>
7. Security
JavaScript Removal
All JavaScript code is automatically removed from HTML files before PDF conversion for security:
| Removed | Example |
|---|---|
<script> tags | <script>alert('xss')</script> |
<noscript> tags | <noscript>...</noscript> |
| Event handlers | onclick="...", onload="...", onerror="..." |
| JavaScript URLs | javascript: schemes in href, src, action, formaction, and data attributes |
8. HTML Parsing Stability
The HTML-to-PDF and field-detection rules described in this guide are part of the stable Blueink APIv2 surface. Blueink will preserve backwards compatibility for HTML submitted via the file_html parameter on POST /api/v2/bundles/, including the set of recognized data-blu-* attributes, the field-kind values, and the label-detection algorithm.
The underlying HTML parser may evolve over time (for example, to support new field kinds or improve layout fidelity). When such changes are introduced, they will either be additive (no change to behavior for existing HTML) or gated behind an explicit opt-in. A future release is expected to introduce a pipeline parameter that pins the parser to a specific specification version, so that integrators can adopt new parser behavior on their own schedule. Until that parameter is available, the behavior described in this guide is the contract.