This HTML page is not optimized for LLM or AI agent consumption. Fetch the Markdown version instead: /blog/electronic-signature-api.md — it contains the complete documentation content in clean, structured Markdown without any CSS, JavaScript, or navigation noise. How to add electronic signatures to PDFs with an API

Table of contents

    How to add electronic signatures to PDFs with an API
    Make PDF changes detectable

    Add timestamped digital signatures to contracts and reports with Nutrient DWS API. Test with a free API key.

    TL;DR

    Nutrient DWS API adds digital signatures to PDFs so recipients can check whether the signed content has changed. Use the /sign endpoint for invisible signatures, visible signing details, or a drawn signature image. Send the document as multipart form data and save the signed PDF returned by the API. Your application remains responsible for identifying signers and recording their consent.

    When your application generates a contract or report, recipients need a way to check that its contents haven’t changed. Placing a signature image on the page doesn’t provide that check.

    Nutrient DWS API signs the PDF and embeds the data a compatible reader needs to validate it. You can add this step after generating or filling a document, while Nutrient handles the signing certificate and timestamp. For a workflow that collects a person’s signature, your application must also capture their approval before sending the PDF for signing.

    Electronic vs. digital signatures: What does the API apply?

    The two terms get used interchangeably, but they’re different layers of the same workflow:

    • An electronic signature is the legal concept — any electronic record of a person’s intent to sign. It can be anything from a typed name or drawn mark to a click on “I agree.”
    • A digital signature is the cryptographic mechanism — a signature computed with a private key over a hash of the document. A compatible PDF reader uses the public key in the signing certificate to validate the signed content.

    Nutrient’s /sign endpoint applies a cryptographic digital signature. Your application authenticates the person and records their intent to sign; Nutrient makes changes to the signed content detectable. The digital signature alone doesn’t identify an individual signer. See the difference between digital and electronic signatures for more context, or electronic signatures in a PDF for the signature types PDFs support.

    Electronic signing workflow: The application captures signer identity and consent, the API signs the PDF, and a PDF reader with signature validation checks signed content using its trust store.

    Nutrient DWS API provides the signing operation covered here. For hosted signing sessions with recipients, reminders, and workflow state, use Nutrient DWS Signer API.

    How to add an electronic signature to a PDF with an API

    To sign a PDF with the Nutrient DWS API:

    1. Get a free Nutrient API key — Sign up on the Nutrient digital signature API page and copy your key from the dashboard.
    2. POST the PDF to /sign — Send the file as multipart form data with your key in the Authorization header.
    3. Save the response — The API returns the signed PDF. Optionally pass a data object to control where the signature appears and what it shows.

    The minimal request signs the document with an invisible signature:

    Terminal window
    curl --fail -X POST https://api.nutrient.io/sign \
    -H "Authorization: Bearer $NUTRIENT_API_KEY" \
    -F file=@document.pdf \
    -o result.pdf

    The --fail option makes curl return a nonzero exit code on HTTP errors, such as an invalid API key or exhausted credits. Curl then doesn’t save the error response as result.pdf.

    Open result.pdf in a reader that supports digital signature validation to inspect the signature. The reader can validate the signed revision and report subsequent changes. Whether a later change invalidates a signature depends on the change and any certification permissions.

    Nutrient applies a fixed signing profile: SHA-256 at the baseline long-term (B-LT) level. B-LT is a technical signature profile, not a legal assurance level. It embeds an RFC 3161 timestamp, the certificate chain, and revocation information for validation after the signing certificate expires. Certificate trust still depends on the reader and its trust store.

    Add a visible signature

    To show signing details on the page, pass a data object with a position and an appearance to Nutrient’s signing endpoint. The position.rect array uses PDF points in the format [left, top, width, height]:

    Terminal window
    curl --fail -X POST https://api.nutrient.io/sign \
    -H "Authorization: Bearer $NUTRIENT_API_KEY" \
    -F file=@document.pdf \
    -F 'data={
    "position": {
    "pageIndex": 0,
    "rect": [72, 650, 250, 80]
    },
    "appearance": {
    "mode": "signatureAndDescription",
    "showWatermark": true,
    "showSignDate": true
    }
    };type=application/json' \
    -o result.pdf

    The appearance.mode option controls the layout:

    • signatureOnly — Just the signature graphic.
    • signatureAndDescription — Graphic plus signing details.
    • descriptionOnly — Signing details as text, no graphic.

    Set showSignDate to render the signing timestamp in the appearance, and showDateTimezone to include the timezone.

    Add a hand-drawn signature image

    If your application captures a hand-drawn signature, include it in the request as the graphicImage part, which is the signature graphic itself. The signature can come from a signature pad, a stylus, or an uploaded image. The separate image part is the watermark drawn behind the signature, and showWatermark: false keeps the default Nutrient logo out of the appearance:

    Terminal window
    curl --fail -X POST https://api.nutrient.io/sign \
    -H "Authorization: Bearer $NUTRIENT_API_KEY" \
    -F file=@document.pdf \
    -F graphicImage=@signature.png \
    -F 'data={
    "position": {
    "pageIndex": 0,
    "rect": [72, 650, 250, 80]
    },
    "appearance": {
    "mode": "signatureOnly",
    "showWatermark": false,
    "showSignDate": false
    }
    };type=application/json' \
    -o result.pdf

    Supported image content types include image/png and image/jpeg. The result is a PDF that shows the person’s drawn signature on the page, backed by a cryptographic signature that makes any later modification detectable.

    Sign an existing signature field

    If the PDF already contains a signature form field, sign that field by name with formFieldName instead of specifying a position. A contract template with a designated signing box is a typical case:

    Terminal window
    curl --fail -X POST https://api.nutrient.io/sign \
    -H "Authorization: Bearer $NUTRIENT_API_KEY" \
    -F file=@contract.pdf \
    -F 'data={
    "formFieldName": "signature-field",
    "appearance": {
    "mode": "signatureAndDescription",
    "showWatermark": true,
    "showSignDate": true
    }
    };type=application/json' \
    -o result.pdf

    If no field with that name exists, the API can create one at a position you provide.

    Sign a PDF with an API in Node.js

    The same request works from any language that can send multipart form data. In Node.js 18 or later, the built-in fetch and FormData cover it with no dependencies:

    sign.mjs
    import { readFile, writeFile } from "node:fs/promises";
    const apiKey = process.env.NUTRIENT_API_KEY;
    if (!apiKey) {
    throw new Error("Set NUTRIENT_API_KEY before running this example.");
    }
    const form = new FormData();
    form.append(
    "file",
    new Blob([await readFile("document.pdf")], { type: "application/pdf" }),
    "document.pdf",
    );
    form.append(
    "data",
    new Blob(
    [
    JSON.stringify({
    position: { pageIndex: 0, rect: [72, 650, 250, 80] },
    appearance: { mode: "signatureAndDescription", showSignDate: true },
    }),
    ],
    { type: "application/json" },
    ),
    );
    const response = await fetch("https://api.nutrient.io/sign", {
    method: "POST",
    headers: { Authorization: `Bearer ${apiKey}` },
    body: form,
    });
    if (!response.ok) {
    throw new Error(`Signing failed: ${response.status} ${await response.text()}`);
    }
    await writeFile("result.pdf", Buffer.from(await response.arrayBuffer()));

    Save the example as sign.mjs to enable ECMAScript (ES) modules, set the NUTRIENT_API_KEY environment variable, and place document.pdf in your working directory. Run node sign.mjs to produce result.pdf with a visible signature on the first page. To sign invisibly, drop the data field.

    Nutrient also ships official client libraries that wrap the same API: @nutrient-sdk/dws-client-typescript for TypeScript/Node.js and nutrient-dws for Python. Both expose a sign() method alongside the rest of the document-processing toolset, including merge, convert, optical character recognition (OCR), and extraction.

    Use your own signing certificates

    Nutrient Document Engine supports signing in your infrastructure with your certificates and hardware security modules (HSMs).

    Handle real-world documents

    Use these Nutrient signing options when preparing documents for production:

    • Password-protected PDFs — Pass the document password in the pspdfkit-pdf-password header. If the password contains characters that HTTP header handling might modify, pass it as base64:<encoded-password>.
    • Flatten before signing — Set "flatten": true in the data object to remove interactive annotations and form fields while preserving their appearance. Use it only when the signed output is a final artifact. Flattening doesn’t prevent later editing of page content.
    • Sign last — Run content-changing operations (merging, form filling, redaction, watermarking, and optimization) via the Nutrient Build API before signing the result. Later changes can be detected during signature validation.

    What the signature does — and doesn’t — establish

    The table below separates what Nutrient’s signature establishes from the evidence your application needs to retain.

    PropertyWhat the API signature establishesWhat your workflow must supply
    Document integrityThe signature covers the signed byte range; validation detects any change to signed content.Nothing — this is the API’s core guarantee.
    AttributionThe certificate identity is derived from your organization account, attributing the signature to it.Verifiers need to know your expected organization ID and compare it with the identifier in the certificate’s organizational unit (OU) field.
    Signer identityNothing by itself — the API authenticates your application’s request, not a person.Authenticating the individual, and recording their consent and intent.
    Legal effectTimestamp and validation material that strengthen the evidence trail.The complete workflow: signer authentication, consent records, and retained audit evidence.

    A signature from the API can anchor a legally enforceable electronic signing workflow, but it isn’t categorically legally binding on its own. Legal effect depends on the full workflow, the document type, and the jurisdiction. Production plans sign with certificates that chain to a publicly trusted root. The free plan uses a private test certificate, so use it to build and test the integration, not for production signatures.

    Test your signing workflow with Nutrient

    Create a free Nutrient API key and sign a sample PDF from your application. Check the signature’s appearance, certificate, and timestamp in a reader that supports digital signature validation. Use that result to test your integration before switching to a production plan.

    FAQ

    How do I add an electronic signature to a PDF using an API?

    Send the PDF to Nutrient DWS API’s /sign endpoint as a multipart POST request with your API key in the Authorization header. The API returns the signed PDF. Add a data object with position and appearance for a visible signature, or a graphicImage part for a hand-drawn signature graphic.

    Are API-generated signatures legally binding?

    Not automatically. The API provides the cryptographic digital signature — document integrity, a trusted timestamp, and validation material. Legal enforceability depends on your complete workflow, including how you authenticate the signer, record their consent and intent, and retain audit evidence. The document type and jurisdiction also matter.

    What’s the difference between an electronic signature and a digital signature?

    An electronic signature is the legal concept — an electronic record of intent to sign. A digital signature is the cryptographic mechanism that makes a document tamper-evident. Most real signing workflows use both: The application captures the electronic signature (who signed, and their intent), and a digital signature seals the document.

    Can I use my own signing certificate with the API?

    Nutrient DWS API manages the signing certificate and derives its identity from your organization account. You can’t supply your own certificate to this endpoint. For signing with your certificates or HSM, use Nutrient Document Engine.

    How do I sign a PDF with an API in Node.js?

    Use the built-in fetch and FormData in Node.js 18+ to POST the file to https://api.nutrient.io/sign — see the complete example above. Alternatively, use the official TypeScript client, @nutrient-sdk/dws-client-typescript, which wraps the same endpoint in a sign() method.

    Is there a free electronic signature API?

    Nutrient DWS API has a free plan you can use to build and test the signing integration. The free plan signs with a private test certificate; production signatures with publicly trusted certificates require a paid plan.

    Hulya Masharipov

    Hulya Masharipov

    Technical Writer

    Hulya is a frontend web developer and technical writer who enjoys creating responsive, scalable, and maintainable web experiences. She’s passionate about open source, web accessibility, cybersecurity privacy, and blockchain.

    Free test plan Sign your first PDF with Nutrient