Leitfäden

Automatisches Platzieren von Unterschriftenfeldern mit Anker-Tags: Textbasierte Feldplatzierung

Abstrakte Grafik mit dunklem Hintergrund zeigt ein geteiltes Rechteck, gepunktete Linien mit den Bezeichnungen "X=?" und "Y=?" sowie einen nach rechts zeigenden Pfeil, der auf Transformation hinweist.

Wenn Sie schon einmal Signaturfelder positioniert haben, indem Sie x/y-Koordinaten auf einem PDF berechnet haben, wissen Sie, wie mühsam das im großen Maßstab wird. Ändern Sie das Dokumentlayout, und jede Koordinate stimmt nicht mehr. Fügen Sie eine zweite Seite hinzu, und Sie berechnen die Offsets für die Hälfte Ihrer Felder neu.

Anker-Tags beheben das. Betten Sie Textmarker wie {{SIGN_HERE}} oder {{DATE}} direkt in Ihre PDF-Vorlage ein, und Firma.dev erkennt sie automatisch und platziert die richtigen Feldtypen an diesen Stellen. Die Marker werden aus dem endgültigen Dokument entfernt, sodass Unterzeichner sie nie sehen. Ein API-Aufruf, keine Koordinatenrechnerei.

Anker-Tags wurden in v1.11.0 eingeführt und unterstützen alle Feldtypen, flexible Abgleichsregeln und bis zu 100 Tags pro Unterzeichnungsanfrage.

Schnellstart

Der schnellste Weg, Anker-Tags zum Laufen zu bringen: Betten Sie einen Marker in Ihr PDF ein, und erstellen Sie dann eine Unterzeichnungsanfrage mit einem anchor_tags-Array.

Schritt 1: Fügen Sie den Text {{SIGN_HERE}} irgendwo in Ihrem PDF ein, wo das Signaturfeld erscheinen soll. Sie können das in jedem Tool tun, das Ihre Dokumente erzeugt, egal ob es sich um eine Word-Vorlage, eine PDF-Bibliothek oder einen Dokumentenerstellungsdienst handelt.

Schritt 2: Erstellen Sie eine dokumentbasierte Unterzeichnungsanfrage mit der Definition des Anker-Tags:

const response = await fetch(
  'https://api.firma.dev/functions/v1/signing-request-api/signing-requests',
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.FIRMA_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      workspace_id: workspaceId,
      document: documentBase64,
      name: 'NDA - Acme Corp',
      anchor_tags: [
        {
          anchor_string: '{{SIGN_HERE}}',
          type: 'signature',
          recipient_id: 'temp_1',
          required: true
        }
      ],
      recipients: [
        {
          id: 'temp_1',
          first_name: 'Jane',
          last_name: 'Smith',
          email: 'jane@example.com',
          designation: 'Signer',
          order: 1
        }
      ]
    })
  }
);

const signingRequest = await response.json();
const response = await fetch(
  'https://api.firma.dev/functions/v1/signing-request-api/signing-requests',
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.FIRMA_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      workspace_id: workspaceId,
      document: documentBase64,
      name: 'NDA - Acme Corp',
      anchor_tags: [
        {
          anchor_string: '{{SIGN_HERE}}',
          type: 'signature',
          recipient_id: 'temp_1',
          required: true
        }
      ],
      recipients: [
        {
          id: 'temp_1',
          first_name: 'Jane',
          last_name: 'Smith',
          email: 'jane@example.com',
          designation: 'Signer',
          order: 1
        }
      ]
    })
  }
);

const signingRequest = await response.json();
const response = await fetch(
  'https://api.firma.dev/functions/v1/signing-request-api/signing-requests',
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.FIRMA_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      workspace_id: workspaceId,
      document: documentBase64,
      name: 'NDA - Acme Corp',
      anchor_tags: [
        {
          anchor_string: '{{SIGN_HERE}}',
          type: 'signature',
          recipient_id: 'temp_1',
          required: true
        }
      ],
      recipients: [
        {
          id: 'temp_1',
          first_name: 'Jane',
          last_name: 'Smith',
          email: 'jane@example.com',
          designation: 'Signer',
          order: 1
        }
      ]
    })
  }
);

const signingRequest = await response.json();

Firma.dev durchsucht das PDF nach {{SIGN_HERE}}, platziert an dieser Stelle ein Signaturfeld, weist es dem Empfänger zu und entfernt den Markierungstext aus dem Dokument. Das war's.

