# Signers API reference

> Individual people on a signature request.

Source: https://signwith.co/docs/api/signers · Updated 2026-10-02

## Get a signer

`GET https://app.signwith.co/api/v1/signers/{id}`

Read-only keys can call this.

Returns one signer with their status, signing link, field values and — once they've signed —
their signed documents. Use it when you track signers individually (e.g. from a `signer.*`
webhook or by storing signer IDs against your own users).

### Path parameters

| Name | Type | Description |
| --- | --- | --- |
| `id` (required) | integer | Signer ID. |

### Request sample

cURL:

```bash
curl https://app.signwith.co/api/v1/signers/9121 \
  -H "Authorization: Bearer $SIGNWITH_API_KEY"
```

Node:

```javascript
const response = await fetch('https://app.signwith.co/api/v1/signers/9121', {
  headers: {
    Authorization: `Bearer ${process.env.SIGNWITH_API_KEY}`,
  },
})

console.log(response.status, await response.json())
```

Python:

```python
import os

import requests

response = requests.get(
    "https://app.signwith.co/api/v1/signers/9121",
    headers={
        "Authorization": f"Bearer {os.environ['SIGNWITH_API_KEY']}",
    },
)

print(response.status_code, response.json())
```

### Response 200

The signer.

```json
{
  "object": "signer",
  "id": 9120,
  "signature_request_id": 4812,
  "role": "Tenant",
  "name": "Grace Hopper",
  "email": "grace@example.com",
  "phone": null,
  "external_id": "cust_8841",
  "metadata": {
    "crm_deal_id": "D-2291"
  },
  "status": "signed",
  "signing_url": null,
  "sent_at": "2026-09-27T09:00:02Z",
  "viewed_at": "2026-09-27T09:41:18Z",
  "signed_at": "2026-09-27T09:44:51Z",
  "declined_at": null,
  "created_at": "2026-09-27T09:00:01Z",
  "updated_at": "2026-09-27T09:44:51Z",
  "values": [
    {
      "field": "Tenant name",
      "value": "Grace Hopper"
    },
    {
      "field": "Monthly rent",
      "value": "2150"
    },
    {
      "field": "Tenant signature",
      "value": "https://app.signwith.co/file/eyJfcmFpbHMiOnsiZGF0YSI6NTUxfX0/signature.png"
    }
  ],
  "documents": [
    {
      "name": "Lease agreement",
      "url": "https://app.signwith.co/file/eyJfcmFpbHMiOnsiZGF0YSI6NTUyfX0/lease-agreement.pdf"
    }
  ]
}
```

### Errors

| Status | Meaning |
| --- | --- |
| 401 | The API key is missing, invalid or expired, or its account has been archived. |
| 403 | The key is read-only, or its user can't access this resource. |
| 404 | The resource doesn't exist or belongs to another account. |
| 429 | Rate limit exceeded (`rate_limited`, with `Retry-After`); more than 20 `POST /feedback` messages in an hour (`rate_limited`, with `Retry-After`: seconds until the next clock hour); or — for `POST /signature_requests/{id}/remind` — signers were reminded less than an hour ago (`remind_too_soon`, with `Retry-After`).  |
| 500 | Something went wrong on SignWith's side. It's safe to retry with the same `Idempotency-Key`. |

## Update a signer

`PATCH https://app.signwith.co/api/v1/signers/{id}`

Needs a full-access key.

Corrects a signer's details or prefills more of their fields before they sign — for example
when a customer gave the wrong email address. Only the parameters you send are changed;
`prefill` values are merged with existing ones.

Set `resend: true` to email the signing link again (only if the signer was already invited; at most
once every 10 minutes per signer, otherwise `429 remind_too_soon` with `Retry-After`).
Signers who have signed or declined can't be changed (`422 signer_finished`), nor can signers
of a canceled, expired or declined request (`422 not_open`). The signer must keep an `email`
or a `phone`, emails must be valid, and `prefill` must be an object (all `422 invalid_parameter`).
`PUT` is accepted as an alias.

### Path parameters

| Name | Type | Description |
| --- | --- | --- |
| `id` (required) | integer | Signer ID. |

### Request body (`application/json`)

- `name` (string or null).
- `email` (string or null, email address).
- `phone` (string or null).
- `external_id` (string or null).
- `metadata` (object). Replaces the signer's metadata.
- `prefill` (object). Field values to set, keyed by field name. Merged with existing prefilled values.
- `resend` (boolean, default `false`). Email the signing link again after updating (only if the signer was already invited).

### Request sample

cURL:

