Integrator FAQ

Short answers an integrating app, or its AI assistant, can quote — observers, AES by SMS, the SMS allowance, checking phone numbers, languages, signer names, parallel signing, field keys and dates, and how to reach us.

The questions integrating apps send us most, answered in a few lines each, with a link to the page that holds the full contract. If you work with an AI assistant, give it llms.txt (every page with a one-line summary) or llms-full.txt (every page as plain Markdown) instead of pasting pages into a chat.

Which release? Every answer describes the API these docs were published with. Where the behaviour changed recently, the answer names the release and the changelog id (look it up in /api-changelog.json), and says what happened before it: that matters for documents created earlier.

Observers

How do I copy someone, such as a secretariat or a shared mailbox, on a signing request?

Send observer_emails on POST /v1/signing-requests:

{ "observer_emails": ["sekretariat@treuhand-muster.ch"] }
  • An array of address strings: no objects, no names, no language per observer. At most 20 entries, counted before duplicates are removed; each address at most 254 characters.
  • A shared mailbox is fine. An observer is an address, not an account.
  • Addresses are stored lower-cased and without duplicates, and read back as observers in the 201 and on GET /v1/documents/{id}.
  • Send plain ASCII addresses without surrounding spaces. A display-name form ("Office" <office@firm.ch>), a leading or trailing space or a non-ASCII domain answers 400 invalid_request; send an internationalised domain as punycode (xn--…).
  • In a multipart body, send the array as a JSON-encoded string.
  • The request key is observer_emails; observers is only the response key. A request key observers is ignored and named in warnings[] (unknown_field); from 2026-12-31 it answers 400 unknown_field.
  • Only this endpoint takes observers: instantiate and confirm do not. The list cannot be changed after the create.

Reference: Observers.

What does an observer receive, and when?

Two emails at most:

WhenAttachmentsLanguage
Notice ("X is collecting signatures on Y")At the create, when the first signer is sent out. Not sent with send_emails: false.None, and no link to the documentThe locale of that first signer
CompletedWhen the last signer signs and every signer has signed. Never after a decline, a withdrawal or an expiry.The signed PDF and the audit certificateThe locale of the signer whose signature completed the document
  • Observers never receive a signing link, a reminder, a note per signature, or a declined, withdrawn or expired notice.
  • send_emails: false stops the notice, not the "Completed" email.
  • An observer address that is also the completing signer, or the document's sender (the user who created the API key), receives that person's own completion email instead of the observer copy.
  • Treat document.completed, or GET /v1/documents/{id} → status: "signed", as the proof of completion — never the observer email. Both require every signer to have signed.
  • Before the 2026-10-01 release (observer-completed-every-signer), when another signer had declined or been withdrawn, observers could receive "Completed" after the last remaining signature.

Are observers on the audit trail?

  • Not by address: the audit certificate shows no observer addresses.
  • GET /v1/signing-requests/{id} → auditEvents has observer_notified (on the first signer's request) and observer_completed (on the completing signer's request), each with the addresses in meta.observers. It returns the first 50 events of that request.
  • There are no observer webhooks.

AES signatures by SMS

What makes a signature AES, and what backs it?

Give the signer a phone_e164 and require_sms_verification: true. Then:

  • The signer opens their own link and requests a code, which we text to that number; they enter it on the page. We never text a code on our own.
  • Our server refuses the signature (403) until that signer's code is verified. Only our server-side record counts, never the browser.
  • Every signer object of the create response and of GET /v1/signing-requests/{id} reads back signature_level: "AES" and, once the code is entered, sms_verified_at.
  • What the code proves: control of the number you supplied. We do not check that the number belongs to the named person. The verification is stored on the signing request, so any browser that has the link can then sign.
  • The signed PDF is sealed with our platform's PAdES certificate (the signer holds no key) and time-stamped under RFC 3161 when the time-stamp authority answers. The caption under the signature says "Electronic signature + SMS 2FA", and the audit certificate records the verification.
  • We classify this as an advanced electronic signature (AES). Whether AES meets your legal requirement is yours to assess.

