Skip to main content

Embedded components

Embedded Signing

Let users review and sign documents directly inside your web app with embedded iframes. Mint one-time signing tokens and enforce signing order sequences.

Last updated:

On this page

Overview

Embedded signing allows your users to sign agreements directly within your application interface without receiving an email invitation link or being redirected to an external domain.

The signer reviews the document, navigates required fields, adopts or draws an e-signature, and submits the completed envelope. All interactions occur inside a secure, sandboxed iframe.

Configuring embedded signers

A signer signs in your app when their deliveryMode is "EMBEDDED". Signers added in the embedded sender widget are EMBEDDED by default. When you create an envelope with POST /api/v1/inkfree/envelopes (see Envelopes) or a draft with POST /api/v1/inkfree/embed/drafts, set it on the signer:

Signer with EMBEDDED delivery mode
"signers": [
  {
    "id": 0,
    "name": "Ana Ruiz",
    "email": "ana@example.com",
    "deliveryMode": "EMBEDDED"
  }
]

Signer eligibility rules

An embedded signer must be a regular signer with a valid email. An embedded signer cannot be a CC recipient or carry the reviewer role in the signers list, cannot be sent a link by SMS, and cannot delegate. (Approvers are set under approval.reviewers instead; see Embedded approvers.) It can have an access code or a one-time code (by email or text): the signer is asked for it inside the iframe before the document opens. You can mix embedded and email signers on one envelope. Bulk send does not support embedded signers. Inkfree also does not return a signing link for an embedded signer in GET /api/v1/inkfree/envelopes/{id}; the only way in is a token from your server.

Mint a signing session token

POST/api/v1/inkfree/embed/sessions

Mint a one-time token for an embedded signer

Requires the X-API-Key header

Request parameters

FieldTypeRequiredDescription
scopestringRequiredMust be "signing".
requestIdstringRequiredThe envelope id. The envelope must be Pending for a signer, or InReview for an approver.
signerEmailstringRequiredThe email of the person who will open the widget, not case sensitive. While the envelope is InReview and the email is an approver's, the token is for that approver; otherwise it must match an EMBEDDED signer.
parentOriginstringRequiredThe origin of the page that will show the widget, registered under Settings > API Keys > Embedded signing origins (for example https://app.example.com).

Example curl command

curl mint signing token
curl -X POST "https://services.softsages.com/core/api/v1/inkfree/embed/sessions" \
  -H "X-API-Key: sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "scope": "signing",
    "requestId": "e4b281f9a0c3451ea9f1388b7d23a105",
    "signerEmail": "ana@example.com",
    "parentOrigin": "https://app.example.com"
  }'

Responses

200Token minted successfully
200 response
{
  "token": "YOUR_ONE_TIME_TOKEN",
  "scope": "signing",
  "requestId": "e4b281f9a0c3451ea9f1388b7d23a105",
  "expiresInSeconds": 300
}

The token works once and expires after 300 seconds. Mint it when your user opens the page, then pass it straight to the browser.

400Missing requestId or signerEmail, an unknown scope, SIGNER_NOT_EMBEDDED, NOT_YOUR_TURN, or the envelope is not in the state this email needs: Pending for a signer, InReview for an approver (REQUEST_COMPLETED, REQUEST_VOIDED, REQUEST_EXPIRED, REQUEST_DECLINED, REQUEST_NOT_READY). For a signer, REQUEST_NOT_READY means the envelope is still waiting for its approvers (InReview) or for its scheduled send time (Scheduled); poll the envelope until it is Pending. An approver's token is minted while the envelope is InReview and does not get REQUEST_NOT_READY for that (see Embedded approvers). A signer who has already signed, or an approver who has already approved, also gets REQUEST_COMPLETED. A rejected envelope gives REQUEST_DECLINED.
401Missing, invalid, revoked or expired API key.
403ORIGIN_NOT_REGISTERED, or your account is scheduled for deletion.
404REQUEST_NOT_FOUND or SIGNER_NOT_FOUND (that email is not a signer on the envelope).

Validation rules & signing order

Inkfree issues a signing token only when all of these are true:

  • Your API key is active and your account is open.
  • parentOrigin is registered under Settings > API Keys > Embedded signing origins.
  • The envelope exists and its status is Pending: approvers, if any, have approved and a scheduled send time has passed (REQUEST_NOT_READY otherwise). An approver's token is the exception, see below.
  • The email belongs to a signer on the envelope with deliveryMode: "EMBEDDED", who is a regular signer (not a CC recipient). While the envelope is InReview, it may instead belong to an EMBEDDED approver under approval.reviewers.
  • The signer has not signed yet. An access code or one-time code on the signer does not stop the token: the signer enters it inside the iframe.
  • Signing order: If the envelope uses a signing order, it must be this signer's turn. A token requested before the earlier signers have signed is refused with NOT_YOUR_TURN.

