# Text tags

> Put the fields in the document. Tag syntax, sizing, validation, and how to check a file before you send it.

Source: https://signclad.com/docs/text-tags/

Text tags let a document carry its own fields. Write a tag into the Word or PDF source, set `text_tags: true` on the create, and Signclad turns each tag into a field. The same syntax works for documents and templates.

This is the right approach when documents are generated by another system — a loan origination platform, a CRM, a mail-merge — because nobody has to open an editor and place boxes.

## Syntax

```
[type|modifier|modifier|...]
```

The first segment is the field type. The rest are modifiers in any order.

```
[sig|req|signer1]
[init|signer1]
[date|signer1|fmt:MM/DD/YYYY|lock]
[text|signer1|id:borrower_full_name|req]
[text|signer1|id:borrower_email|validate:email]
[check|signer1|id:consent_ach|req]
[drop|signer1|id:entity_type|opts:LLC,Corp,Individual]
[auto|signer1|value:name]
```

| Type | Field |
|---|---|
| `sig` | Signature |
| `init` | Initials |
| `date` | Date signed |
| `text` | Text |
| `check` | Checkbox |
| `drop` | Dropdown |
| `sel` | Select |
| `auto` | Autofill |

| Modifier | Meaning |
|---|---|
| `signerN` | Which recipient the field belongs to, by position. |
| `req` | Required. `opt` is the opposite, and is the default for a bracket tag. |
| `id:` | Sets the field's `api_id`. Give every field you intend to prefill or read one. |
| `label:`, `name:` | The label shown to the signer, and the internal name shown in the builder. |
| `lock` | On a date field, fills at signing and refuses a supplied value. |
| `fmt:` | Date format: `MM/DD/YYYY`, `DD/MM/YYYY`, `YYYY/MM/DD`, `Month DD YYYY`, or `MM/DD/YYYY hh:mm:ss a`. |
| `formula:` | A date formula, for example `sent_date + 10 days`. |
| `validate:` | `email`, `number`, `letters`, `phone`, `zip`, `ssn`, `age`, `alphanumeric`, `routing`, `bank_account`, or a regular expression. Anything unrecognised becomes a `custom` validation with that pattern. |
| `opts:`, `default:`, `other` | Options for `drop` and `sel`, which one is preselected, and whether the signer may type their own. |
| `value:` (or `prefill:`) | A prefilled value. On an `auto` tag it picks the source instead: `first_name`, `last_name`, `name`, `email`, `company`, `phone`, `title`, or `date_signed`. |
| `w:`, `h:` | Override the size the tag box would have given, in units. |
| `fixed` | Keep the drawn width instead of growing the box to fit the text. |

An `auto` tag without a supported `value:` is not a field at all — it is left in the document as literal text. So is any tag whose first segment is not a known type. Nothing rejects the document for it.

## Legacy compatibility

Signclad also accepts the positional `{{...}}` format used by imported templates, so they can move over without being rewritten:

```
{{signature:1:y:Please sign::borrower_signature:200:50}}
{{text:2:y:Full name::borrower_name:160:24:letters:y}}
{{date:1:y:Signed::signed_on:110:24:y:mm/dd/yyyy:sent_date + 10 days}}
{{af_e:2:n:::borrower_email}}
```

The positions are field type, signer number, required (`y` or `n`), label, prefill value, API ID, width, and height. Text fields may then specify validation and fixed width. Date fields may specify locked signing date, date format, and formula. Blank positions keep their defaults.

All legacy field names and short autofill aliases are accepted. Variables also work: define one with `{{set=a1:text:1:y:Age? }}` and reuse it with `{{a1}}`.

Use Signclad's bracket syntax for new templates. It names each modifier, so adding or removing one does not require a run of positional blanks.

## Sizing, and a deliberate improvement

The field takes the size of the tag box as it appears in the document, measured in **units** — CSS pixels at 96 DPI, one unit being 0.75 PDF points. Where a tag box is smaller than a field of that type can usefully be, Signclad applies a **minimum size for the type** instead of producing an unusably small field, anchored at the tag's top-left so the field grows right and down from where you put it.

| Type | Minimum |
|---|---|
| `sig` | 120 × 40 |
| `init` | 60 × 40 |
| `date` | 110 × 24 |
| `text` | 100 × 20 |
| `check` | 16 × 16 |
| anything else | 100 × 20 |

Practical guidance: give a signature tag roughly 180 × 44 units and a date tag roughly 120 × 24, and you will get exactly what you drew. `w:` and `h:` override the measured box outright, and the floor still applies afterwards. Height is capped at 200 units for `sig` and `init`, 74 for everything else.

## Making tags invisible

Tags remain part of the rendered page: nothing removes them. Colour the tag text to match its background in the source — white on white is the usual case — and it disappears from the output while still occupying exactly the space that sets the field's size. A small run inside a table cell is a reliable way to position a tag precisely.

Do that in the DOCX or the PDF before you upload. Signclad does not recolour tags for you.

## Checking before you send

There is no HTTP endpoint for this. The check lives in the MCP server as `validate_text_tags`, which reads a local DOCX, text-based PDF, or plain text — or a snippet of tag text — and parses it with the same syntax the API uses. Nothing is uploaded, so it works on a document you have not sent and on a workspace you have not connected. See [MCP](https://signclad.com/docs/mcp/).

It reports every tag it found, the field each one produces, the signers and `api_id`s the document expects, and a list of problems with the line each is on: an unknown field type, an unsupported modifier, a `signerN` below 1, an unknown validation or date format, a `drop` or `sel` with no options, a height over the maximum, a reference to a variable never defined with `set=`, a prefill on a signature field, and a duplicate `api_id`.

Two things it cannot tell you, because both need the rendered page: the field's page and coordinates, and whether a tag is large enough to avoid the minimum for its type. A scanned PDF has no text layer at all, and it says so plainly rather than reporting no tags.

One difference between the checker and the API is worth knowing. The checker calls a repeated `api_id` an error; the API does not fail on one — it keeps the first and suffixes the rest `_2`, `_3`. That is forgiving, and it also means a copy-pasted tag silently produces a field you cannot address by the name you expected.

## Combining tags with explicit fields

You can do both, and the explicit field wins. `fields` you pass are written during the create request; tag fields are imported afterwards, once the file has been converted and its text extracted, and a tag whose `api_id` already exists on the document is skipped. So naming a field in `fields` with the same `api_id` as a tag overrides that tag's position without editing the source document.

That import is also why fields from tags are not in the create response. They appear on the next `GET`, with the page count.

## Related

- [Creating a document](https://signclad.com/docs/creating-a-document/)
- [Templates and create-from-template](https://signclad.com/docs/templates/)