Beachten Sie, dass Anker-Tags nur bei der Erstellung dokumentbasierter Unterzeichnungsanfragen funktionieren, nicht bei vorlagenbasierten. Sie senden das Roh-PDF und überlassen dem Ankersystem die Feldplatzierung.

Unterstützte Feldtypen

Anker-Tags unterstützen jeden in Firma.dev verfügbaren Feldtyp. Setzen Sie die Eigenschaft type bei jedem Anker-Tag auf einen dieser Werte:

signature für Signaturfelder, initials für Initialenfelder, text für einzeilige Texteingaben, textarea für mehrzeilige Texteingaben, date für Datumsfelder, checkbox für Kontrollkästchen, radio für Optionsfeldgruppen, dropdown für Dropdown-Auswahlen, url für URL-Felder, stamp für Stempelfelder und file für Datei-Upload-Felder.

Jeder Typ rendert das passende Feld-Widget im Unterzeichnungserlebnis. Ein date-Anker-Tag erzeugt einen Datumsauswahldialog, ein dropdown ein Auswahlmenü, und so weiter.

Übereinstimmungs- und Positionierungsoptionen

Das standardmäßige Abgleichsverhalten funktioniert für die meisten Fälle, aber Sie können im Detail anpassen, wie Firma.dev durch Anker erzeugte Felder findet und positioniert.

Groß-/Kleinschreibung: Setzen Sie case_sensitive auf true oder false (Standard ist false). Bei nicht groß-/kleinschreibungssensitivem Abgleich passen {{sign_here}} und {{SIGN_HERE}} beide.

Übereinstimmung ganzer Wörter: Setzen Sie whole_word auf true, um Teilübereinstimmungen zu verhindern. Wenn Ihre Ankerzeichenfolge SIGN ist und whole_word false ist, würde sie auch SIGNATURE oder COSIGN treffen. Wenn Sie es auf true setzen, wird sichergestellt, dass nur das exakte Wort übereinstimmt.

Gezieltes Ansprechen bestimmter Vorkommen: Wenn Ihr PDF dieselbe Ankerzeichenfolge mehrmals enthält, können Sie mit occurrence bestimmte Vorkommen ansprechen. Setzen Sie es auf 1 für die erste Übereinstimmung, 2 für die zweite und so weiter. Lassen Sie es weg oder setzen Sie match_all auf true, um Felder bei jedem Vorkommen zu platzieren.

Offset-Positionierung: Fein abstimmen, wo das Feld relativ zum Ankertext landet, mithilfe von offset_x und offset_y. Sie können Offsets in Prozenten (bezogen auf die Seitendimensionen) oder in Pixeln angeben. Das ist nützlich, wenn Sie möchten, dass das Feld leicht unterhalb oder rechts vom Marker positioniert wird, statt direkt darüber.

Eleganter Umgang mit fehlenden Ankern: Setzen Sie ignore_if_not_present auf true, wenn die Ankerzeichenfolge möglicherweise nicht in jedem Dokument vorhanden ist. Ohne diese Einstellung gibt ein fehlender Anker einen Fehler zurück. Wenn sie aktiviert ist, überspringt Firma.dev dieses Tag stillschweigend und verarbeitet den Rest.

Erweiterte Konfiguration

Hier ist ein vollständigeres Beispiel, das mehrere Anker-Tags mit unterschiedlichen Feldtypen, benutzerdefinierten Abmessungen und Positions-Offsets kombiniert:

const response = await fetch(
  'https://api.firma.dev/functions/v1/signing-request-api/signing-requests',
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.FIRMA_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      workspace_id: workspaceId,
      document: documentBase64,
      name: 'Employment Agreement',
      anchor_tags: [
        {
          anchor_string: '{{EMPLOYEE_SIGNATURE}}',
          type: 'signature',
          recipient_id: 'temp_1',
          required: true,
          width: 30,
          height: 8,
          offset_y: 2
        },
        {
          anchor_string: '{{EMPLOYEE_DATE}}',
          type: 'date',
          recipient_id: 'temp_1',
          required: true
        },
        {
          anchor_string: '{{EMPLOYEE_INITIALS}}',
          type: 'initials',
          recipient_id: 'temp_1',
          required: true,
          match_all: true
        },
        {
          anchor_string: '{{MANAGER_SIGNATURE}}',
          type: 'signature',
          recipient_id: 'temp_2',
          required: true
        },
        {
          anchor_string: '{{BENEFITS_OPT_IN}}',
          type: 'checkbox',
          recipient_id: 'temp_1',
          required: false,
          ignore_if_not_present: true
        }
      ],
      recipients: [
        {
          id: 'temp_1',
          first_name: 'Sarah',
          last_name: 'Chen',
          email: 'sarah@example.com',
          designation: 'Signer',
          order: 1
        },
        {
          id: 'temp_2',
          first_name: 'Mike',
          last_name: 'Torres',
          email: 'mike@example.com',
          designation: 'Signer',
          order: 2
        }
      ]
    })
  }
);
const response = await fetch(
  'https://api.firma.dev/functions/v1/signing-request-api/signing-requests',
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.FIRMA_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      workspace_id: workspaceId,
      document: documentBase64,
      name: 'Employment Agreement',
      anchor_tags: [
        {
          anchor_string: '{{EMPLOYEE_SIGNATURE}}',
          type: 'signature',
          recipient_id: 'temp_1',
          required: true,
          width: 30,
          height: 8,
          offset_y: 2
        },
        {
          anchor_string: '{{EMPLOYEE_DATE}}',
          type: 'date',
          recipient_id: 'temp_1',
          required: true
        },
        {
          anchor_string: '{{EMPLOYEE_INITIALS}}',
          type: 'initials',
          recipient_id: 'temp_1',
          required: true,
          match_all: true
        },
        {
          anchor_string: '{{MANAGER_SIGNATURE}}',
          type: 'signature',
          recipient_id: 'temp_2',
          required: true
        },
        {
          anchor_string: '{{BENEFITS_OPT_IN}}',
          type: 'checkbox',
          recipient_id: 'temp_1',
          required: false,
          ignore_if_not_present: true
        }
      ],
      recipients: [
        {
          id: 'temp_1',
          first_name: 'Sarah',
          last_name: 'Chen',
          email: 'sarah@example.com',
          designation: 'Signer',
          order: 1
        },
        {
          id: 'temp_2',
          first_name: 'Mike',
          last_name: 'Torres',
          email: 'mike@example.com',
          designation: 'Signer',
          order: 2
        }
      ]
    })
  }
);
const response = await fetch(
  'https://api.firma.dev/functions/v1/signing-request-api/signing-requests',
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.FIRMA_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      workspace_id: workspaceId,
      document: documentBase64,
      name: 'Employment Agreement',
      anchor_tags: [
        {
          anchor_string: '{{EMPLOYEE_SIGNATURE}}',
          type: 'signature',
          recipient_id: 'temp_1',
          required: true,
          width: 30,
          height: 8,
          offset_y: 2
        },
        {
          anchor_string: '{{EMPLOYEE_DATE}}',
          type: 'date',
          recipient_id: 'temp_1',
          required: true
        },
        {
          anchor_string: '{{EMPLOYEE_INITIALS}}',
          type: 'initials',
          recipient_id: 'temp_1',
          required: true,
          match_all: true
        },
        {
          anchor_string: '{{MANAGER_SIGNATURE}}',
          type: 'signature',
          recipient_id: 'temp_2',
          required: true
        },
        {
          anchor_string: '{{BENEFITS_OPT_IN}}',
          type: 'checkbox',
          recipient_id: 'temp_1',
          required: false,
          ignore_if_not_present: true
        }
      ],
      recipients: [
        {
          id: 'temp_1',
          first_name: 'Sarah',
          last_name: 'Chen',
          email: 'sarah@example.com',
          designation: 'Signer',
          order: 1
        },
        {
          id: 'temp_2',
          first_name: 'Mike',
          last_name: 'Torres',
          email: 'mike@example.com',
          designation: 'Signer',
          order: 2
        }
      ]
    })
  }
);

Ein paar Dinge sind in diesem Beispiel bemerkenswert. Das {{EMPLOYEE_INITIALS}}-Tag verwendet match_all: true, sodass, wenn das PDF Initialen-Marker auf den Seiten 1, 5 und 12 enthält, alle drei Felder erhalten. Das Kontrollkästchen {{BENEFITS_OPT_IN}} verwendet ignore_if_not_present: true, weil nicht jede Version der Arbeitsvereinbarung diesen Abschnitt enthält. Und offset_y: 2 beim Signaturfeld verschiebt es leicht nach unten von der Position des Ankertexts.

Die Abmessungen (width und height) folgen demselben prozentbasierten Koordinatensystem, das auch von manuell positionierten Feldern verwendet wird. Anker-Tags und manuelle Felder funktionieren zusammen, sodass Sie Anker für den Großteil Ihrer Felder nutzen und für Sonderfälle dennoch manuell koordinatenbasierte Felder in derselben Anfrage hinzufügen können.

Migration von anderen Plattformen