Reference: SMS verification, Signer object.

What must hold for an SMS signature to work?

  1. phone_e164 is E.164 (^\+[1-9]\d{7,14}$, e.g. +41791234567) and is sent with require_sms_verification: true. A missing or malformed number answers 400 before anything is created.
  2. It is a mobile number in a country our SMS provider serves. Only the shape is checked at the create; a landline, blocked or unreachable number shows when the signer requests a code, as signing_request.sms_failed.
  3. The workspace has a code left this month for every SMS signer. Otherwise the create answers 402 sms_allowance_exhausted and nothing is created.
  4. The request is still open when the signer asks for the code: a queued, withdrawn, declined, signed or expired request gets none.

Can two signers both confirm by SMS in one parallel request?

Yes; a request takes up to 20 signers. Each signer is a signing request of its own, with its own link, number and code:

  • Give each signer its own role. Fields are assigned by role, so two signers sharing a role would each get the other's fields.
  • Give each signer its own phone_e164. Codes are issued per number: when two signers share one, the code one of them enters makes the other request a new one.
  • Each SMS signer needs at least one code, so a two-signer request needs two codes left.
  • Read Is parallel signing safe? before you rely on two signatures that land within seconds of each other.

How many SMS codes do we get, and what do they cost?

PlanCodes included per month
Free25
Pro50
Branded200
Teams, Enterprise100 per paid seat
  • There is no price per SMS and no price per AES signature: the codes are included in your subscription. API keys come with Enterprise (and legacy Teams) workspaces, so an API integration has 100 codes per paid seat.
  • Every code sent counts, resends included; a refused send does not. The counter resets at 00:00 UTC on the 1st of each month.
  • GET /v1/me → sms_allowance: { monthly, used, remaining, resets_at }.
  • When the allowance is used up, an SMS signer cannot sign until the reset. A request is never downgraded to a signature without SMS.
  • If your firm needs more, email support@wesign.now with your workspace ID and the number of codes you expect per month. We raise the workspace's monthly allowance, included in your subscription; sms_allowance.monthly then shows the plan's codes plus the raise (sms-allowance-raise, since the 2026-10-01 release).

Reference: SMS verification → the monthly allowance.

Can we verify a phone number by SMS before we create a request?

No. It is not offered and not planned. A code can only be requested by the signer, on their own signing link. Check numbers in your own interface before you create the request. After the create:

  • signing_request.sms_failed names the reason (invalid_number, landline, blocked, …) the moment the signer requests a code;
  • an sms_sent without a later sms_verified means our SMS provider accepted the code, not that the phone received it;
  • PATCH /v1/signing-requests/{id} with { "phone_e164": "+41…" } corrects the number while the request is pending, viewed or queued and no code has been verified. It sends nothing; the signer then requests a new code.

Reference: When no SMS arrives.

Languages

Can each signer have their own language?

Yes: locale on each signer, one of en, de, fr, it, nl, es. Only the two-letter code is accepted (de-CH answers 400). A signer without one takes the request's locale, which defaults to en.

Follows the signer's locale: their invitation email, the signing page, reminders, the SMS code (if our SMS provider refuses the language, the number's country decides) and their own completion email.

Does not follow it:

ItemLanguage
The caption under each signatureEnglish, 24-hour clock
The audit certificate from GET /v1/documents/{id}/audit-trailEnglish
The audit certificate attached to completion emailsEnglish (certificate-always-english, since the 2026-10-01 release; before, the language of the signer whose signature completed the document)
The observer noticeThe first signer's locale
The observer "Completed" emailThe completing signer's locale
Error messages of the SMS step on the signing pageEnglish

Values you send, such as names, print exactly as sent; only the labels around them are English.

Reference: Signer object, The SMS itself.

Signer names

Which name fields does a signer take?

  • name (at most 200 characters), or first_name and last_name (at most 100 each). If either first_name or last_name is non-blank, the stored name is "first last" and name is ignored, so send one form, not both. Put a title such as "Dr." where it should print.
  • The stored name prints in the caption under the signature, as the signer's name in the seal and on the audit certificate, and is read back as name on GET /v1/signing-requests/{id} and GET /v1/documents/{id}.
  • Signer objects are strict: an unknown key answers 400 unknown_signer_field, naming it.

