Fields & placeholders
The two ways content gets filled — positioned fields and inline merge placeholders — who fills each value, line-item collections and standard field names.
A template carries two distinct kinds of variable. Knowing which is which is the key to automating contracts cleanly.
The two kinds
Fields are boxes at fixed x/y/w/h coordinates on the rendered PDF,
placed visually in the editor — a signature, an initial, a date, or a short
text. A signer fills them, except a text box whose author set it to
Filled by: Sender / API: its value is fixed before anyone signs.
Placeholders are inline {{tokens}} woven into the body text. They're
merge variables: at instantiate time the literal {{token}} is replaced with
a value. No coordinates — they reflow with the text.
Both share one field_key namespace (lowercase snake_case, optionally
in parts joined by dots — client_name, person.date_of_birth). The
same field_values map you send at instantiate fills a placeholder and any
positioned text field with the same key.
Who fills a value
Every value a template takes — a placeholder or a positioned text box — has
an owner, published as owner on
GET /v1/templates/{id}:
owner | Who supplies the value | Where it comes from in the editor |
|---|---|---|
api | Your integration, in field_values on instantiate or generate. | A placeholder in a template filled by your system (API fills). |
sender | Whoever sends the document. An API call stands in for them. | A PDF text box set to Filled by: Sender / API, and the platform's date_today and sender_* tokens. |
signer | The recipient, while signing. You may pre-fill it. | A placeholder in a template filled by people (People fill), and a PDF text box set to Filled by: Signer (every box until the author chooses). |
How required is derived
required: true means your call fails without the value
(422 template_input_invalid, problem code field_required). The platform
derives it once, from the owner:
apiorsender: required, unless it is a platform token (auto_filled: true, below), unless the author made it optional, and — for a positioned text box — unless it has a default value, which then prints.signer: never required of you.signer_requiredsays whether the signer must answer: on a placeholder it is the author's Required / Optional switch; on a positioned text box it is alwaysfalse, because an empty text box never blocks signing.- A table (collection) is required when its
modeisapi: it has no authored rows to fall back on. - An input inside a conditional section that your values hide is not required on that call; it will never be rendered.
Read the published required; never re-derive it from owner.
Which fields you must supply
spells out what that means for a call.
Platform tokens (auto_filled)
The platform fills these placeholders itself, so they come back with
auto_filled: true and required: false:
date_today;- the letterhead tokens
sender_name,sender_company,sender_street,sender_zip,sender_city,sender_country; - the recipient tokens
recipient_name,recipient_email,recipient_company,first_name,last_name, and their per-signer copies (recipient_name_s2).
A value you send for one wins over the platform's. When each is filled on a direct send and on a staged one is in Which fields you must supply.
Writing a rich-text template for the API
- Choose who fills the values. A new template asks Who fills it in?: Filled by your system (the API) or Filled by people (a form). While the template is a draft, the editor's toolbar switches between People fill and API fills.
- The choice sets each placeholder's owner when you insert it or type its
{{key}}:apiunder API fills,signerunder People fill. Platform tokens keep their own owner. Switching changes only the placeholders you add afterwards: one already in the body keeps its owner, so delete it and insert it again to change it. - Insert placeholder offers the platform tokens, the entries of your field registry whose Source matches the choice, and any valid key you type.
- An API placeholder has no question, answer type or Required switch in the field inspector: its type comes from your field registry or its standard name, and it is required. A date or time placeholder still gets its print format there.
- Give every signer a signature line. A call must name a recipient for
every slot that has a line or box (
400 missing_recipients), and every recipient needs a signature or initials on their slot (422 signer_without_signature). See Several signers. - Present stays off while the template has an API placeholder or table: the public form cannot fill them.
- Lock the template. Its contract is then fixed for that version, and
GET /v1/templates/{id}serves it.
source (legacy)
Every entry of GET /v1/templates/{id} and GET /v1/fields also carries
source, from the older split between the lead form and the API. On a
template's input it is the Source of the matching
field registry entry — "lead" when
there is none — and "api" on a table. It does not say who fills the
value: a PDF box set to Filled by: Sender / API usually reads
"source": "lead". Read owner and required instead.
API objects (line-item collections)
Some data is a list, not a single value — order lines, deliverables, services rendered. A collection is an inline table whose row is repeated once per item.
In field_values, a collection key maps to an array of row objects; every
other key maps to a string:
POST https://api.wesign.now/v1/templates/{id}/instantiate
Authorization: Bearer wsk_live_…
Content-Type: application/json
{
"recipients": [
{ "slot": 1, "email": "buyer@acme.ch", "name": "Sara Buyer" }
],
"field_values": {
"client_name": "Acme AG",
"order_total": "CHF 1,240.00",
"line_items": [
{ "description": "Design sprint", "qty": "1", "unit_price": "900.00", "amount": "900.00" },
{ "description": "Hosting (yr)", "qty": "1", "unit_price": "340.00", "amount": "340.00" }
]
}
}The column keys in each row object (description, qty, …) match the column
keys defined on the table in the template.
Reusable definitions & preview examples
Admins curate a workspace catalog of fields and API objects in Settings → API → Fields & API objects. Each definition carries:
- a key + label + type (
text,multiline,email,phone,number,currency,date,time,enum,boolean,agreeorcollection), - a Source — Lead (Present form) or API (instantiate) — which decides whether Insert placeholder offers it in templates filled by people or in templates filled by your system,
- an example value (and per-column examples for collections).
Authors then insert known tokens from the editor's placeholder menu instead of
retyping them, and the example values render in the template preview — so a
draft shows “Acme AG” and real line items rather than {{client_name}}.
A definition that a template already uses is locked: its key can't be renamed or deleted until it's removed from the template, so live integrations never break.
Discover a workspace's whole registry — keys, types, enum options, examples,
max lengths — with GET https://api.wesign.now/v1/fields, or one template's
input schema with GET /v1/templates/{id}.
Enum fields are validated
If a definition has type enum, its value is checked against the allowed
options — either the display label ("Gold") or the underlying key ("gold")
is accepted. An out-of-vocabulary value comes back with every other problem in
the same 422 template_input_invalid response, as one entry of problems[]
with code: "invalid_enum" and the allowed list:
{
"error": "1 problem with this request.",
"code": "template_input_invalid",
"problems": [
{
"field": "plan_tier",
"label": "Plan tier",
"code": "invalid_enum",
"message": "Invalid value \"Platinum\" for \"Plan tier\". Allowed: Gold, Silver, Bronze.",
"allowed": ["Gold", "Silver", "Bronze"]
}
],
"warnings": []
}The full list of problem codes is in Templates → Validation.
Dates and times
Choosing how a date or time prints
The author picks the format on each date or time placeholder:
| Format | Prints |
|---|---|
| Date | 15.03.1990, 15/03/1990, 03/15/1990, or written out (24. September 2026) in a language picked with it |
| Time | 14:30 or 2:30 PM |
- Rich-text templates: click a date or time placeholder, or
{{date_today}}, and choose the format in the field inspector. A written-out date also gets a language. - Date signature line (the day that signer signs): the line's toolbar has a format menu. Workspace default follows your company country when the document is signed. A written-out line is spelled in the line's own language.
- PDF documents and PDF templates: select a Date field, or a text field whose key is a date or time answer, and choose the format in the field inspector (on a phone: Field settings).
Defaults
| Placeholder | Starts as |
|---|---|
| A new date | 15.03.1990, or 03/15/1990 when your company country (Settings → Company) is the United States |
| A new time | 14:30, or 2:30 PM for the United States |
{{date_today}} | written out |
| A date signature line or PDF Date field | Workspace default: the house format above, decided when the document is signed |
| A date placed before formats existed | 15.03.1990; {{date_today}} stays written out |
A written-out date is spelled in the language recorded with it (the author's language when the placeholder was placed), else the document's language (that of its signature lines), else the language of the request, else English.
{{date_today}} is the day the document was created. The day a signer signs
belongs on a date signature line or a PDF Date field.
What signers and form visitors see
- A date is typed into three boxes in the placeholder's order:
MM / DD / YYYY when it prints
03/15/1990, otherwise DD / MM / YYYY. - A time is typed into HH : MM boxes, plus an AM / PM switch when it
prints
2:30 PM. An hour from 1 to 12 is not accepted there until AM or PM is picked; it is never assumed to be morning. - The date field on the signing page shows the date exactly as it will be stamped.
The format only changes how a value is printed. What is accepted and stored
never depends on it: forms and the API take 15.03.1990 or 1990-03-15, and
14:30 or 2:30 PM; values are stored and returned as YYYY-MM-DD and
24-hour HH:MM. See
Templates → how dates and times print.
The template preview fills a date or time placeholder that has no example
value with a sample (15.03.1990, 14:30) in its format, and
{{date_today}} with today. The audit trail and the caption under each
signature stay in English with a 24-hour clock whatever the formats.
Standard field names
Keys are yours to choose, but the platform suggests standard names for the data contracts ask for most. Each is anchored to a vocabulary integrators already know, so its meaning is not ours to invent. When your templates use them, an app maps its data to these keys once and fills every such template.
| Key | Meaning | Anchored to | Type | Example |
|---|---|---|---|---|
person.first_name | First name. Given name or names of the person, as on their ID document. | schema.org givenName | text | Anna |
person.last_name | Last name. Family name of the person. | schema.org familyName | text | Muster |
person.full_name | Full name. Full name of the person as one value, exactly as it should print. | schema.org name | text | Anna Muster |
person.date_of_birth | Date of birth, as YYYY-MM-DD or day first (15.03.1990). It prints in the template's date format. | schema.org birthDate | date | 1990-03-15 |
person.tax_id | Tax ID. The person's tax identification number, e.g. the German Steuer-IdNr. The format depends on the country. | schema.org taxID | text | 12345678901 |
person.ch_ahv_number | AHV number. Swiss social security number (AHV/AVS): 13 digits starting with 756. | Swiss AHV/AVS number (AHVN13, eCH-0044) | text | 756.1234.5678.97 |
company.legal_name | Company name. The company's registered legal name, including its legal form (Muster AG). | schema.org legalName | text | Muster AG |
company.uid | UID number. Swiss business identification number (UID), format CHE-123.456.789. | Swiss UID (Unternehmens-Identifikationsnummer, UIDG) | text | CHE-123.456.789 |
company.tax_id | Company tax ID. The company's tax number, e.g. the German W-IdNr DE123456789-00001. The format depends on the country. | schema.org taxID | text | DE123456789-00001 |
company.vat_id | VAT number: the Swiss UID followed by MWST, TVA or IVA, or an EU VAT ID with its country prefix (DE123456789). | schema.org vatID | text | CHE-123.456.789 MWST |
address.street | Street. Street and house number as one value (Bahnhofstrasse 1). | schema.org streetAddress | text | Bahnhofstrasse 1 |
address.postal_code | Postal code without a country prefix (8001, not CH-8001). | schema.org postalCode | text | 8001 |
address.city | City. City or town of the postal address (not the place of signing). | schema.org addressLocality | text | Zürich |
address.country | Country as an ISO 3166-1 alpha-2 code (CH, DE). The value prints as sent. | ISO 3166-1 alpha-2 (schema.org addressCountry) | country | CH |
address.full | Address. The complete postal address on one line (street, postal code, city). | schema.org PostalAddress, on one line | text | Bahnhofstrasse 1, 8001 Zürich |
contact.email | Email address. | schema.org email | email | anna.muster@example.com |
contact.phone | Phone number in international E.164 format (+41791234567). | ITU-T E.164 (schema.org telephone) | phone | +41791234567 |
signing.place | Place of signing. Place where this signer signs, usually a city. For signer 2: signing.place_s2. | ETSI EN 319 142-1 signer location (PAdES /Location) | text | Zürich |
signing.date | Date of signing. The day this signer signs. The platform stamps it at signing; nobody supplies it. | ETSI EN 319 142-1 signing time (PAdES /M) | date | 2026-09-24 |
- Keys carry no party.
company.legal_nameis a company, not "the client" or "the supplier": where it sits in the document says whose it is. - A per-signer copy is for a value that differs per signer. Add the
suffix of the signer's slot:
signing.placefor signer 1,signing.place_s2for signer 2 — orcompany.legal_name_s2when signer 2 represents another company. A copy is standard too and carries its base entry's metadata. - A shared fact is one field. When both signers sign for the same company,
company.legal_nameis one Sender / API box, placed once: every signer sees it, whichever slot carries it (see Who fills a text field). Your own company stays the auto-filledsender_*tokens. signing.dateis a stamp: the name of a Date field, which the platform stamps with the day that signer signs. The editor offers it only when you name a Date field, never as a value anyone fills in.- National identifiers carry the country (
person.ch_ahv_number). - A suggestion, never a rule. A custom key (
mandate_number) is just as valid. Nothing is refused, renamed or downgraded for being custom.
How a standard key behaves over the API. GET /v1/templates/{id}
publishes it with standard: true, its name in all six UI languages
(labels), the example above (unless your field registry has its own) and a
one-sentence English description. GET /v1/fields marks registry entries
the same way (standard, labels); the example and description there stay
your registry's own. Six keys also carry a pattern, a regular expression
your own form may use to hint at the usual shape. It is a hint: the API never
checks a value against it.
person.ch_ahv_number:^756\.?\d{4}\.?\d{4}\.?\d{2}$company.uid:^CHE-?\d{3}\.?\d{3}\.?\d{3}$company.vat_id:^(?:CHE-?\d{3}\.?\d{3}\.?\d{3}(?: ?(?:MWST|TVA|IVA))?|[A-Z]{2}[A-Z0-9]{2,12})$address.country:^[A-Z]{2}$contact.email:^[^\s@]+@[^\s@]+\.[^\s@]+$contact.phone:^\+[1-9](?: ?\d){1,14}$(E.164, plus the spaces of the grouped form the API echoes)
The Type column applies only when neither the template nor your field
registry gives the field a type. Then a date is checked and stored like any
date field (15.03.1990 → 1990-03-15) and an email must be an email
address. A phone is never refused; a number we recognise is stored in spaced
international form (+41 79 123 45 67). A country is free text.
A field that is unlabelled everywhere reads the standard name as its label,
in the document's language when the template records one, else in English.
Naming fields in the app. Wherever you name a key (the field inspector
of a PDF template, a template's field list, the placeholder menu,
Settings → API), the key box suggests these names as you type, matching
their names in all six languages (geburt finds person.date_of_birth).
Each suggestion shows a Standard badge and, on hover, what it is anchored
to; under the box, a standard name says what it means in your language.
Picking one fills in the label in your language, unless you already wrote
one. A field the editor named for you (text_1) lists the standard names as
soon as you click into its box, and a name of your own that matches none of
them is matched by the field's label instead (a box labelled Firma suggests
company.legal_name). In a template, the inspector's auto-fill choices write
the standard names too (Full name → person.full_name).
Who fills a text field (PDF templates)
Each text box you place on a PDF template says who fills it:
- Sender / API: you (or your integration) supply the value when you send.
It is fixed document content: every signer sees it as text from their
first view of the document, in any signing order and whichever signer's
slot carries the box, and no signer can change it. Each seal prints it
exactly once. Over the API it is
owner: "sender"andrequired: trueunless you mark it optional or give it a default value. - Signer: the signer of the box's slot types it while signing, and may
leave it empty. Your integration may pre-fill it (
owner: "signer", never required); the signer can still change what you sent.
A box's slot decides only which signer's field set carries it. Place a fact
every signer shares once; add a per-signer copy (signing.place_s2) only for
a value that differs per signer — see
Standard field names.
Set it in the field inspector while you edit the template (on a phone:
Field settings) or in the template's field list while it is a draft. A
Sender / API field has its own Optional for the sender switch; a default
value makes it optional too (the default prints when nothing is sent), so the
switch then shows on and locked, and the field list reads Optional
(default). A caller that sends "" for such a box prints it blank instead of
the default; a caller that omits the key gets the default. A Signer field
never blocks signing, so it has no Required switch. When you send from
the app, Quick send asks you for the Sender / API values, Batch send
maps them to columns of your file, and the editor does not send while a
required one is empty.
A Present (form) link has no sending step: a Sender / API box prints its default there, and one without a default becomes a box the visitor fills in.
Every existing text box is Signer until you change it, so no template's API
contract moves on its own. Changing the choice on a locked template takes an
unlock and a new version; callers pinned to an older version keep the
contract they were built against.
A Signer box named person.full_name, person.first_name,
person.last_name, contact.email or company.legal_name (or a per-signer
copy such as person.first_name_s2) opens with that signer's own details
while it is empty (nothing sent for it, no default), taken from the request
and your address book. It works like the auto-fill choices in the field
inspector, and the signer can change it. A text or name anchor marker on
POST /v1/signing-requests whose third part is one of these keys
([[ls:text:tenant:person.full_name]]) works the same way — see
Anchor placeholders.
Which should I use?
- Need a signature, initials, or a value a person types as they sign → field (Filled by: Signer).
- A value you know before sending that must sit at a fixed spot on a PDF → text field (Filled by: Sender / API).
- Need to merge a value you already have into the prose → placeholder in a
template filled by your system (
owner: "api"). - Collecting from a person on a form or a shared link → placeholder in a
template filled by people (
owner: "signer") + Present. - A repeating list (invoice lines, deliverables) → collection.
