> ## 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.

# Submitters

> Manage individual signers within submissions, track their status lifecycle, and handle invitations.

A submitter is an individual signer within a submission. Each submitter is assigned to a role defined in the template, has their own secure signing link, and progresses through an independent status lifecycle. You can track when they opened, signed, or declined the document, pre-fill their fields, and resend invitations.

## Submitter object

The standard submitter object returned by list endpoints:

```json theme={null}
{
  "id": 301,
  "uuid": "f9e8d7c6-b5a4-3210-fedc-ba9876543210",
  "slug": "r7t2q9v4",
  "email": "jane@example.com",
  "name": "Jane Smith",
  "role": "Client",
  "status": "completed",
  "submission_id": 187,
  "opened_at": "2026-04-08T11:10:00.000Z",
  "sent_at": "2026-04-08T10:31:01.000Z",
  "completed_at": "2026-04-08T11:15:00.000Z"
}
```

| Field           | Type           | Description                                                                                            |
| --------------- | -------------- | ------------------------------------------------------------------------------------------------------ |
| `id`            | integer        | Unique submitter identifier.                                                                           |
| `uuid`          | string         | UUID for this submitter instance. Unique per submission (not the same as the template submitter UUID). |
| `slug`          | string         | URL-safe identifier used in the signing link (`/s/{slug}`).                                            |
| `email`         | string         | Submitter's email address (encrypted at rest).                                                         |
| `name`          | string or null | Submitter's full name (encrypted at rest).                                                             |
| `role`          | string         | The template submitter role this person is assigned to (e.g., "Client", "Witness").                    |
| `status`        | string         | Current status. See [Status lifecycle](#status-lifecycle).                                             |
| `submission_id` | integer        | ID of the parent submission.                                                                           |
| `opened_at`     | string or null | ISO 8601 timestamp when the submitter first opened the signing link.                                   |
| `sent_at`       | string or null | ISO 8601 timestamp when the invitation email was sent.                                                 |
| `completed_at`  | string or null | ISO 8601 timestamp when the submitter completed and submitted their form.                              |

## Full submitter object

When retrieving a single submitter by ID, the response includes additional detail:

```json theme={null}
{
  "id": 301,
  "uuid": "f9e8d7c6-b5a4-3210-fedc-ba9876543210",
  "slug": "r7t2q9v4",
  "email": "jane@example.com",
  "name": "Jane Smith",
  "role": "Client",
  "status": "completed",
  "submission_id": 187,
  "phone": "+15551234567",
  "external_id": "cust-001",
  "opened_at": "2026-04-08T11:10:00.000Z",
  "sent_at": "2026-04-08T10:31:01.000Z",
  "completed_at": "2026-04-08T11:15:00.000Z",
  "declined_at": null,
  "values": {
    "full_name": "Jane Smith",
    "agreement_date": "2026-04-08",
    "payment_method": "Credit Card",
    "address_line_1": "123 Main St",
    "city": "Portland",
    "state": "OR",
    "zip_code": "97201"
  },
  "metadata": {
    "source": "website_checkout",
    "session_id": "sess_abc123"
  },
  "preferences": {
    "send_email": true,
    "sign_mode": "normal"
  },
  "documents": [
    {
      "id": 95,
      "name": "Service Agreement - Signed.pdf",
      "url": "/api/submissions/187/documents/95",
      "content_type": "application/pdf",
      "size": 284672
    }
  ],
  "submission_events": [
    {
      "event": "form.sent",
      "timestamp": "2026-04-08T10:31:01.000Z",
      "actor": "system",
      "ip_address": null
    },
    {
      "event": "form.viewed",
      "timestamp": "2026-04-08T11:10:00.000Z",
      "actor": "jane@example.com",
      "ip_address": "198.51.100.22"
    },
    {
      "event": "field.updated",
      "timestamp": "2026-04-08T11:12:00.000Z",
      "actor": "jane@example.com",
      "ip_address": "198.51.100.22"
    },
    {
      "event": "form.completed",
      "timestamp": "2026-04-08T11:15:00.000Z",
      "actor": "jane@example.com",
      "ip_address": "198.51.100.22"
    }
  ],
  "template": {
    "id": 42,
    "name": "Service Agreement",
    "slug": "qk7x9m2p",
    "external_id": "contract-sa-2026",
    "folder_name": "Legal Contracts"
  },
  "submission": {
    "id": 187,
    "slug": "n3k8p1w5",
    "source": "api",
    "status": "completed",
    "template_id": 42,
    "submitter_count": 2,
    "created_at": "2026-04-08T10:31:00.000Z",
    "updated_at": "2026-04-08T11:20:00.000Z",
    "completed_at": "2026-04-08T11:20:00.000Z",
    "expire_at": "2026-05-08T10:31:00.000Z",
    "archived_at": null
  }
}
```

### Additional fields in the detail response

| Field               | Type           | Description                                                                                                                                              |
| ------------------- | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `phone`             | string or null | Submitter's phone number in E.164 format (encrypted at rest).                                                                                            |
| `external_id`       | string or null | Your custom identifier for mapping this submitter to an external system (e.g., CRM contact ID).                                                          |
| `declined_at`       | string or null | ISO 8601 timestamp when the submitter declined to sign, or null.                                                                                         |
| `values`            | object         | Key-value map of the submitter's field entries. Keys match the field `key` from the template schema. Includes both pre-filled and signer-entered values. |
| `metadata`          | object         | Custom key-value pairs attached to this submitter (encrypted at rest).                                                                                   |
| `preferences`       | object         | Submitter-level preferences including `send_email` and `sign_mode`.                                                                                      |
| `documents`         | array          | Documents associated with this submitter's completed form.                                                                                               |
| `submission_events` | array          | Audit trail of events specific to this submitter. Each event includes `event`, `timestamp`, `actor`, and `ip_address`.                                   |
| `template`          | object         | Summary of the template this submission was created from.                                                                                                |
| `submission`        | object         | Summary of the parent submission.                                                                                                                        |

## Status lifecycle

Each submitter progresses through a series of statuses independently from other submitters in the same submission.

```
waiting(0) → sent(1) → opened(2) → completed(3)
                                  → declined(4)
waiting(0) → expired(5)
```

| Status      | Code | Description                                                                                           |
| ----------- | ---- | ----------------------------------------------------------------------------------------------------- |
| `waiting`   | 0    | The submitter's turn has not arrived yet (in sequential signing) or the invitation has not been sent. |
| `sent`      | 1    | The invitation email has been sent. The submitter has not yet opened the signing link.                |
| `opened`    | 2    | The submitter has opened the signing link at least once.                                              |
| `completed` | 3    | The submitter has filled all required fields and submitted the form.                                  |
| `declined`  | 4    | The submitter explicitly declined to sign the document.                                               |
| `expired`   | 5    | The submission's `expire_at` timestamp passed before this submitter completed.                        |

<Note>
  In **sequential** signing order, submitters start in `waiting` status and move to `sent` only when the previous submitter completes. In **parallel** signing, all submitters are sent invitations immediately and skip the `waiting` state.
</Note>

### Status transitions

The status only moves forward -- a submitter cannot go back to a previous status. The possible transitions are:

| From      | To          | Trigger                                                                     |
| --------- | ----------- | --------------------------------------------------------------------------- |
| `waiting` | `sent`      | Previous submitter completed (sequential) or submission created (parallel). |
| `sent`    | `opened`    | Submitter clicks the signing link for the first time.                       |
| `opened`  | `completed` | Submitter fills all required fields and submits the form.                   |
| `opened`  | `declined`  | Submitter clicks the decline button and confirms.                           |
| `waiting` | `expired`   | Submission `expire_at` reached.                                             |
| `sent`    | `expired`   | Submission `expire_at` reached.                                             |
| `opened`  | `expired`   | Submission `expire_at` reached.                                             |

## Listing submitters

Retrieve all submitters across your account, optionally filtered by submission, status, or external ID.

```bash theme={null}
curl "$DOCUTRUST_URL/api/submitters?limit=25&status=completed" \
  -H "X-Auth-Token: $DOCUTRUST_TOKEN"
```

### Filter parameters

| Parameter       | Type    | Description                                                                        |
| --------------- | ------- | ---------------------------------------------------------------------------------- |
| `submission_id` | integer | Filter by parent submission.                                                       |
| `status`        | string  | Filter by status: `waiting`, `sent`, `opened`, `completed`, `declined`, `expired`. |
| `external_id`   | string  | Filter by your custom external ID.                                                 |
| `email`         | string  | Filter by submitter email address.                                                 |
| `after`         | integer | Cursor for pagination (return items after this ID).                                |
| `before`        | integer | Cursor for pagination (return items before this ID).                               |
| `limit`         | integer | Items per page (1-100, default 10).                                                |

**Response:**

```json theme={null}
{
  "data": [
    {
      "id": 301,
      "uuid": "f9e8d7c6-b5a4-3210-fedc-ba9876543210",
      "slug": "r7t2q9v4",
      "email": "jane@example.com",
      "name": "Jane Smith",
      "role": "Client",
      "status": "completed",
      "submission_id": 187,
      "opened_at": "2026-04-08T11:10:00.000Z",
      "sent_at": "2026-04-08T10:31:01.000Z",
      "completed_at": "2026-04-08T11:15:00.000Z"
    },
    {
      "id": 302,
      "uuid": "a8b7c6d5-e4f3-2109-abcd-987654321098",
      "slug": "k5m9n3p7",
      "email": "bob@acmecorp.com",
      "name": "Bob Johnson",
      "role": "Company Representative",
      "status": "completed",
      "submission_id": 187,
      "opened_at": "2026-04-08T11:17:00.000Z",
      "sent_at": "2026-04-08T10:31:01.000Z",
      "completed_at": "2026-04-08T11:20:00.000Z"
    },
    {
      "id": 295,
      "uuid": "c9d8e7f6-a5b4-3210-cdef-ba9876543210",
      "slug": "p4q8r2s6",
      "email": "carol@example.com",
      "name": "Carol Williams",
      "role": "Client",
      "status": "sent",
      "submission_id": 185,
      "opened_at": null,
      "sent_at": "2026-04-07T14:00:01.000Z",
      "completed_at": null
    }
  ],
  "pagination": {
    "count": 3,
    "next": 295,
    "prev": null
  }
}
```

### Filter by submission

Retrieve all submitters for a specific submission:

```bash theme={null}
curl "$DOCUTRUST_URL/api/submitters?submission_id=187" \
  -H "X-Auth-Token: $DOCUTRUST_TOKEN"
```

### Filter by external ID

Find a submitter by your custom identifier:

```bash theme={null}
curl "$DOCUTRUST_URL/api/submitters?external_id=cust-001" \
  -H "X-Auth-Token: $DOCUTRUST_TOKEN"
```

## Retrieving a submitter

Get the full detail for a single submitter:

```bash theme={null}
curl "$DOCUTRUST_URL/api/submitters/301" \
  -H "X-Auth-Token: $DOCUTRUST_TOKEN"
```

This returns the [full submitter object](#full-submitter-object) with values, metadata, preferences, events, and nested template/submission data.

## Updating a submitter

Update a submitter's details before they have completed their form. You can change their name, email, phone, external ID, metadata, and pre-filled values.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X PUT "$DOCUTRUST_URL/api/submitters/301" \
    -H "X-Auth-Token: $DOCUTRUST_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "Jane M. Smith",
      "email": "jane.smith@newdomain.com",
      "phone": "+15559876543",
      "external_id": "cust-001-updated",
      "metadata": {
        "source": "website_checkout",
        "session_id": "sess_abc123",
        "updated_by": "admin"
      },
      "values": {
        "full_name": "Jane M. Smith",
        "address_line_1": "456 Oak Ave"
      }
    }'
  ```

  ```javascript Node.js theme={null}
  const response = await fetch(`${process.env.DOCUTRUST_URL}/api/submitters/301`, {
    method: "PUT",
    headers: {
      "X-Auth-Token": process.env.DOCUTRUST_TOKEN,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      name: "Jane M. Smith",
      email: "jane.smith@newdomain.com",
      phone: "+15559876543",
      external_id: "cust-001-updated",
      metadata: {
        source: "website_checkout",
        session_id: "sess_abc123",
        updated_by: "admin",
      },
      values: {
        full_name: "Jane M. Smith",
        address_line_1: "456 Oak Ave",
      },
    }),
  });

  const submitter = await response.json();
  ```

  ```python Python theme={null}
  import requests
  import os

  url = f"{os.environ['DOCUTRUST_URL']}/api/submitters/301"
  headers = {
      "X-Auth-Token": os.environ["DOCUTRUST_TOKEN"],
      "Content-Type": "application/json",
  }
  payload = {
      "name": "Jane M. Smith",
      "email": "jane.smith@newdomain.com",
      "phone": "+15559876543",
      "external_id": "cust-001-updated",
      "metadata": {
          "source": "website_checkout",
          "session_id": "sess_abc123",
          "updated_by": "admin",
      },
      "values": {
          "full_name": "Jane M. Smith",
          "address_line_1": "456 Oak Ave",
      },
  }

  response = requests.put(url, headers=headers, json=payload)
  submitter = response.json()
  ```
</CodeGroup>

**Response:**

```json theme={null}
{
  "id": 301,
  "uuid": "f9e8d7c6-b5a4-3210-fedc-ba9876543210",
  "slug": "r7t2q9v4",
  "email": "jane.smith@newdomain.com",
  "name": "Jane M. Smith",
  "role": "Client",
  "status": "sent",
  "submission_id": 187,
  "phone": "+15559876543",
  "external_id": "cust-001-updated",
  "opened_at": null,
  "sent_at": "2026-04-08T10:31:01.000Z",
  "completed_at": null,
  "declined_at": null,
  "values": {
    "full_name": "Jane M. Smith",
    "agreement_date": "2026-04-08",
    "payment_method": "Credit Card",
    "address_line_1": "456 Oak Ave",
    "city": "Portland",
    "state": "OR",
    "zip_code": "97201"
  },
  "metadata": {
    "source": "website_checkout",
    "session_id": "sess_abc123",
    "updated_by": "admin"
  },
  "preferences": {
    "send_email": true,
    "sign_mode": "normal"
  }
}
```

### Updatable fields

| Field         | Type   | Notes                                                                                                                       |
| ------------- | ------ | --------------------------------------------------------------------------------------------------------------------------- |
| `name`        | string | Update the submitter's display name.                                                                                        |
| `email`       | string | Change the email address. If the invitation has been sent, use [resend](#resending-invitations) to send to the new address. |
| `phone`       | string | Phone number in E.164 format.                                                                                               |
| `external_id` | string | Your custom identifier.                                                                                                     |
| `metadata`    | object | Replaces the entire metadata object. Merge existing values client-side if you want to preserve them.                        |
| `values`      | object | Merges with existing values. Only the keys you provide are updated; other pre-filled values are preserved.                  |

<Warning>
  You cannot update a submitter whose status is `completed`, `declined`, or `expired`. The API returns a `422 Unprocessable Entity` error for updates to finalized submitters.
</Warning>

## Resending invitations

If a submitter has not received or has lost their invitation email, resend it:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "$DOCUTRUST_URL/api/submitters/301/resend" \
    -H "X-Auth-Token: $DOCUTRUST_TOKEN"
  ```

  ```javascript Node.js theme={null}
  await fetch(`${process.env.DOCUTRUST_URL}/api/submitters/301/resend`, {
    method: "POST",
    headers: { "X-Auth-Token": process.env.DOCUTRUST_TOKEN },
  });
  ```

  ```python Python theme={null}
  import requests
  import os

  url = f"{os.environ['DOCUTRUST_URL']}/api/submitters/301/resend"
  headers = {"X-Auth-Token": os.environ["DOCUTRUST_TOKEN"]}
  response = requests.post(url, headers=headers)
  ```
