Formify can read the internal names of PDF form fields and interpret pipe-separated tink-* attributes. This lets a normal PDF text field become a validated email input, SMS OTP field, BankID-verified organisation number, ID scan trigger, auto-filled date field, searchable value, and more.
How it works
Name the PDF form field with a human-readable label first, then add one or more attributes after pipe characters:
phone|tink-format-mobile|tink-sms-verification
In this example, phone is the field label. tink-format-mobile validates the mobile number format, and tink-sms-verification sends an OTP code by SMS that the signer must enter before continuing.
Syntax rules
- Formify reads the PDF field's internal name, not only the visible text printed on the PDF.
- Anything before the first pipe character (
|) is treated as the field label. - Anything after the first pipe is interpreted as a
tink-*attribute. - Multiple attributes can be combined on the same field.
- Attributes ending with
[index]use the same index to connect trigger fields with fields they populate. Replaceindexwith a number but keep the square brackets — they are part of the actual field name:tink-scan-id[1]is correct,tink-scan-id1is not (without brackets the index is ignored and the fields are not linked). - Trigger fields are used as actions, such as opening BankID verification, ID scan, or attachment upload. They should not be treated as manually editable input fields.
Quick examples
| PDF field name | Result |
|---|---|
email|tink-format-email|tink-email-verification |
Validates email format and sends an email OTP. |
phone|tink-format-mobile|tink-sms-verification |
Validates Swedish mobile format and sends an SMS OTP. |
orgNumber|tink-orgnumber-verification[1]|tink-verified-orgnumber[1] |
Starts BankID organisation verification for group [1]. The trigger must be combined with a tink-verified-orgnumber* attribute on the same field to become clickable; the field receives the verified organisation number. |
companyName|tink-verified-orgnumber-companyname[1] |
Auto-fills the verified company name from the same verification group. |
idScan|tink-scan-id[1] |
Opens ID scanning and reads MRZ data from a passport or national ID. The field itself is replaced with an image of the scanned document — draw it generously sized, landscape about 3:2. |
photo|tink-scanned-id-portrait[1] |
Places the portrait photo from ID scan [1] at the field's position. |
date|tink-date-now|tink-style-transparent |
Auto-fills today's date and makes the field background transparent. |
Working with indexed attributes
Use the same [index] value when one field triggers a verification or scan and other fields should receive the result. The index is just a grouping key inside the PDF.
orgNumber|tink-orgnumber-verification[1]|tink-verified-orgnumber[1] companyName|tink-verified-orgnumber-companyname[1] address|tink-verified-orgnumber-addressline1[1] zip|tink-verified-orgnumber-zipCode[1] city|tink-verified-orgnumber-city[1]
Before sending
After uploading a PDF through POST /files, use GET /files/{fileId}/fields to inspect the fields Formify detected before creating a document. This is useful when testing new attribute combinations or confirming that the PDF editor saved the expected internal field names.
Some attributes depend on account capabilities such as BankID, ID scanning, attachments, or Sign & Pay. Check GET /account/capabilities before relying on optional features in production.
Attribute reference
Organisation verification
The trigger must be combined with a value attribute on the same field: a field named with only tink-orgnumber-verification[index] never becomes clickable. Combine it with tink-verified-orgnumber[index] or tink-verified-orgnumber-companyname[index] — the combination renders the "Click to verify" badge, and the field receives that verified value after verification.
| Attribute | Type | Description |
|---|---|---|
tink-orgnumber-verification[index] | triggermanual-entry-forbidden | Clickable input verifying organisation number and Beneficial Owner via Swedish BankID. Auto-populates verified organisation number and company name fields with the same index. |
tink-orgnumber-verification-boardmember[index] | triggermanual-entry-forbidden | Clickable input verifying organisation number and either Beneficial Owner or Board Member via BankID. Auto-populates verified organisation number and company name fields with the same index. |
tink-orgnumber-verification-kyc[index] | triggermanual-entry-forbidden | KYC-adapted BankID verification. Results are stored for compliance. Auto-populates verified organisation number and company name fields with the same index. |
tink-verified-orgnumber[index] | auto-populated | Verified organisation number. |
tink-verified-orgnumber-companyname[index] | auto-populated | Verified company name. |
tink-verified-orgnumber-addressline1[index] | auto-populated | Verified company address line 1. |
tink-verified-orgnumber-zipCode[index] | auto-populated | Verified company zip code. |
tink-verified-orgnumber-city[index] | auto-populated | Verified company city. |
Validation, verification, and styling
| Attribute | Type | Description |
|---|---|---|
tink-format-mobile | formatting | Validates Swedish mobile number format. |
tink-format-email | formatting | Validates email address format. |
tink-sms-verification | triggermanual-entry-forbidden | Triggers OTP verification by SMS. |
tink-email-verification | triggermanual-entry-forbidden | Triggers OTP verification by email. |
tink-email-recipient | Receives the completed document by email. | |
tink-date-now | auto-populated | Automatically inserts the current date in ISO 8601 format. |
tink-style-transparent | formatting | Makes the field transparent so it blends into a colored or styled PDF background. |
tink-input-fullname | Prefills full name for visible signature fields. |
ID scanning
Passports and national ID documents contain highly sensitive identification data. In some countries, scanning or copying ID documents is only allowed in limited circumstances. Before enabling ID scanning in a flow, you are responsible for ensuring that you have a valid legal basis and that scanning, storing, and retaining the document is necessary and proportionate for your specific purpose.
Formify provides the technical capability. You remain responsible as data controller for assessing legal requirements, applying appropriate retention periods, and informing signees about how their ID document will be processed.
Data minimization: note that by default the scan trigger field is replaced with an image of the scanned document — a copy of the ID document is then reproduced in the signed output. If you only need the verified data (name, document number, etc.) and not a document image, combine the trigger with an MRZ attribute, e.g. passportNo|tink-scan-id[1]|tink-scanned-id-mrz-documentid[1] — no image is placed and the field receives the document number instead. See ID scan images below.
| Attribute | Type | Description |
|---|---|---|
tink-scan-id[index] | triggermanual-entry-forbidden | Full ID scan button. Captures and reads a passport or national ID via camera and populates MRZ fields with the same index. The field itself is replaced with an image of the scanned document's front side — draw it generously sized, landscape about 3:2 (see ID scan images below for other options, including no image at all). |
tink-scan-id-basic[index] | triggermanual-entry-forbidden | Partial ID scan button. Populates MRZ fields with the same index and uses less strict validation. |
tink-scan-id-passport[index] | triggermanual-entry-forbidden | Full ID scan button that only allows passports. Populates MRZ fields with the same index. |
tink-scan-id-passport-basic[index] | triggermanual-entry-forbidden | Partial passport-only ID scan button. Populates MRZ fields with the same index and uses less strict validation. |
tink-scanned-id-mrz-firstname[index] | auto-populated | First name from scanned MRZ. |
tink-scanned-id-mrz-lastname[index] | auto-populated | Last name from scanned MRZ. |
tink-scanned-id-mrz-personalnumber[index] | auto-populated | Personal number from scanned MRZ. |
tink-scanned-id-mrz-documentid[index] | auto-populated | Document ID from scanned MRZ. |
tink-scanned-id-mrz-nationality[index] | auto-populated | Nationality from scanned MRZ. |
tink-scanned-id-mrz-nationalitycode[index] | auto-populated | Nationality code from scanned MRZ. |
tink-scanned-id-mrz-birthdate[index] | auto-populated | Birth date from scanned MRZ. |
tink-scanned-id-mrz-expirydate[index] | auto-populated | Expiry date from scanned MRZ. |
tink-scanned-id-mrz-issuedate[index] | auto-populated | Issue date from scanned MRZ. |
tink-scanned-id-mrz-issuingstatecode[index] | auto-populated | Issuing state code from MRZ. |
tink-scanned-id-mrz-issuingstatename[index] | auto-populated | Issuing state name from MRZ. |
tink-scanned-id-mrz-placeofbirth[index] | auto-populated | Place of birth from MRZ. |
tink-scanned-id-mrz-placeofissue[index] | auto-populated | Place of issue from MRZ. |
ID scan images
By default, the scan trigger field is replaced with an image of the scanned document's front side. The attributes below place other parts of the scanned document instead — or in addition. They work like the MRZ attributes: put them on their own fields with the same [index] as the trigger, and they are populated when the scan completes. One scan can fill any number of fields.
Create the trigger field and all image fields as read-only in your PDF — they act as a scan button and image placeholders, and signees should not be able to type text into them. The Formify signing client also locks them automatically, but setting read-only in the PDF is good practice and covers all client versions.
| Attribute | Type | Description |
|---|---|---|
tink-scanned-id-portrait[index] | auto-populatedmanual-entry-forbidden | Portrait photo from the scanned document. Strict: if the portrait cannot be extracted, the scan fails and the signee is asked to scan again. Draw the field upright, about 3:4 (width:height). |
tink-scanned-id-signature[index] | auto-populatedmanual-entry-forbidden | The printed signature from the scanned document, when the document has one. Draw the field wide and low, about 4:1. |
tink-scanned-id-ghostportrait[index] | auto-populatedmanual-entry-forbidden | The secondary "ghost" portrait, present on many modern ID cards and some passports. Draw the field upright, about 3:4. |
tink-scanned-id-documentrear[index] | auto-populatedmanual-entry-forbidden | The rear side of the document. Requires the signee to capture the back side (two-sided documents such as ID cards). Draw the field landscape, about 3:2. |
tink-scanned-id-barcode[index] | auto-populatedmanual-entry-forbidden | Image of the document's barcode area (for example PDF417 on US driver's licenses), when the document has one. Draw the field wide and low, about 4:1. |
Three placement rules:
- Standalone field:
photo|tink-scanned-id-portrait[1]is replaced by the portrait photo when scan[1]completes. - Combined with the trigger field:
idScan|tink-scan-id[1]|tink-scanned-id-portrait[1]overrides the default — the portrait is placed at the trigger field instead of the front-side image. - No image at all: combine the trigger with an MRZ attribute, e.g.
passportNo|tink-scan-id[1]|tink-scanned-id-mrz-documentid[1]— no image is placed; the field stays a text field and receives the document number.
idScan|tink-scan-id[1] photo|tink-scanned-id-portrait[1] signature|tink-scanned-id-signature[1] passportNo|tink-scanned-id-mrz-documentid[1]
Layout tip: images are stretched to fill the field's rectangle exactly — a portrait placed in a landscape field will look distorted. Follow the recommended field shapes in the table above (this also applies to the default front-side image at the trigger field: draw it landscape, about 3:2). Apart from the portrait, these images are document-dependent — if the scanned document does not have one (for example no barcode on a passport), the field is simply removed without an image and does not block signing.
Reusing a scan for Live ID signing
When a document combines an ID scan field with a Live ID signature (ID document scan + biometric face check), the signee would normally have to scan the same document twice. Add tink-scanned-id-allow-in-signature[index] to the trigger field to let the completed scan be reused: at signing, the signee is offered their already scanned document and goes straight to the face liveness check.
idScan|tink-scan-id[1]|tink-scanned-id-allow-in-signature[1]
| Attribute | Type | Description |
|---|---|---|
tink-scanned-id-allow-in-signature[index] | modifier | Combine on an ID scan trigger field. Allows the completed scan to be offered for reuse in a Live ID signature within the same signing session. |
- The
[index]is the scan group — the same index as on the trigger field it is combined with. It has no connection to any signature index: an eligible scan is offered for every Live ID signature in the document. - Only fully successful scans qualify (all document checks passed and the portrait was readable). This also holds for
-basictriggers: a fully successful basic scan is reusable, an incomplete-but-accepted one is not. - The biometric face liveness check always runs — reuse only skips re-photographing the document.
- Reuse is offered within the same browser session. If the signee reloads the page, or the stored scan has expired, they simply scan the document again.
Attachments, Sign & Pay, search, and sharing
| Attribute | Type | Description |
|---|---|---|
tink-upload-attachment[index] | triggermanual-entry-forbidden | Triggers a client attachment upload dialog. Always pair with a tink-uploaded-attachmentname[index] field — the trigger alone works, but the uploaded file's name is then not shown anywhere in the document. |
tink-uploaded-attachmentname[index] | auto-populatedmanual-entry-forbidden | Auto-populated after attachment upload. |
tink-sign-and-pay-email[index] | Prefills Sign & Pay email field. | |
tink-search-{label} | Custom searchable field. Replace {label} with the field label you want to search by. | |
tink-search-firstname | Searchable first name field. | |
tink-search-lastname | Searchable last name field. | |
tink-share-sms-phonenumber | Prefills phone number for public link sharing. | |
tink-share-email-emailaddress | Prefills email address for public link sharing. | |
tink-access-document | action | Public link access before finalization. |