Can a signer's company and function print under the signature?

Yes, since the 2026-10-01 release (signer-company-job-title): each signer takes company (at most 200 characters) and job_title (at most 120). Both print in the caption under the signature, Anna Muster · Geschäftsführerin · Muster AG · anna@muster-ag.ch, and on the audit certificate, both the one attached to the completion emails and the one from GET /v1/documents/{id}/audit-trail, labelled "stated by the sender": we do not verify them. Template recipients and confirm take the same two fields. Before that release, both answered 400 unknown_signer_field.

Reference: Company and function.

Parallel signing

Is parallel signing safe?

signing_mode: "parallel", the default, invites every signer at once, and each signs whenever they like.

  • document.completed fires only when every signer has signed. It never fires when a signer declined, was withdrawn or expired.
  • The signatures of one document are sealed one at a time (parallel-signing-chain, since the 2026-10-01 release). A signer who presses Sign while another signature is being sealed waits a few seconds; the signing page retries by itself. The completed PDF carries every signature, however close together they land.
  • Before that release, a completed PDF could lack an earlier signature although every status read signed, whatever the signing_mode: when two signers signed within the same few seconds, or, rarely, when the earlier signed file could not be read at the next signature. Sequential signing (signing_mode: "sequential") avoided only the first case. If a PDF completed before that release lacks a signature, email support@wesign.now with its document_id.
  • Deduplicate document.completed on document_id as well as on event_id: delivery is at least once.

Reference: What "completed" means, Webhooks.

Templates, field keys and dates

What do we have to send to fill a template?

Read the template's contract with GET /v1/templates/{id}, ask your user for every input with required: true, dry-run the call with "validate_only": true, fix what problems lists, offer what missing_optional lists, then send the same body. Step by step: Prepare a fill in your app.

Who fills a text field, we or the signer?

owner on each input of GET /v1/templates/{id} says so:

  • "sender": you send the value. It prints as fixed document content that no signer can change. It is required: true unless the template's author made it optional or gave it a default.
  • "signer": the signer types it while signing. It is never required; you may prefill it, and the signer may change it.

An empty text field never blocks signing. Reference: Who fills a text field.

What does a field key look like?

Lowercase parts of letters, digits and underscores, each starting with a letter, joined by single dots; at most 64 characters: client_name, person.date_of_birth. A dotted key is one flat key of field_values, as in { "person.date_of_birth": "1990-03-15" }, never a nested object.

Standard field names such as person.first_name, company.legal_name or signing.place are keys we suggest for common data. An input that uses one reads standard: true and carries its name in six languages. Custom keys are just as valid.

Reference: Field keys and values, Standard field names.

Which date and time formats do you accept?

  • Dates: YYYY-MM-DD, or day first: DD.MM.YYYY, DD/MM/YYYY, DD-MM-YYYY or DD MM YYYY. Month first is never read: 03/04/1990 is 3 April, and 03/15/1990 answers 422 invalid_date. Stored and echoed as YYYY-MM-DD.
  • Times: 14:30, 14.30 or 2:30 PM. Stored and echoed as 24-hour HH:MM.
  • How a value prints is the template's choice, shown read-only as date_format and time_format on GET /v1/templates/{id}.

Reference: Dates and times.

Asking us

How do we ask something the docs do not answer?

Email support@wesign.now. We reply within one working day. Include:

  • the method and path (POST /v1/signing-requests) and the UTC time of the call;
  • the HTTP status and the code and error of the answer;
  • the ids you have: document_id, signing_request_id, the webhook event_id (header X-WeSign-Event-Id), your Idempotency-Key, and the x-vercel-id response header, which finds the call in our logs;
  • your workspace (GET /v1/me → workspace.slug);
  • what you expected instead.

Never send an API key, a webhook secret or a complete signing link.

Reference: Support.