</CodeGroup>

**Response:**

```json theme={null}
{
  "message": "Invitation resent successfully",
  "submitter_id": 301,
  "email": "jane@example.com",
  "sent_at": "2026-04-08T14:00:00.000Z"
}
```

<Note>
  Resending updates the `sent_at` timestamp. You can only resend to submitters in `sent` or `opened` status. Submitters in `waiting` status have not yet reached their turn in sequential signing.
</Note>

## External ID mapping

The `external_id` field lets you associate a submitter with a record in your own system -- a CRM contact, a user account, an order ID, or any other identifier.

### Setting external IDs at creation

```json theme={null}
{
  "submitters": [
    {
      "role": "Client",
      "email": "jane@example.com",
      "external_id": "crm_contact_12345"
    }
  ]
}
```

### Looking up by external ID

```bash theme={null}
curl "$DOCUTRUST_URL/api/submitters?external_id=crm_contact_12345" \
  -H "X-Auth-Token: $DOCUTRUST_TOKEN"
```

This returns all submitters with the matching external ID across all submissions. Use this to check if a specific contact has any pending or completed signing requests.

### Common patterns

| Use case              | External ID format      | Example                       |
| --------------------- | ----------------------- | ----------------------------- |
| CRM integration       | CRM contact ID          | `crm_contact_12345`           |
| User account mapping  | Your app's user ID      | `user_98765`                  |
| Order processing      | Order or invoice number | `order_2026-0042`             |
| HR onboarding         | Employee ID             | `emp_HR-2026-001`             |
| Multi-system tracking | Composite key           | `salesforce:0015000000ABC123` |

## Signing links

Each submitter has a unique signing link constructed from their `slug`:

```
https://spitshake.io/s/{slug}
```

For example, submitter with slug `r7t2q9v4` signs at `https://spitshake.io/s/r7t2q9v4`.

### When to use direct links

* **Embedded flows**: Generate the signing URL server-side and redirect the user, or embed it in an iframe.
* **Custom emails**: If you handle email delivery yourself (with `send_email: false`), include this link in your email templates.
* **In-app signing**: Open the signing link in a modal or new tab within your application.

<Tip>
  For production embedded signing, consider using [JWT bearer tokens](/guides/authentication#jwt-bearer-token) with the DocuTrust JavaScript SDK instead of raw signing links. JWTs provide scoped access control and do not expose permanent signing URLs.
</Tip>
