Placement modes

Where signature fields land on the PDF — anchors, auto-append, explicit. Visualised, with when-to-use guidance. Manual placement is retired.

Pick a mode with the placement form field on POST /v1/signing-requests. The default is anchors with a fall-through to auto_append when no markers are found. Three live modes; every one of them places the fields at API call time, so the request that answers 201 is the request that went out.

manual is retired. A fourth mode — placement="manual": POST the PDF and the signers with no field information, get back a placementUrl, and let a person drop the fields in a hosted editor before anything was sent — was retired on 2026-07-31. It never dispatched a request in production, and the guest placement editor it opened went with the classic-editor retirement. The value is still parsed so that an old request body fails loudly instead of with a generic validation error: POST /v1/signing-requests answers 400 placement_retired before any document is minted (placement_assignee_email is accepted and ignored), and its companion POST /v1/documents — ingest a PDF by URL, get the same placement link — answers 410 placement_retired.

Use one of the three live modes instead: anchors when your generator can drop [[ls:signature:role]] markers into the PDF, explicit when it already knows the coordinates, auto_append when a signature page on the end is enough. Ingest-by-URL lives on as file_url on POST /v1/signing-requests. To keep a person in the loop before the send, stage a template instance with review: true and confirm or discard it — the fields come from the template, so there is nothing left to place.

At a glance

ModeWhen to pick itCaller passes coordinates?Field placement happens at
anchorsYou generated the PDF programmatically (HTML→PDF, LaTeX, Word) with markers.NoAPI call time
auto_appendAd-hoc letters, no structure, just need a signature page on the end.NoAPI call time
explicitYou generated the PDF programmatically AND tracked field positions yourself.YesAPI call time

anchors (default)

Drop a marker like [[ls:signature:tenant]] in your PDF (HTML→PDF, LaTeX, Word, anywhere with a real text layer). We find it, mask the marker with a white rectangle, and place the signature field on top.

1 — UPLOAD
PDF with markers in text layer
Tenant signature:
[[ls:signature:tenant]]
─────────────────
2 — SCAN
pdfjs reads positions; we white-rect each marker
Markers are masked so they don't bleed through under the field.
3 — PLACE
Signature field rendered on top of the masked region
Sign here

Best ergonomics for programmatically generated contracts — HTML→PDF templates, document-assembly tools (Portant, DocAssemble), LaTeX, Pandoc. See Anchor placeholders for the full marker syntax.

Caveats:

  • The PDF's text layer must contain the marker. Scanned-image PDFs don't qualify (run them through OCR first).
  • Markers wrapped across two lines are skipped silently — keep them on one line in the source template.
  • A marker can appear once per page per role for signature / initial / date / name. Duplicates → 400 duplicate_anchor.

auto_append

We add a fresh signature page after your PDF — one block per signer, role-labelled with a signature line and a date line. No coordinates needed from you.

1 — UPLOAD
Original PDF (N pages)
2 — APPEND
We add page N+1 with role-labelled blocks
3 — SIGN
Signers sign on the appended page
TENANT
LANDLORD

Good for ad-hoc letters and quick-and-clean send-and-forget flows where there's no existing signature area. Also the fall-through when anchors mode finds zero markers in the PDF — rather than bouncing your call with no_anchors_found, we silently switch to auto_append so the document still goes out.

Caveats:

  • Adds at least one extra page (more if you have >7 signers).
  • Page size matches A4 regardless of your source PDF's size.

explicit

You pass a fields[] array with one tuple per field, in normalized [0..1] coordinates with a top-left origin:

{
  "placement": "explicit",
  "fields": [
    { "page": 0, "x": 0.10, "y": 0.85, "w": 0.30, "h": 0.06, "kind": "signature", "role": "tenant" },
    { "page": 0, "x": 0.45, "y": 0.85, "w": 0.30, "h": 0.06, "kind": "signature", "role": "landlord" },
    { "page": 0, "x": 0.10, "y": 0.92, "w": 0.15, "h": 0.03, "kind": "date",      "role": "tenant" }
  ]
}
1 — UPLOAD
PDF + JSON coords from your generator
{ "page": 0,
"x": 0.10,
"y": 0.85,
...
2 — VALIDATE
Each role must match a signer; coords clamp to [0..1]
3 — PLACE
Field rendered exactly where you said

Use when you generated the PDF programmatically AND tracked field positions at generation time — most often a templating system with inline metadata about where each field belongs.

Coordinate system:

  • Origin top-left (matches our editor; PDF native is bottom-left but you don't need to think about that).
  • Both x and y are in [0, 1] — fractions of page width / height.
  • kind is signature | initial | date | text.
  • role MUST match a signers[].role value.

Caveats:

  • No safety net — coords land where you say. A bug in your generator puts the signature box on top of the legalese.
  • Page sizes vary; if your generator outputs Letter and the field table assumes A4, fields land where they shouldn't.