> ## Documentation Index
> Fetch the complete documentation index at: https://docs.spitshake.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Witness Signatures

> Allow signers to invite a witness after completing their signature.

# Witness Signatures

Witness signatures add a layer of verification to the signing process. After a signer completes their portion of a document, they can invite a witness to co-sign. The witness receives a signing invitation and must complete their own signature fields before the submission is finalized.

## How it works

1. A template defines a **Witness** submitter role with signature fields assigned to it.
2. The primary signer completes their form (fills all their fields and submits).
3. After completion, the signer is presented with an option to invite a witness.
4. The signer enters the witness's name and email address.
5. DocuTrust sends the witness a signing invitation email.
6. The witness opens the link, reviews the document, and completes their signature fields.
7. Once the witness completes, the submission moves to the next step (or finishes if all roles are done).

## API endpoint

### Invite a witness

`POST /s/:slug/invite_witness`

After completing their form, a signer can invite a witness by calling this endpoint with the signer's signing slug.

```bash theme={null}
curl -X POST "https://your-app.com/s/aB3kL9mNpQ/invite_witness" \
  -H "Content-Type: application/json" \
  -d '{
    "witness_name": "Sarah Johnson",
    "witness_email": "sarah.johnson@example.com",
    "message": "Hi Sarah, I have just signed an employment agreement and need you to witness it. Please review and add your signature."
  }'
```

**Request parameters:**

| Parameter       | Type   | Required | Description                                                                                   |
| --------------- | ------ | -------- | --------------------------------------------------------------------------------------------- |
| `witness_name`  | string | Yes      | Full name of the witness.                                                                     |
| `witness_email` | string | Yes      | Email address where the witness invitation will be sent. Must differ from the signer's email. |
| `message`       | string | No       | Optional custom message included in the witness invitation email.                             |

**Response (200 OK):**

```json theme={null}
{
  "success": true,
  "witness": {
    "id": 305,
    "uuid": "e5f6a7b8-c9d0-1234-ef01-456789012345",
    "slug": "w2x6y3z7",
    "email": "sarah.johnson@example.com",
    "name": "Sarah Johnson",
    "role": "Witness",
    "status": "sent",
    "phone": null,
    "external_id": null,
    "metadata": {
      "invited_by_submitter_id": 301,
      "invited_by_email": "jane@example.com",
      "invited_by_name": "Jane Smith"
    },
    "values": {},
    "preferences": {
      "send_email": true,
      "sign_mode": "normal"
    },
    "embed_src": "https://your-app.com/s/w2x6y3z7",
    "opened_at": null,
    "sent_at": "2026-04-09T14:35:00.000Z",
    "completed_at": null,
    "declined_at": null,
    "submission_id": 187,
    "template_id": 42
  },
  "submission": {
    "id": 187,
    "slug": "n3k8p1w5",
    "status": "pending",
    "template_id": 42,
    "submitter_count": 3,
    "created_at": "2026-04-08T10:31:00.000Z",
    "updated_at": "2026-04-09T14:35:00.000Z",
    "completed_at": null,
    "expire_at": "2026-05-08T10:31:00.000Z",
    "archived_at": null
  }
}
```

## Validation rules

The endpoint enforces the following rules. Violations return an HTTP `422` response with a descriptive error message.

| Rule                                                              | Error message                                               |
| ----------------------------------------------------------------- | ----------------------------------------------------------- |
| The signer must have completed their form (status = `completed`). | `"Signer has not completed their form yet."`                |
| The witness email must differ from the signer's email.            | `"Witness email cannot be the same as the signer's email."` |
| The template must define a `Witness` submitter role.              | `"Template does not have a Witness role defined."`          |
| A witness has not already been invited for this signer.           | `"A witness has already been invited for this submission."` |
| The submission must not be completed, expired, or archived.       | `"Submission is no longer active."`                         |

**Error response example (422):**

```json theme={null}
{
  "error": "validation_error",
  "message": "Signer has not completed their form yet.",
  "details": {
    "submitter_id": 301,
    "submitter_status": "opened",
    "required_status": "completed"
  }
}
```

## Audit events

Witness actions are recorded in the immutable audit trail:

| Event                 | Description                            | Recorded data                                                                |
| --------------------- | -------------------------------------- | ---------------------------------------------------------------------------- |
| `witness_invited`     | A signer invited a witness.            | Signer ID, signer email, witness email, witness name, IP address, timestamp. |
| `witness_form_sent`   | The witness invitation email was sent. | Witness submitter ID, witness email, timestamp.                              |
| `witness_form_viewed` | The witness opened the signing link.   | Witness submitter ID, witness IP, user agent, timestamp.                     |
| `witness_completed`   | The witness completed their signature. | Witness submitter ID, witness email, witness IP, signed fields, timestamp.   |
| `witness_declined`    | The witness declined to sign.          | Witness submitter ID, witness email, decline reason, timestamp.              |

**Audit log entry example:**