Wenn Sie von einem anderen E-Signatur-Anbieter migrieren, der eine textbasierte Feldplatzierung verwendet, lassen sich die Konzepte direkt übertragen. Die Syntax der Ankerzeichenfolge und die Eigenschaftsnamen unterscheiden sich, aber der zugrunde liegende Mechanismus ist derselbe: einen Marker einbetten, den Feldtyp definieren, die Platzierung der API überlassen.

Von DocuSign Auto-Place: DocuSign verwendet anchorString, anchorXOffset, anchorYOffset und tab-spezifische Typen wie signHereTabs. In Firma.dev wird daraus anchor_string, offset_x, offset_y und das universelle type-Feld. DocuSigns anchorIgnoreIfNotPresent entspricht ignore_if_not_present. DocuSigns anchorCaseSensitive entspricht case_sensitive. Der wichtigste strukturelle Unterschied besteht darin, dass Firma.dev ein einziges anchor_tags-Array mit einer type-Eigenschaft verwendet, anstatt separater Arrays für jeden Tab-Typ.

Von Yousign Smart Anchors: Yousigns Konzept der "Smart Anchors" mit Feldtyperkennung lässt sich direkt übertragen. Die Optionen für Abgleich und Positionierung sind vergleichbar, obwohl die Eigenschaftsnamen der snake_case-Konvention von Firma.dev folgen.

Das Limit liegt bei 100 Anker-Tags pro Unterzeichnungsanfrage, was die meisten Dokument-Workflows bequem abdeckt. Wenn Sie Dokumente verarbeiten, die tatsächlich mehr als 100 Felder benötigen, sollten Sie eine Aufteilung auf mehrere Unterzeichnungsanfragen oder eine Kombination aus Anker-Tags und vorlagenbasierten Felddefinitionen in Betracht ziehen.

API-Referenz

Das anchor_tags-Array ist am Endpunkt zur Erstellung dokumentbasierter Unterzeichnungsanfragen verfügbar (POST /signing-requests). Jedes Element im Array ist ein AnchorTag-Objekt mit ungefähr 25 konfigurierbaren Eigenschaften.

Die wichtigsten Eigenschaften:

anchor_string (erforderlich) ist der Textmarker, nach dem im PDF gesucht wird. type (erforderlich) ist der Feldtyp, der erstellt werden soll. recipient_id weist das Feld einem bestimmten Empfänger anhand seiner ID oder temporären ID zu. required kennzeichnet das Feld als obligatorisch oder optional. offset_x und offset_y passen die Feldposition relativ zur Ankerposition an. width und height legen benutzerdefinierte Feldabmessungen fest. case_sensitive steuert, ob der Abgleich groß-/kleinschreibungssensitiv ist. whole_word verhindert Teilzeichenfolgen-Übereinstimmungen. occurrence zielt auf ein bestimmtes Vorkommen ab, wenn der Anker mehrmals erscheint. match_all platziert Felder bei jedem Vorkommen. ignore_if_not_present überspringt das Tag ohne Fehler, wenn der Ankertext im Dokument nicht gefunden wird.

Das vollständige Schema mit allen Eigenschaften und ihren Typen finden Sie im API-Änderungsprotokoll für v1.11.0.

Nächste Schritte

Anker-Tags lassen sich gut mit programmatischer Dokumentenerstellung kombinieren. Wenn Ihre App Verträge, NDAs oder Onboarding-Dokumente aus Vorlagen generiert, können Sie während der Erzeugung Ankerzeichenfolgen einbetten und Firma.dev die Feldplatzierung bei jeder Anfrage automatisch übernehmen lassen.

Starten Sie kostenlos mit Firma.dev, keine Kreditkarte erforderlich.

  1. Überschrift

Hintergrundbild

Bereit, elektronischen Unterschriften zu Ihrer Anwendung hinzuzufügen?

Kostenlos starten. Keine Kreditkarte erforderlich. Zahlen Sie nur 0,049 € pro Umschlag, wenn Sie bereit sind, live zu gehen.

Hintergrundbild

Bereit, elektronischen Unterschriften zu Ihrer Anwendung hinzuzufügen?

Kostenlos starten. Keine Kreditkarte erforderlich. Zahlen Sie nur 0,049 € pro Umschlag, wenn Sie bereit sind, live zu gehen.

Hintergrundbild

Bereit, elektronischen Unterschriften zu Ihrer Anwendung hinzuzufügen?

Kostenlos starten. Keine Kreditkarte erforderlich. Zahlen Sie nur 0,049 € pro Umschlag, wenn Sie bereit sind, live zu gehen.