---
title: "Sign PDFs in WordPress"
url: "https://docs.signnow.com/docs/sign-pdfs-in-wordpress"
type: "page"
section: "Documentation"
slug: "sign-pdfs-in-wordpress"
---

# Sign PDFs in WordPress

# Sign PDFs in WordPress

This guide shows how to add document signing to a WordPress page using the SignNow API. Signers complete and sign the document right on your site, without registering, waiting for an email, or leaving the page, so the workflow stays inside your brand.

You will build a document group, save it as a reusable document group template, create a fresh document group from that template for each signing session, generate an embedded signing link, and paste that link into a WordPress page. The whole flow relies on the SignNow REST API and the built in WordPress Custom HTML block, so no extra plugin is required.

The walkthrough is built around **document groups** and **document group templates**. A document group lets you send one or several documents to signers as a single package. A group can contain a single document, so this approach works equally well for one PDF or many.

Saving the prepared group as a template lets you reuse it: instead of rebuilding fields for every visitor, you create a new document group from the template on demand. Each signer gets an isolated copy, while the template stays untouched as the master version. This is the practical pattern for a WordPress page where many visitors sign the same document.

## How it works

The flow splits into two parts. You do the **one-time setup** once, then repeat the **per signing session** steps for every visitor who signs.

One-time setup:

1. Create a document group from one or more uploaded documents.
2. Add fields (signature, text, and so on) to the documents in the group.
3. Save the document group as a document group template.

Per signing session:

4. Create a new document group from the template for the signing session.
5. Create an embedded signing invite for that document group.
6. Generate an embedded signing link for the recipient.
7. Add the link to a WordPress page inside a Custom HTML block.

## Before you begin

Make sure that:

- you have a SignNow account with API access and valid authorization credentials (see [Authentication](/docs/authentication))
- you have already [uploaded the documents](/docs/document/operations/upload-document) you want signed and have their document IDs
- you are the owner of those documents
- the documents are not in _pending_ or _signed_ status

> All requests below use the base URL `https://api.signnow.com` and must be authorized. The examples use an access token (`Authorization: Bearer {{access_token}}`), but you can authorize with an API key instead. See [Authentication](/docs/authentication) for the available methods.

## One-time setup

Prepare the documents, fields, and template once. You repeat these three steps only when the documents or fields change.