Handling sequential signing

Subscribe to the signer.signed webhook on your server. When signer 1 has signed, tell your app that signer 2 can start. Mint signer 2's token only at that moment, when signer 2 opens the page, so the 300 seconds are not used up while they wait.

Embedded approvers

Approvers can approve inside your app too, with the same token call and the same widget. An approver is embedded when their deliveryMode is "EMBEDDED"; every approver added in the sender widget or pre-filled on a draft is. Inkfree sends an embedded approver no email.

  1. After sending, the envelope is InReview. Read it and find the approvers under approval.reviewers with status Pending.
  2. Mint a token with scope: "signing" and the approver's email as signerEmail.
  3. Mount the widget with type: "sign". The approver sees the document with Approve and Reject.
  4. The widget sends approval_viewed, then approval_completed or approval_rejected. Confirm on your server: when every approver has approved, the envelope becomes Pending and you can mint tokens for the signers. A rejection makes it Rejected.

An approver gets a token only while they are Pending and it is their turn. An approver who is not embedded gets SIGNER_NOT_EMBEDDED; one who already approved gets REQUEST_COMPLETED; with an approval order, a later approver gets NOT_YOUR_TURN. In an approver group, once one member approves the others are Skipped and get NOT_YOUR_TURN. A decision counts once. An approver with an EMAIL delivery mode (possible on envelopes you create with POST /api/v1/inkfree/envelopes) is emailed as usual.

No approval webhook

There is no webhook when an approver approves or rejects. Use the widget events as a hint and poll GET /api/v1/inkfree/envelopes/{id} to confirm.

Mounting the signing widget

Once your server returns the one-time token, initialize the widget in your web page:

Mount the signing widget
<div id="signing-container" style="width: 100%; height: 750px;"></div>

<script src="https://sign.inkfree.app/embed/inkfree-embed.js"></script>
<script>
  var widget = InkfreeEmbed.mount({
    container: "#signing-container",
    type: "sign",
    token: token,
    theme: {
      primaryColor: "#0a7d5c",
      buttonTextColor: "#ffffff"
    }
  });

  widget.on("sign_completed", function (event) {
    console.log("Document signed by:", event.data.signerRole);
    // Display confirmation screen or redirect
  });

  widget.on("sign_declined", function () {
    console.log("Document was declined by signer");
  });
</script>

A signer who completes the flow produces these events, in order: ready, signer_viewed, sign_started (once, when the signer fills the first field or adopts a signature) and sign_completed. A signer who declines produces sign_declined instead, and the decline reason stays inside Inkfree. After sign_completed or sign_declined the widget stays on a final screen until your page removes it. sign_completed means this signer's signature was accepted; other signers may still be pending. See the SDK reference for every event and error code.

Confirming results on your server

Client-side browser events can fail to dispatch if the user closes their browser immediately after pressing Complete or drops connection. Always confirm completion server-to-server:

  • Webhook notifications: Subscribe to signer.opened, signer.signed, signer.declined, envelope.completed and, where identity verification is used, signer.identity_verified and signer.identity_verification_blocked. There is no webhook when approvers approve or when a scheduled send goes out: poll the envelope for those.
  • Query envelope status: Call GET /api/v1/inkfree/envelopes/{id} to inspect current completion status. The response carries each signer's deliveryMode and status, the approvers under approval.reviewers (with status and deliveryMode; no url for embedded approvers), scheduleTime and the signRequestConfig permissions.
  • Download the signed PDF: Call GET /api/v1/inkfree/envelopes/{id}/document?signed=true to download the legal PDF and certificate. The signing frame offers a download button after signing unless the sender switched off signRequestConfig.allowDocumentDownload (on by default); the file is downloaded in the iframe, so keep the SDK's default sandbox. You can always fetch the signed file from your server instead.

Envelope dispatched webhook note

An envelope whose recipients are all embedded signers (no email signers and no CC recipients) does not emit an envelope.sent webhook, because Inkfree sends no email. Do not wait for that event; use signer.signed and envelope.completed instead.

Email notifications behavior

  • Embedded signers and approvers: Receive no invitation emails, reminder notifications or SMS texts from Inkfree.
  • Email signers and CC recipients: Receive Inkfree's standard email notifications as usual when mixed on the same envelope.
  • Completion notifications: Delivery of final completion emails respects signRequestConfig.sendNotificationOnCompletion. Set this to false if your signers should not receive emails from Inkfree upon envelope completion. The sender is always copied on completion.