```bash
curl -X PATCH https://app.signwith.co/api/v1/signers/9121 \
  -H "Authorization: Bearer $SIGNWITH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "email": "ada.lovelace@acme.co",
  "prefill": {
    "Landlord name": "Ada Lovelace"
  },
  "resend": true
}'
```

Node:

```javascript
const response = await fetch('https://app.signwith.co/api/v1/signers/9121', {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${process.env.SIGNWITH_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    email: 'ada.lovelace@acme.co',
    prefill: {
      'Landlord name': 'Ada Lovelace',
    },
    resend: true,
  }),
})

console.log(response.status, await response.json())
```

Python:

```python
import os

import requests

response = requests.patch(
    "https://app.signwith.co/api/v1/signers/9121",
    headers={
        "Authorization": f"Bearer {os.environ['SIGNWITH_API_KEY']}",
    },
    json={
        "email": "ada.lovelace@acme.co",
        "prefill": {
            "Landlord name": "Ada Lovelace",
        },
        "resend": True,
    },
)

print(response.status_code, response.json())
```

### Response 200

The updated signer.

```json
{
  "object": "signer",
  "id": 9121,
  "signature_request_id": 4812,
  "role": "Landlord",
  "name": "Ada Lovelace",
  "email": "ada.lovelace@acme.co",
  "phone": null,
  "external_id": null,
  "metadata": {},
  "status": "sent",
  "signing_url": "https://app.signwith.co/s/q8LkT2mZpV4r",
  "sent_at": "2026-09-27T09:44:53Z",
  "viewed_at": null,
  "signed_at": null,
  "declined_at": null,
  "created_at": "2026-09-27T09:00:01Z",
  "updated_at": "2026-09-27T11:02:17Z",
  "values": [
    {
      "field": "Landlord name",
      "value": "Ada Lovelace"
    }
  ]
}
```

### Errors

| Status | Meaning |
| --- | --- |
| 400 | The request body is not valid JSON. |
| 401 | The API key is missing, invalid or expired, or its account has been archived. |
| 403 | The key is read-only, or its user can't access this resource. |
| 404 | The resource doesn't exist or belongs to another account. |
| 422 | The request is valid JSON but can't be processed. See `error.code`; the codes each endpoint can return are described in the endpoint's description and in the error table above.  |
| 429 | Rate limit exceeded (`rate_limited`, with `Retry-After`); more than 20 `POST /feedback` messages in an hour (`rate_limited`, with `Retry-After`: seconds until the next clock hour); or — for `POST /signature_requests/{id}/remind` — signers were reminded less than an hour ago (`remind_too_soon`, with `Retry-After`).  |
| 500 | Something went wrong on SignWith's side. It's safe to retry with the same `Idempotency-Key`. |

## The signer object

Anchor: https://signwith.co/docs/api/signers#the-signer-object

- `object` (string, required, always `signer`).
- `id` (integer, required).
- `signature_request_id` (integer, required).
- `role` (string or null, required). The template role this signer fills.
- `name` (string or null, required).
- `email` (string or null, required, email address).
- `phone` (string or null, required).
- `external_id` (string or null, required). Your own ID for this signer.
- `metadata` (object, required). Arbitrary key/value data you attached to the signer.
- `status` (string, required, one of `waiting`, `ready`, `sent`, `viewed`, `signed`, `declined`). `waiting` — an earlier signer in a sequential request has to sign first; `ready` — it's their turn but they weren't emailed (e.g. `send_email: false`, or the email is still queued), so share `signing_url` yourself; `sent` — invited; `viewed` — opened the document; `signed` — finished signing; `declined` — declined to sign.
- `signing_url` (string or null, required, URL). The signer's private signing link. Anyone with it can sign as this signer, so only share it with them. `null` once they've signed, or when the request is canceled, declined or expired, or its template is archived.
- `sent_at` (string (date-time) or null, required).
- `viewed_at` (string (date-time) or null, required).
- `signed_at` (string (date-time) or null, required).
- `declined_at` (string (date-time) or null, required).
- `created_at` (string (date-time), required).
- `updated_at` (string (date-time), required).
- `values` (array of objects, required). Field values filled so far (prefilled or entered by the signer).
  - `field` (string, required). Field name (or a generated name such as `Text Field 2` for unnamed fields).
  - `value` (string or number or boolean or array of anys or null, required). The value entered or prefilled.
- `documents` (array of objects). The signer's signed documents. Present only once they've signed.
  - `name` (string, required). File name without extension.
  - `url` (string, required, URL). Download link for the signed PDF.