```json theme={null}
{
  "event": "witness_invited",
  "timestamp": "2026-04-09T14:35:00.000Z",
  "actor": "jane@example.com",
  "ip_address": "198.51.100.22",
  "details": {
    "signer_submitter_id": 301,
    "signer_email": "jane@example.com",
    "signer_name": "Jane Smith",
    "witness_submitter_id": 305,
    "witness_email": "sarah.johnson@example.com",
    "witness_name": "Sarah Johnson",
    "submission_id": 187,
    "template_id": 42
  }
}
```

## Webhook events

When a witness is invited or completes signing, webhook events are dispatched to all configured endpoints:

### form.created (witness)

Fired when the witness signing form is created and the invitation is sent.

```json theme={null}
{
  "event": "form.created",
  "timestamp": "2026-04-09T14:35:00Z",
  "data": {
    "submitter": {
      "id": 305,
      "uuid": "e5f6a7b8-c9d0-1234-ef01-456789012345",
      "email": "sarah.johnson@example.com",
      "name": "Sarah Johnson",
      "role": "Witness",
      "status": "sent",
      "external_id": null,
      "metadata": {
        "invited_by_submitter_id": 301,
        "invited_by_email": "jane@example.com",
        "invited_by_name": "Jane Smith"
      },
      "opened_at": null,
      "completed_at": null,
      "declined_at": null
    },
    "submission": {
      "id": 187,
      "slug": "n3k8p1w5",
      "status": "pending",
      "template_id": 42
    },
    "template": {
      "id": 42,
      "name": "Service Agreement"
    }
  }
}
```

### form.completed (witness)

Fired when the witness completes their signature.

```json theme={null}
{
  "event": "form.completed",
  "timestamp": "2026-04-09T15:10:00Z",
  "data": {
    "submitter": {
      "id": 305,
      "uuid": "e5f6a7b8-c9d0-1234-ef01-456789012345",
      "email": "sarah.johnson@example.com",
      "name": "Sarah Johnson",
      "role": "Witness",
      "status": "completed",
      "external_id": null,
      "metadata": {
        "invited_by_submitter_id": 301,
        "invited_by_email": "jane@example.com",
        "invited_by_name": "Jane Smith"
      },
      "opened_at": "2026-04-09T15:00:00Z",
      "completed_at": "2026-04-09T15:10:00Z",
      "declined_at": null
    },
    "submission": {
      "id": 187,
      "slug": "n3k8p1w5",
      "status": "completed",
      "template_id": 42
    },
    "template": {
      "id": 42,
      "name": "Service Agreement"
    }
  }
}
```

## Template setup

To enable witness signatures, your template must include a **Witness** submitter role. The Witness role should have at minimum a signature field assigned to it.

```json theme={null}
{
  "submitters": [
    {
      "uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "name": "Client"
    },
    {
      "uuid": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
      "name": "Company Representative"
    },
    {
      "uuid": "c3d4e5f6-a7b8-9012-cdef-123456789012",
      "name": "Witness"
    }
  ],
  "schema": [
    {
      "uuid": "d4e5f6a7-b8c9-0123-def0-234567890123",
      "name": "Witness Signature",
      "type": "signature",
      "submitter_uuid": "c3d4e5f6-a7b8-9012-cdef-123456789012",
      "required": true,
      "readonly": false,
      "key": "witness_signature",
      "default_value": null,
      "placeholder": null,
      "options": null,
      "areas": [
        {
          "page": 2,
          "x": 0.55,
          "y": 0.82,
          "w": 0.30,
          "h": 0.06,
          "attachment_uuid": "e5f6a7b8-c9d0-1234-ef01-456789012345"
        }
      ]
    },
    {
      "uuid": "e5f6a7b8-c9d0-1234-ef01-567890123456",
      "name": "Witness Name",
      "type": "text",
      "submitter_uuid": "c3d4e5f6-a7b8-9012-cdef-123456789012",
      "required": true,
      "readonly": false,
      "key": "witness_name",
      "default_value": null,
      "placeholder": "Enter your full name",
      "options": null,
      "areas": [
        {
          "page": 2,
          "x": 0.55,
          "y": 0.78,
          "w": 0.30,
          "h": 0.03,
          "attachment_uuid": "e5f6a7b8-c9d0-1234-ef01-456789012345"
        }
      ]
    },
    {
      "uuid": "f6a7b8c9-d0e1-2345-f012-678901234567",
      "name": "Witness Date",
      "type": "date",
      "submitter_uuid": "c3d4e5f6-a7b8-9012-cdef-123456789012",
      "required": true,
      "readonly": false,
      "key": "witness_date",
      "default_value": "today",
      "placeholder": "MM/DD/YYYY",
      "options": null,
      "areas": [
        {
          "page": 2,
          "x": 0.55,
          "y": 0.90,
          "w": 0.20,
          "h": 0.03,
          "attachment_uuid": "e5f6a7b8-c9d0-1234-ef01-456789012345"
        }
      ]
    }
  ]
}
```

<Tip>
  You can also use the embed component with `data-role="Witness"` to render only the witness portion of the form for integration into your own witness invitation flow.
</Tip>

<Note>
  The witness signing URL returned in `embed_src` can be used to embed the witness form directly in your application, bypassing the email invitation flow entirely.
</Note>
