Using Form Fields per Document

Hi folks! We caught a bug in the data structure expected by form_fields_per_document. Sorry about that! What broke? Support for using one-dimensional payloads with form_fields_per_document, which was recently introduced.
The good news: We've already discovered and implemented a fix.
The bad news: It's going to take about a week to get fully rolled out.
Using form_fields_per_document
At this time, the form_fields_per_document parameter only supports the use of two-dimensional arrays.

What is the impact?

At the time of writing, using form_fields_per_document only works with two dimensional arrays sent as JSON payloads. The biggest impact is that our beta SDKs don't support form_fields_per_document (...temporarily).
This two-dimensional array is the same data structure used for this property in the past. Many older examples still use this format and can be used as reference, such as this Help Center article: How to use the Form_Fields_Per_Document parameter.

What should I do?

Use the two-dimensional format for passing form_fields_per_document until our fix is fully rolled out. For anyone using our beta SDKs, that might mean sending raw HTTP requests from your code (instead of using the SDK) to pass the data structure directly.

What do the data structures look like?

Here's a side-by-side comparison of the two different data structures:

USE: Two-dimensional Array (Legacy)DON'T USE: One-dimensional Array (New)
Copy
Copied
{
  "file": [
    "file_0",
    "file_1",
    "file_2"
  ],
  "form_fields_per_document": [
    [
      {
        "api_id": "uniqueIdHere_1",
        "name": "",
        "placeholder": "",
        "type": "text",
        "x": 112,
        "y": 328,
        "width": 100,
        "height": 16,
        "required": true,
        "signer": 1,
        "page": 1,
        "validation_type": "numbers_only"
      }
    ],
    [],
    [
      {
        "api_id": "uniqueIdHere_3",
        "name": "",
        "type": "signature",
        "x": 530,
        "y": 415,
        "width": 120,
        "height": 30,
        "required": true,
        "signer": 0,
        "page": 1
      }
    ]
  ]
}
Copy
Copied
{
  "file": [
    "file_0",
    "file_1",
    "file_2"
  ],
  "form_fields_per_document": [
    {
      "document_index": 0,
      "api_id": "uniqueIdHere_1",
      "name": "",
      "placeholder": "",
      "type": "text",
      "x": 112,
      "y": 328,
      "width": 100,
      "height": 16,
      "required": true,
      "signer": 1,
      "page": 1,
      "validation_type": "numbers_only"
    },
    {
      "document_index": 2,
      "api_id": "uniqueIdHere_3",
      "name": "",
      "type": "signature",
      "x": 530,
      "y": 415,
      "width": 120,
      "height": 30,
      "required": true,
      "signer": 0,
      "page": 1
    }
  ]
}

Here's a summary of the differences between the two formats:

FeatureLegacy Structure (Two-dimensional)New Structure (One-dimensional)
Object formatTwo-dimensional array, where an array of field objects is nested inside another arrayOne-dimensional array, where a flat object contains two arrays; one for documents and one for fields
Matching fields to documentsUses the index of the array to determine which document the fields are associated with.Uses the document_index property to explicitly define the document the fields are associated with.
Documents without fieldsMust be included as an empty array ([]) to maintain index of other arraysCan be omitted from API call

Two-dimensional Arrays

Historically, developers using form_fields_per_document would add fields to their document using a two dimensional array. The first array defined the documents on the request and the second array defined the fields associated with that respective document based on that array's index. Here's a couple examples:
Add field to two documentsAdd field to third document only
Copy
Copied
{
  "file": [
    "file_0",
    "file_1"
  ],
  "form_fields_per_document": [
    [
      {
        "api_id": "uniqueIdHere_1",
        "name": "",
        "placeholder": "",
        "type": "text",
        "x": 112,
        "y": 328,
        "width": 100,
        "height": 16,
        "required": true,
        "signer": 1,
        "page": 1,
        "validation_type": "numbers_only"
      }
    ],
    [
      {
        "api_id": "uniqueIdHere_2",
        "name": "",
        "type": "signature",
        "x": 530,
        "y": 415,
        "width": 120,
        "height": 30,
        "required": true,
        "signer": 0,
        "page": 1
      }
    ]
  ]
}
Copy
Copied
{
  "file": [
    "file_0",
    "file_1",
    "file_2",
    "file_3",
    "file_4"
  ],
  "form_fields_per_document": [
    [],
    [],
    [
      {
        "api_id": "uniqueIdHere_1",
        "name": "",
        "placeholder": "",
        "type": "text",
        "x": 112,
        "y": 328,
        "width": 100,
        "height": 16,
        "required": true,
        "signer": 1,
        "page": 1,
        "validation_type": "numbers_only"
      }
    ],
    [],
    []
  ]
}
In this two-dimensional model, new fields can be added to documents by inserting additional field objects into the array that corresponds with a specific document. This structure also requires that an empty array [] be passed for documents that you don't want to add fields. These objects had the potential to get confusing and difficult to work with, especially as they grew in size for signature requests with lots of documents or lots of fields.

One-dimensional Array

As part of our work on HelloSign's OpenAPI spec, we introduced the ability to use a one-dimensional array with form_fields_per_document. Our goal was to improve the experience of developers programmatically placing fields while maintaining backwards compatibility. There are two major changes to this new data structure:
1. Introduces an explicity defined index for documents (document_index) -- allowing fields to specify the document they belong to
2. Flattens the object overall -- eliminating nested arrays
Copy
Copied
{
  "file": [
    "file_0",
    "file_1"
  ],
  "form_fields_per_document": [
    {
      "document_index": 0,
      "api_id": "uniqueIdHere_1",
      "name": "",
      "placeholder": "",
      "type": "text",
      "x": 112,
      "y": 328,
      "width": 100,
      "height": 16,
      "required": true,
      "signer": 1,
      "page": 1,
      "validation_type": "numbers_only"
    },
    {
      "document_index": 0,
      "api_id": "uniqueIdHere_2",
      "name": "",
      "type": "signature",
      "x": 530,
      "y": 415,
      "width": 120,
      "height": 30,
      "required": true,
      "signer": 0,
      "page": 1
    },
    {
      "document_index": 1,
      "api_id": "uniqueIdHere_3",
      "name": "",
      "type": "signature",
      "x": 530,
      "y": 415,
      "width": 120,
      "height": 30,
      "required": true,
      "signer": 0,
      "page": 1
    }
  ]
}
It might seem subtle, but this change in structure adds a lot of value. The reduction in complexity is designed to help developers read, understand, and interact with form_fields_per_document more effectively. The data structure with one-dimensional arrays is the format that our OpenAPI-based SDKs (in beta) are designed to support.

Future Plans

Moving forward, our plan is to steer developers towards the one-dimensional data structure. We will ensure backwards compatibility for the two-dimensional structure to support legacy SDKs, but the new OpenAPI-based SDKs will use the one dimensional structure and our sample coverage will reflect that.

We're sorry for any temporary disruptions (beta SDK users especially) or challenges you encounter while using form_fields_per_document. We're working to get our fix fully tested and deployed to production quickly and safely. This article will be updated to reflect status and progress.