DoConure

Where the signature goes on the page

There are two ways to say where a signer signs. Put a tag in the document (the usual way): the signature lands where the tag is, wherever the text around it pushes it. Or give coordinates in the request. If you send both for a signer, the coordinates win.

With a tag in the document

In the template, a tag is written like every other field, with signature and the key the signer has in signers:

Signed for the customer: {{ signature.A }}
Name: {{ signature.A.name }}      Date: {{ signature.A.date }}

Signed for the supplier: {{ signature.B.box(0.3, 0.08) }}
TagPlaces
{{ signature.A }}signer A's signature
{{ signature.A.name }}their name, printed when they sign
{{ signature.A.date }}the date they sign
.box(width, height)the size, in fractions of the page (default 0.25 × 0.06), on any of the three

The top-left corner of the signature is where the tag starts. The tag itself prints nothing: when the PDF is made it is found, turned into a field and removed from the file before the file is hashed, sealed or stored, so no hidden text is left for anybody to copy out of it. A tag works in Word and HTML templates in the body, a table cell, a header or a footer; in Excel in a cell of a sheet (not in the printed header or footer), one tag per cell, placed where the cell's text starts, so give it a cell of its own. Write it in one go: Word can split a tag you edit afterwards (Common mistakes).

  • Several tags for one signer make several fields: a signature on every page, or the date beside each one. At most 20 tags per signer, and 200 in one document.
  • A signer with no fields in the request is placed by their tags. A signer with fields keeps them.
  • Refused, never guessed: a tag for a signer the request does not have (SIGNATURE_TAG_UNKNOWN_SIGNER), and, when the template uses tags, a signer with neither a tag nor fields (SIGNER_NOT_PLACED). In POST /api/v1/flow both are refused before the document is composed, so they cost nothing — except for tags typed in an uploaded annex, which are read once the document exists.
  • A tag inside a condition that turns out false is not in the document. If that signer had no other place, the flow is refused after composing (SIGNER_NOT_PLACED, naming the document that was charged).
  • A box near the right or bottom edge is moved back inside the page, never shrunk.
  • A tag inside an existing link in a Word document is refused (a link cannot hold another).
  • If your data has its own field called signature, your field wins and the document has no tags.

A document composed on its own (POST /api/v1/compose/documents/generate) remembers where its tags landed. Send it for signature later with its documentId and the signers without fields are placed at their tags in the same way.

In a PDF you upload

Type the same tag as text in the document, for example {{ signature.A }}, and ask for it to be read with "signatureTags": true on that document:

"documents": [ { "fileId": "6d1c...", "signatureTags": true } ]

An upload is never scanned unless you ask. The position is exact when the tag starts its own line (or sits in its own text box); inside a longer line it is estimated from the characters before it. The text stays in your file: an uploaded file is signed exactly as you sent it.

With coordinates

Field coordinates are fractions of the page, not millimetres or points, with the origin at the top left. So x: 0.1, y: 0.78 is a tenth of the way across and 78% of the way down. They are fractions so that a template re-rendered at another page size still puts the mark in the same place.

"signers": {
  "A": { "email": "anna@example.com", "fullName": "Anna Rossi",
         "fields": [ { "kind": "signature", "page": 2, "x": 0.1, "y": 0.78,
                       "width": 0.3, "height": 0.08 } ] }
}

How to read x and y off a PDF

Open the PDF in a viewer that shows the cursor position in points (most do: Acrobat's measuring tool, or any PDF editor). An A4 page is 595 × 842 points. Say the line where the customer signs starts 70 points from the left edge and 650 points from the top:

x = 70 / 595  = 0.118
y = 650 / 842 = 0.772

If your viewer measures from the bottom (PDF's own convention), subtract first: a point 192 from the bottom is 842 − 192 = 650 from the top. Width and height work the same way: a box 180 points wide is 180 / 595 = 0.30. A field must stay on the page: x + width and y + height are each at most 1.

Fields that ask a question

Besides the marks (signature, name, date), a field can be an input the signer answers on the signing page: text, checkbox or dropdown. The answer is printed in the field's own box, recorded on the signed event of the evidence trail, listed under the signer on the certificate and returned in the API (recipients[].fields[].answer).

{ "kind": "checkbox", "page": 2, "x": 0.1, "y": 0.60,
  "label": "I have read annex B", "required": true }

{ "kind": "dropdown", "page": 2, "x": 0.1, "y": 0.68, "width": 0.4,
  "label": "Role", "options": ["Director", "Employee", "Contractor"],
  "value": "Employee" }

{ "kind": "text", "page": 2, "x": 0.1, "y": 0.76, "width": 0.5,
  "label": "Tax code", "required": false }
KeyMeans
labelThe question the signer sees. Required for an input.
requiredDefault true. The signature is refused (SIGNER_FIELD_INVALID) until it is answered; a required checkbox must be ticked. false lets it stay empty, and then it prints nothing.
optionsDropdown only: 2 to 20 choices, each up to 80 characters, all different. Any other answer is refused.
valueWhat you prefilled. The signer may change it…
locked…unless true: then the answer is your value whatever the form says. A locked field needs a value.

None of these mean anything on a signature, name or date, and a request that sets one there is refused, never ignored. The signing page works with script switched off: the questions are plain form controls in the one linear form.

When the envelope has more than one document

Up to ten documents can go into one envelope. They are merged, in the order you list them, into a single PDF before anybody signs — so there is one set of marks, one certificate of completion, one hash on /verify, and the signer reads one file.

"settings": {
  "documents": [
    { "documentId": "contract-9f2a..." },
    { "fileId": "6d1c..." }
  ],
  "subject": "Service agreement"
}

documentId on its own still works and means exactly what it always did; use documents when there is more than one.

A field then says which document and which page of that document:

{ "kind": "signature", "document": 2, "page": 1,
  "x": 0.1, "y": 0.8, "width": 0.3, "height": 0.08 }

Never an absolute page of the merged packet. You cannot know how long our merge made the file, and the first time an annexe gains a page every signature after it would move — silently. The offset is ours to know, so it is ours to apply. document defaults to 1, so an envelope written before this existed means exactly what it always meant.

Two things are refused rather than accepted quietly: a field on a document the envelope does not have, and a field past the last page of its own document. The second used to be accepted and the mark dropped at signing time, which is a mark nobody ever sees and nobody is told about.

Once it is signed, the certificate of completion lists every source with its own hash, and the evidence bundle carries each one separately beside the packet. The packet has replaced its parts, so without that, "which documents were in this" stops being answerable.

Where this sits in the request body: Signing on its own.