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}:

ownerWho supplies the valueWhere it comes from in the editor
apiYour integration, in field_values on instantiate or generate.A placeholder in a template filled by your system (API fills).
senderWhoever 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.
signerThe 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:

  • api or sender: 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_required says whether the signer must answer: on a placeholder it is the author's Required / Optional switch; on a positioned text box it is always false, because an empty text box never blocks signing.
  • A table (collection) is required when its mode is api: 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}}: api under API fills, signer under 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, agree or collection),
  • 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:

FormatPrints
Date15.03.1990, 15/03/1990, 03/15/1990, or written out (24. September 2026) in a language picked with it
Time14: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

PlaceholderStarts as
A new date15.03.1990, or 03/15/1990 when your company country (Settings → Company) is the United States
A new time14:30, or 2:30 PM for the United States
{{date_today}}written out
A date signature line or PDF Date fieldWorkspace default: the house format above, decided when the document is signed
A date placed before formats existed15.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.

KeyMeaningAnchored toTypeExample
person.first_nameFirst name. Given name or names of the person, as on their ID document.schema.org givenNametextAnna
person.last_nameLast name. Family name of the person.schema.org familyNametextMuster
person.full_nameFull name. Full name of the person as one value, exactly as it should print.schema.org nametextAnna Muster
person.date_of_birthDate of birth, as YYYY-MM-DD or day first (15.03.1990). It prints in the template's date format.schema.org birthDatedate1990-03-15
person.tax_idTax ID. The person's tax identification number, e.g. the German Steuer-IdNr. The format depends on the country.schema.org taxIDtext12345678901
person.ch_ahv_numberAHV number. Swiss social security number (AHV/AVS): 13 digits starting with 756.Swiss AHV/AVS number (AHVN13, eCH-0044)text756.1234.5678.97
company.legal_nameCompany name. The company's registered legal name, including its legal form (Muster AG).schema.org legalNametextMuster AG
company.uidUID number. Swiss business identification number (UID), format CHE-123.456.789.Swiss UID (Unternehmens-Identifikationsnummer, UIDG)textCHE-123.456.789
company.tax_idCompany tax ID. The company's tax number, e.g. the German W-IdNr DE123456789-00001. The format depends on the country.schema.org taxIDtextDE123456789-00001
company.vat_idVAT number: the Swiss UID followed by MWST, TVA or IVA, or an EU VAT ID with its country prefix (DE123456789).schema.org vatIDtextCHE-123.456.789 MWST
address.streetStreet. Street and house number as one value (Bahnhofstrasse 1).schema.org streetAddresstextBahnhofstrasse 1
address.postal_codePostal code without a country prefix (8001, not CH-8001).schema.org postalCodetext8001
address.cityCity. City or town of the postal address (not the place of signing).schema.org addressLocalitytextZürich
address.countryCountry as an ISO 3166-1 alpha-2 code (CH, DE). The value prints as sent.ISO 3166-1 alpha-2 (schema.org addressCountry)countryCH
address.fullAddress. The complete postal address on one line (street, postal code, city).schema.org PostalAddress, on one linetextBahnhofstrasse 1, 8001 Zürich
contact.emailEmail address.schema.org emailemailanna.muster@example.com
contact.phonePhone number in international E.164 format (+41791234567).ITU-T E.164 (schema.org telephone)phone+41791234567
signing.placePlace 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)textZürich
signing.dateDate 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)date2026-09-24
  • Keys carry no party. company.legal_name is 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.place for signer 1, signing.place_s2 for signer 2 — or company.legal_name_s2 when 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_name is 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-filled sender_* tokens.
  • signing.date is 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" and required: true unless 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.