> You can also create the document group template in the SignNow UI instead of through **Step 1** to **Step 3**. If you already have a template, skip ahead to [Per signing session](/docs/sign-pdfs-in-wordpress#per-signing-session) and start from **Step 4**. To get its ID, call [Get doc group templates](/docs/document-group-template/operations/get-user-documentgroup-templates), or copy it from the UI: open **My Templates**, open the template, and take the ID from the page URL.

### Step 1. Create a document group

Combine your documents into a single group with [Create document group](/docs/document-group/operations/create-document-group). Pass the document IDs and a group name.

```bash
curl --request POST \
  --url https://api.signnow.com/documentgroup \
  --header 'Authorization: Bearer {{access_token}}' \
  --header 'Content-Type: application/json' \
  --data '{
    "document_ids": ["9f2c7b1e4d8a4f0c9b3e6a1d5c8f2b7e0a4d6c19", "e4a91c7d2b6f4083a5c1e9d7b0f3a86c2d5e4f19"],
    "group_name": "Client Service Agreement"
  }'
```

The response returns the `id` of the new document group. Save it for the next steps.

```json
{
  "id": "7b3e1a9c5d2f48609a1c7e4b2d8f6a0c3e5b9d17"
}
```

> The `group_name` is visible to signers, so choose a name that tells them what they are signing.

### Step 2. Add fields to the documents

Signers can only sign where you place fields. Add fields to each document in the group using [Edit a document](/docs/request-payments/operations/put-document-document_id). Assign every field to a role (for example, `Signer 1`) so you can address it when you create the invite. The example below adds three fields for the signer: a text field for their full name, a signature field, and a text field for the signing date.

> To get the IDs of the documents in the group, use [Get document group info](/docs/document-group/operations/get-document-group-info-v2).

Add the fields to the first document (Client Service Agreement):

```bash
curl --request PUT \
  --url https://api.signnow.com/document/{{document_id_1}} \
  --header 'Authorization: Bearer {{access_token}}' \
  --header 'Content-Type: application/json' \
  --data '{
    "fields": [
      {
        "type": "text",
        "role": "Signer 1",
        "required": true,
        "page_number": 0,
        "x": 100,
        "y": 650,
        "width": 200,
        "height": 28,
        "name": "full_name",
        "label": "Full name"
      },
      {
        "type": "signature",
        "role": "Signer 1",
        "required": true,
        "page_number": 0,
        "x": 100,
        "y": 690,
        "width": 200,
        "height": 40,
        "name": "signature"
      },
      {
        "type": "text",
        "role": "Signer 1",
        "required": true,
        "page_number": 0,
        "x": 100,
        "y": 745,
        "width": 120,
        "height": 28,
        "name": "date_signed",
        "label": "Date signed"
      }
    ]
  }'
```

Then add the same three fields to the second document (Statement of Work):

```bash
curl --request PUT \
  --url https://api.signnow.com/document/{{document_id_2}} \
  --header 'Authorization: Bearer {{access_token}}' \
  --header 'Content-Type: application/json' \
  --data '{
    "fields": [
      {
        "type": "text",
        "role": "Signer 1",
        "required": true,
        "page_number": 0,
        "x": 100,
        "y": 650,
        "width": 200,
        "height": 28,
        "name": "full_name",
        "label": "Full name"
      },
      {
        "type": "signature",
        "role": "Signer 1",
        "required": true,
        "page_number": 0,
        "x": 100,
        "y": 690,
        "width": 200,
        "height": 40,
        "name": "signature"
      },
      {
        "type": "text",
        "role": "Signer 1",
        "required": true,
        "page_number": 0,
        "x": 100,
        "y": 745,
        "width": 120,
        "height": 28,
        "name": "date_signed",
        "label": "Date signed"
      }
    ]
  }'
```

If your document runs to more than one page, set `page_number` to the index of the page that holds the signature block. For the full list of field types and options, see the [Fields](/docs/fields) guide.

### Step 3. Save the document group as a template

Turn the prepared group into a reusable template with [Create doc group template from doc group](/docs/document-group-template/operations/post-v2-document-groups-document_group_uid-document-group-template). The template stores the documents, fields, and roles so you can spin up identical groups later.

```bash
curl --request POST \
  --url https://api.signnow.com/v2/document-groups/{{document_group_id}}/document-group-template \
  --header 'Authorization: Bearer {{access_token}}' \
  --header 'Content-Type: application/json' \
  --data '{
    "name": "Client Service Agreement template"
  }'
```

This request is processed asynchronously and returns `202 Accepted` with an empty body. Retrieve the new template ID with [Get doc group templates](/docs/document-group-template/operations/get-user-documentgroup-templates).

```json
{
  "document_group_templates": [
    {
      "template_id": "3c8f0a2e6b1d47598c3a5e9b7d0f2a4c6e8b1d39",
      "template_name": "Client Service Agreement template"
    }
  ]
}
```

## Per signing session

Run these steps for each visitor who signs. Each session gets its own document group created from the template, so signers never touch the master version.

### Step 4. Create a document group from the template

For each signing session, create a fresh document group from the template with [Create doc group from template](/docs/document-group-template/operations/post-v2-document-group-templates-unique_id-document-group). This gives every signer an isolated copy while the template stays intact.

```bash
curl --request POST \
  --url https://api.signnow.com/v2/document-group-templates/{{document_group_template_id}}/document-group \
  --header 'Authorization: Bearer {{access_token}}' \
  --header 'Content-Type: application/json' \
  --data '{
    "group_name": "Client Service Agreement"
  }'
```

The response returns the new document group in `data.unique_id`, along with the documents it contains and their roles. Use these values in the next step.

```json
{
  "data": {
    "unique_id": "b6d2f4a8c0e3475991a7c5e3b9d1f0a24c6e8b35",
    "name": "Client Service Agreement",
    "state": "created",
    "documents": [
      {
        "id": "0c5a9e3b7d1f42869c4a2e8b6d0f3a7c1e5b9d24",
        "document_name": "Client Service Agreement",
        "roles": ["Signer 1"]
      },
      {
        "id": "5d1e8b3a7c2f49608b4a1e6d9c0f3a75b2e4d68c",
        "document_name": "Statement of Work",
        "roles": ["Signer 1"]
      }
    ]
  }
}
```

> The document IDs in the new group differ from the originals. Use the `id` and `roles` returned here, not the IDs from **Step 1**, when you build the invite.

### Step 5. Create an embedded invite for the document group

Create an embedded signing invite with [Create embedded invite](/docs/doc-group-embedded-signing/operations/create-embedded-invite-document-group). Group recipients into ordered steps. Each signer lists the documents they act on, the role they hold in each document, and the action (`sign`, `view`, or `approve`). Use the document group and document IDs returned in **Step 4**.

```bash
curl --request POST \
  --url https://api.signnow.com/v2/document-groups/{{document_group_id}}/embedded-invites \
  --header 'Authorization: Bearer {{access_token}}' \
  --header 'Content-Type: application/json' \
  --data '{
    "invites": [
      {
        "order": 1,
        "signers": [
          {
            "email": "signer1@email.com",
            "auth_method": "none",
            "redirect_uri": "https://your-wordpress-site.com/thank-you",
            "redirect_target": "self",
            "documents": [
              {
                "id": "0c5a9e3b7d1f42869c4a2e8b6d0f3a7c1e5b9d24",
                "role": "Signer 1",
                "action": "sign"
              },
              {
                "id": "5d1e8b3a7c2f49608b4a1e6d9c0f3a75b2e4d68c",
                "role": "Signer 1",
                "action": "sign"
              }
            ]
          }
        ]
      }
    ]
  }'
```

The response returns an embedded invite ID. Save it for the next step.

```json
{
  "data": {
    "id": "a2d6c19e4f8b40739c1e5a2d8b6f0c3e7d5b9a14"
  }
}
```

### Step 6. Generate the embedded signing link

Generate the link the recipient will open with [Generate embedded invite link](/docs/doc-group-embedded-signing/operations/generate-link-for-embedded-invite-document-group). The `email` and `auth_method` must match the values you set when creating the invite.

```bash
curl --request POST \
  --url https://api.signnow.com/v2/document-groups/{{document_group_id}}/embedded-invites/{{embedded_invite_id}}/link \
  --header 'Authorization: Bearer {{access_token}}' \
  --header 'Content-Type: application/json' \
  --data '{
    "email": "signer1@email.com",
    "auth_method": "none",
    "link_expiration": 45
  }'
```

The response contains the signing link:

```json
{
  "data": {
    "link": "https://app.signnow.com/document_group/01f3a9c7d2b64e8091a5c3e7b9d0f2a46c8e1b53"
  }
}
```

> `link_expiration` accepts 15 to 45 minutes. The link is single use and short lived, so generate it at the moment the signer needs it (for example, from your server when the WordPress page loads) rather than hardcoding it into the page.

### Step 7. Add the signing link to a WordPress page

Open the signing link inside an iframe on any WordPress page, such as a contact page or a dedicated signing page.

1. In the WordPress admin panel, open the page where you want the signing form and click **Edit**.
2. Click the **+** (Add block) button where you want the form to appear.
3. Search for **Custom HTML** and add the block.
4. Paste the iframe below, replacing the `src` with the link from **Step 6**.

```html
<iframe
  src="https://app.signnow.com/document_group/01f3a9c7d2b64e8091a5c3e7b9d0f2a46c8e1b53"
  width="100%"
  height="800"
  frameborder="0">
</iframe>
```

![sn_wordpress.png](/reference-assets/images/use_cases_all/sn_wordpress.png)

Click **Preview** to check how the form looks, then save the page. Your visitors can now sign the document directly on your WordPress site. After they finish, they are sent to the `redirect_uri` you configured in **Step 5**.

> To customize the look of the embedded signing session (your logo, colors, and other styling), see the [Branding](/docs/guides-branding) and [White-labeled signing](/docs/white-labeled-signing) guides.

Because embedded signing links expire, most integrations generate the link on the server (for example, in a small PHP snippet or plugin) and inject it into the iframe `src` when the page is requested, rather than pasting a fixed link into the block.

## More embedding options

Embedded signing is one of several ways to bring SignNow into your site or app:

- [Embedded signing](/docs/guides-embedded-signing): let recipients sign documents and document groups inside your site, as described in this guide.
- [Embedded sending](/docs/guides-embedded-sending): let your users prepare a document, add fields, and send it for signature from within your site.
- [Embedded editor](/docs/guides-embedded-editor): let your users open a document or document group in the SignNow editor to add or adjust fields before sending.

## Conclusion

With a few API calls and the standard WordPress Custom HTML block, you can offer PDF document signing on your WordPress site without any third party plugin. Building the flow on a document group template lets you prepare the documents and fields once, then create a fresh document group for every signer, which keeps your integration aligned with how SignNow handles signing whether you send one document or many. From here you can extend the experience with signer authentication, redirects, branding, and the other embedded options above to match your site's look and workflow.


---
*Full page: https://docs.signnow.com/docs/sign-pdfs-in-wordpress*
