{"openapi":"3.1.0","info":{"title":"SignWith API","version":"1.0.0","summary":"Send documents for e-signature, track signers and receive signing events.","contact":{"name":"SignWith Support","url":"https://signwith.co"},"description":"The SignWith API lets you turn your documents into reusable **templates**, send them out as\n**signature requests**, follow each **signer** through the process and download the signed\nresult. Everything you can do from the API you can also see in the SignWith dashboard.\n\nAll requests go to `https://app.signwith.co/api/v1`, accept and return JSON (`Content-Type:\napplication/json`), and use UTF-8. Timestamps are ISO 8601 strings. IDs are integers,\nexcept template field IDs, which are UUID strings.\n\n## Authentication\n\nEvery request must carry an API key in the `Authorization` header:\n\n```http\nAuthorization: Bearer sw_live_3xAmPl3K3y...\n```\n\nCreate and revoke keys in the dashboard under **Settings → Developers**. Each key belongs to\nthe user who created it and acts with that user's permissions.\n\n| Key prefix  | Environment | Behaviour |\n|-------------|-------------|-----------|\n| `sw_live_`  | Live        | Sends real signing emails and uses credits. |\n| `sw_test_`  | Test        | Issued from your test account. Use it while building your integration; data is kept apart from live data. |\n\nCall [`GET /me`](#operation/getMe) to confirm which user, account and environment a key belongs to.\n\nKeys can be **full access** or **read-only**. A read-only key can call any `GET` endpoint,\n`POST /documents/verify` and `POST /feedback`, but every other write returns\n`403 read_only_api_key`. Keys can also have an expiry date; an expired key returns\n`401 api_key_expired`.\n\n## Errors\n\nSignWith uses conventional HTTP status codes. Every error response has the same envelope:\n\n```json\n{\n  \"error\": {\n    \"code\": \"invalid_signer\",\n    \"message\": \"Signer 2 needs an email or phone\"\n  }\n}\n```\n\n`code` is stable and meant for your code to branch on; `message` is human-readable and may change.\n\n| HTTP | `code` | Meaning |\n|------|--------|---------|\n| 400 | `invalid_json` | The request body is not valid JSON. |\n| 401 | `unauthenticated` | The API key is missing, malformed or revoked, or its account has been archived. |\n| 401 | `api_key_expired` | The API key has passed its expiry date. Create a new one. |\n| 402 | `insufficient_credits` | Your account doesn't have enough credits to send this document. See [Buying credits](#section/Buying-credits). |\n| 403 | `read_only_api_key` | A read-only key was used for a write request. |\n| 403 | `insufficient_scope` | MCP only: the AI app was connected with **View only** access and tried to change something. |\n| 403 | `not_available` | MCP only: the tool isn't offered to this app (credit purchase tools in ChatGPT). |\n| 403 | `forbidden` | The key's user doesn't have access to this resource. |\n| 404 | `not_found` | The resource doesn't exist or belongs to another account, or no endpoint matches the method and path. |\n| 409 | `idempotency_key_in_use` | Another request with the same `Idempotency-Key` is still running. |\n| 422 | `idempotency_key_reused` | The `Idempotency-Key` was already used with a different request body. |\n| 422 | `missing_parameter` | A required parameter is missing. |\n| 422 | `invalid_parameter` | A parameter has an unsupported value (e.g. `status`, `signing_order`, `expires_at` not an ISO 8601 time in the future, `prefill`/`metadata` not an object, invalid signer email on update). |\n| 422 | `invalid_request` | The request is well-formed but can't be processed (e.g. invalid prefill value). |\n| 422 | `missing_documents` | A template was created without any documents. |\n| 422 | `too_many_documents` | More than 10 documents were sent for one template. |\n| 422 | `document_too_large` | A document is larger than 25 MB. |\n| 422 | `invalid_document` | A document is empty, could not be downloaded, or is not valid base64 / PDF. |\n| 422 | `invalid_file_type` | A document is not a PDF or an image. |\n| 422 | `invalid_field` | A template field in `fields` is invalid (unknown type, missing options or areas, page or coordinates out of range, too many roles). |\n| 422 | `template_has_no_fields` | The template has no fields to fill in or sign yet. Add fields with `PATCH /templates/{id}` or in the editor. |\n| 422 | `template_archived` | The template is archived and can't be sent. Duplicate it or pick another one. |\n| 422 | `pdf_encrypted` | The PDF is password protected and no `password` was sent. |\n| 422 | `missing_signers` | A signature request has no usable signers. |\n| 422 | `invalid_signer` | `signers` isn't a list of objects, a signer has no email or phone or an invalid email, has an unknown role, a role is given twice, or there are more signers than roles. |\n| 422 | `already_completed` | The signature request is already fully signed. |\n| 422 | `not_open` | The signature request was canceled, declined or has expired, so it can't be reminded and its signers can't be changed. |\n| 422 | `nothing_to_remind` | No signer is currently waiting to sign. |\n| 422 | `signer_finished` | The signer has already signed or declined. |\n| 422 | `invalid_discount_code` | The discount code is invalid, used up, expired or not valid for this credit pack. |\n| 422 | `already_purchased` | The user already has the lifetime deal. |\n| 422 | `billing_details_required` | The user must add a billing country in SignWith before buying credits. |\n| 429 | `rate_limited` | Too many requests (or more than 20 feedback messages in an hour). Wait for `Retry-After` seconds when present. |\n| 429 | `remind_too_soon` | Signers of this request were reminded less than an hour ago, or (`resend: true`) this signer was emailed less than 10 minutes ago. |\n| 500 | `internal_error` | Something went wrong on SignWith's side. Retry (with the same `Idempotency-Key` for `POST`s); contact support if it persists. |\n| 502 | `payment_provider_error` | The payment provider couldn't start the checkout. Try again later. |\n\n## Pagination\n\nList endpoints use cursor pagination and return newest items first:\n\n```json\n{ \"object\": \"list\", \"data\": [ ... ], \"has_more\": true, \"next_cursor\": 4812 }\n```\n\n- `limit` — items per page, 1–100 (default 20). Values outside that range fall back to the default or the maximum.\n- `cursor` — pass the `next_cursor` of the previous page to get the next one.\n\nKeep requesting while `has_more` is `true`. `next_cursor` is `null` on the last page.\n\n## Rate limits\n\nEach API key may make **300 requests per minute** (fixed one-minute windows). Every\nauthenticated response includes:\n\n| Header | Meaning |\n|--------|---------|\n| `RateLimit-Limit` | Requests allowed per window. |\n| `RateLimit-Remaining` | Requests left in the current window. |\n| `RateLimit-Reset` | Seconds until the window resets. |\n\nOver the limit, the API returns `429 rate_limited` with a `Retry-After` header (seconds).\n\n`POST /feedback` has an extra limit of **20 messages per user per clock hour**; beyond it the\nAPI returns `429 rate_limited` with `Retry-After` (seconds until the next clock hour).\n\n## Buying credits\n\nOne credit per signed document: a document (template) uses a credit the first time it is signed;\nsending the same document again doesn't use another (see [`GET /credits`](#operation/getCredits)). When an account\nruns out, `POST /signature_requests` returns `402 insufficient_credits`. An API client or AI\nagent can recover without leaving the conversation:\n\n1. `GET /credit_packs` — list the packs on sale and pick one with the user.\n2. `POST /checkouts` with `credit_pack_id` (and an optional `discount_code`). Send an\n   `Idempotency-Key` so a retry doesn't start a second payment.\n3. Send the user the returned `checkout_url`; they pay on the hosted payment page. The API never\n   handles card details.\n4. Poll `GET /checkouts/{id}` (every few seconds, then less often) until `status` is `completed`\n   (credits have been added) or `failed`.\n5. Retry the original request. If you sent it with an `Idempotency-Key`, reuse the same key and\n   body — failed responses aren't stored, so the retry runs normally.\n\nCheckouts need a full-access key and a billing country on the user's SignWith profile\n(`422 billing_details_required` otherwise).\n\n## Idempotency\n\nNetwork errors happen. To safely retry a `POST` without creating a duplicate (for example sending\nthe same signature request twice), send a unique `Idempotency-Key` header — a UUID v4 works well:\n\n```http\nIdempotency-Key: 5f1c6c1e-0b1a-4d38-9d0e-8a7a1f2f8d11\n```\n\n- The first successful (2xx) response is stored for **24 hours** per API key and path. Retries with\n  the same key return that stored response with the header `Idempotent-Replayed: true`.\n- Failed responses are not stored, so you can retry a failed request with the same key.\n- If the original request is still in progress, the retry returns `409 idempotency_key_in_use`.\n- Reusing a key with a different request body returns `422 idempotency_key_reused`. Use a new key for each distinct request.\n\n## Webhooks & signature verification\n\nAdd webhook endpoints in **Settings → Webhooks** and pick the events you want. SignWith sends a\n`POST` with a JSON body to your URL:\n\n```json\n{\n  \"id\": \"evt_7Qm2Vt9sKd3LpXa8RzYw1bNc\",\n  \"type\": \"signer.signed\",\n  \"created_at\": \"2026-09-27T10:15:00Z\",\n  \"data\": { \"object\": \"signer\", \"id\": 9121, ... }\n}\n```\n\n`data` uses the same shapes as API responses and reflects the object's state at delivery time.\nUse `id` to ignore duplicate deliveries. Respond with any 2xx within 30 seconds; other responses\n(and timeouts) are retried with exponential back-off (1, 2, 4, 8 … minutes). Each event is\ndelivered at most **10 times in total** (the first attempt plus up to 9 retries).\n\nWebhook URLs must be public `http://` or `https://` addresses. URLs that point at private,\nloopback or link-local networks (e.g. `localhost`, `10.0.0.0/8`, `192.168.0.0/16`) are rejected\nwhen you save the endpoint and again at delivery time. Use a tunnel such as ngrok to test locally.\n\nEach request carries these headers:\n\n| Header | Example | Meaning |\n|--------|---------|---------|\n| `X-SignWith-Event` | `signer.signed` | Event type (same as `type`). |\n| `X-SignWith-Delivery` | `2b1e…` | Unique ID of this delivery attempt. |\n| `X-SignWith-Signature` | `t=1790503200,v1=5d41…` | Timestamp and HMAC-SHA256 signature. |\n| `User-Agent` | `SignWith Webhook` | |\n\nAny custom headers you configured on the endpoint are sent too.\n\n**Verify every request.** Compute HMAC-SHA256 of `\"<t>.<raw request body>\"` with the endpoint's\nsigning secret (shown on the webhook's settings page), hex-encode it and compare it to `v1` using a\nconstant-time comparison. Reject requests whose `t` is more than a few minutes old to stop replays.\n\n```js\nconst crypto = require('crypto');\n\nfunction verifySignWithWebhook(rawBody, signatureHeader, secret, toleranceSeconds = 300) {\n  const parts = Object.fromEntries(\n    signatureHeader.split(',').map((part) => part.trim().split('=', 2))\n  );\n  const timestamp = Number(parts.t);\n  if (!timestamp || !parts.v1) return false;\n  if (Math.abs(Date.now() / 1000 - timestamp) > toleranceSeconds) return false;\n\n  const expected = crypto\n    .createHmac('sha256', secret)\n    .update(`${timestamp}.${rawBody}`)\n    .digest('hex');\n\n  const a = Buffer.from(expected, 'hex');\n  const b = Buffer.from(parts.v1, 'hex');\n  return a.length === b.length && crypto.timingSafeEqual(a, b);\n}\n\n// Express: use the raw body, not the parsed JSON.\napp.post('/webhooks/signwith', express.raw({ type: 'application/json' }), (req, res) => {\n  const ok = verifySignWithWebhook(\n    req.body.toString('utf8'),\n    req.get('X-SignWith-Signature'),\n    process.env.SIGNWITH_WEBHOOK_SECRET\n  );\n  if (!ok) return res.status(400).send('Invalid signature');\n\n  const event = JSON.parse(req.body);\n  // handle event.type ...\n  res.sendStatus(200);\n});\n```\n\nThe **Send test event** button on a webhook's settings page sends a `webhook.test` event\nimmediately, whatever events the endpoint is subscribed to.\n\n## AI assistants (MCP)\n\nSignWith also runs an MCP server at `https://app.signwith.co/mcp` (Streamable HTTP), so AI\nassistants such as Claude, ChatGPT or Cursor can use SignWith directly. Each tool runs the matching\nendpoint in this reference, with the same rules, credits and errors.\n\n**Connecting with OAuth (recommended).** Add `https://app.signwith.co/mcp` as a connector. The app\nsends you to SignWith to sign in and approve it, choosing **Full access** or **View only**; no key is\npasted anywhere. Manage or disconnect apps in **Settings → Connected apps**.\n\nIn ChatGPT, the credit purchase tools (`list_credit_packs`, `buy_credits`, `get_checkout`) aren't\noffered and results leave out `purchase_url` and `checkout_url`, because ChatGPT apps may not sell\ndigital goods; out of credits, ChatGPT tells the user to add credits in SignWith.\n\nFor MCP client developers: SignWith follows the MCP authorization spec. An unauthenticated request\nreturns `401` with `WWW-Authenticate: Bearer resource_metadata=\".../.well-known/oauth-protected-resource/mcp\"`.\nThe authorization server (`/.well-known/oauth-authorization-server`) supports authorization code\nwith PKCE (`S256` only), refresh token rotation, Dynamic Client Registration (`/oauth/register`),\nClient ID Metadata Documents, resource indicators (tokens are bound to `https://app.signwith.co/mcp`),\nthe `iss` response parameter and token revocation (`/oauth/revoke`). Scopes are `read` and `write`.\nAccess tokens last an hour; refresh tokens 60 days. OAuth tokens only work on `/mcp`, not on this REST API.\n\n**Connecting with an API key.** Clients without OAuth can send an API key instead:\n\n```bash\nclaude mcp add --transport http signwith https://app.signwith.co/mcp \\\n  --header \"Authorization: Bearer $SIGNWITH_API_KEY\"\n```\n\nA read-only key or a View only connection only lists the tools it can use.\n\nIt offers 18 tools:\n\n| Area | Tools |\n|------|-------|\n| Account | `get_account` (user, environment and credits) |\n| Templates | `list_templates`, `get_template`, `create_template` (documents plus optional `fields`), `update_template` (rename, move, set roles or replace `fields`), `duplicate_template`, `archive_template` |\n| Signature requests | `send_signature_request`, `list_signature_requests`, `get_signature_request`, `remind_signers`, `cancel_signature_request`, `update_signer` |\n| Billing | `list_credit_packs`, `buy_credits`, `get_checkout` |\n| Other | `verify_document`, `send_feedback` |\n\nProtocol notes:\n\n- The server is stateless and only answers `POST /mcp`; `GET` and `DELETE` return `405`.\n- A tool call that fails returns a normal result with `isError: true` and the API's error `code`\n  and `message`, so the assistant can explain it or fix its arguments. Calls missing required\n  arguments fail the same way, naming the missing arguments.\n- JSON-RPC messages without an `id` are notifications: they're not executed and get no response\n  (a request made only of notifications returns HTTP `202`). An empty batch returns error `-32600`.\n\nEverything done through the API or MCP is recorded against the API key or connected app that did\nit (see **Settings → API activity**), and records it creates have `source` set to `api` or `mcp`.\n\n## Glossary\n\n- **Template** — a reusable set of one or more documents (PDFs or images) with fields placed on\n  them and one or more roles. You create signature requests from templates.\n- **Role** — a named party on a template, such as \"Client\" or \"Landlord\". Every field belongs to a\n  role; when you send a signature request, each signer fills one role.\n- **Field** — a place on a document where a signer enters something: a signature, initials, text,\n  a date, a checkbox, a selection, an image and so on. Fields have a name, a type, a role and one\n  or more areas (where they sit on a page). Fillable PDF form fields are turned into template fields\n  automatically when you upload a PDF; you can also place fields with the `fields` parameter of\n  `POST /templates` and `PATCH /templates/{id}`, or in the editor (`edit_url`).\n- **Signature request** — one instance of a template sent to specific people for signing. It\n  holds the signers, their progress, and — once everyone has signed — the signed documents and\n  audit trail.\n- **Signer** — a person (identified by email and/or phone) asked to fill a role in a signature\n  request. Each signer gets their own private signing link.\n- **Prefill** — values you set on a signer's fields before they sign, keyed by field name (e.g.\n  `{\"Full name\": \"Ada Lovelace\"}`). Signers see the values already filled in.\n- **Signing order** — `sequential` (default): signers are invited one at a time in the order of\n  the template's roles; the next signer is invited when the previous one signs. `parallel`:\n  every signer is invited at once and can sign in any order.\n- **Statuses**\n  - Signature request: `sent` (nobody has signed yet), `in_progress` (at least one signer has\n    signed), `completed` (everyone signed), `declined` (a signer declined), `expired` (passed\n    `expires_at` before completion), `canceled` (canceled via the API or dashboard).\n  - Signer: `waiting` (an earlier signer in a sequential request has to sign first), `ready` (it's\n    their turn but they weren't emailed — e.g. `send_email: false` or the email is still queued; share\n    `signing_url` yourself), `sent` (invited), `viewed` (opened the document), `signed`, `declined`.\n"},"servers":[{"url":"https://app.signwith.co/api/v1","description":"Production (use a `sw_live_` or `sw_test_` key)"}],"security":[{"apiKey":[]}],"tags":[{"name":"Account","description":"Who the API key belongs to and how many credits are left."},{"name":"Templates","description":"Reusable documents with fields and roles, used to create signature requests."},{"name":"Signature requests","description":"Send a template to people for signing and track progress."},{"name":"Signers","description":"Individual people on a signature request."},{"name":"Documents","description":"Check signed PDFs."},{"name":"Billing","description":"Buy credits from the API. When a request fails with `402 insufficient_credits`:\n`GET /credit_packs` → `POST /checkouts` → send the user the `checkout_url` → poll\n`GET /checkouts/{id}` until `status` is `completed` → retry the original request with the same\n`Idempotency-Key`. See [Buying credits](#section/Buying-credits).\n"},{"name":"Feedback","description":"Report bugs, feature requests, feedback or questions to the SignWith team on the user's\nbehalf. Meant for API clients and AI agents such as the SignWith MCP server.\n"}],"paths":{"/me":{"get":{"operationId":"getMe","tags":["Account"],"summary":"Get the current API key's user and account","description":"Returns the user and account the API key acts as, the environment (`live` or `test`) and\ndetails of the key itself. Call it when setting up an integration to check you're using the\nright key, or as a cheap health check for your stored credentials.\n","responses":{"200":{"description":"The key's user, account and environment.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"},"example":{"object":"me","user":{"id":42,"email":"ada@acme.co","name":"Ada Lovelace"},"account":{"id":7,"name":"Acme Inc."},"environment":"live","api_key":{"id":118,"name":"Production CRM","permission":"full","expires_at":null}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/credits":{"get":{"operationId":"getCredits","tags":["Account"],"summary":"Get the credit balance","description":"Returns how many credits the key's user has and whether they can send another document.\nOne credit per signed document: a document (template) uses a credit the first time it is\nsigned; sending the same document again doesn't use another. Check `can_send` before creating signature\nrequests in bulk so you can prompt users to top up instead of hitting `402 insufficient_credits`.\nUsers on a lifetime plan have `unlimited: true` and `available: null`. To buy more credits\nfrom the API see [`GET /credit_packs`](#operation/listCreditPacks); `purchase_url` is the\nequivalent page in the SignWith dashboard.\n","responses":{"200":{"description":"The credit balance.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Credits"},"examples":{"metered":{"summary":"Pay-as-you-go account","value":{"object":"credits","unlimited":false,"available":12,"overdraft_limit":-3,"can_send":true,"billing":"One credit per signed document: a document (template) uses a credit the first time it is signed; sending the same document again doesn't use another.","purchase_url":"https://app.signwith.co/credit_plans"}},"unlimited":{"summary":"Lifetime plan","value":{"object":"credits","unlimited":true,"available":null,"overdraft_limit":-3,"can_send":true,"billing":"One credit per signed document: a document (template) uses a credit the first time it is signed; sending the same document again doesn't use another.","purchase_url":"https://app.signwith.co/credit_plans"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/templates":{"get":{"operationId":"listTemplates","tags":["Templates"],"summary":"List templates","description":"Lists the templates the key's user can access, newest first. Use it to let users pick a\ntemplate in your app, or to look up a template by your own `external_id` or by folder.\nArchived templates are excluded unless `archived=true`. List items omit `fields` and\n`documents`; fetch a single template to get them.\n","parameters":[{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"name":"q","in":"query","description":"Case-insensitive search on the template name.","schema":{"type":"string"},"example":"lease"},{"name":"archived","in":"query","description":"`true` to list only archived templates instead of active ones.","schema":{"type":"boolean","default":false}},{"name":"external_id","in":"query","description":"Only templates with this `external_id`.","schema":{"type":"string"},"example":"lease-v3"},{"name":"folder","in":"query","description":"Only templates in the folder with this exact name.","schema":{"type":"string"},"example":"Leasing"}],"responses":{"200":{"description":"A page of templates.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/List"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/TemplateSummary"}}}}]},"example":{"object":"list","data":[{"object":"template","id":311,"name":"Residential lease","external_id":"lease-v3","folder":"Leasing","roles":["Tenant","Landlord"],"edit_url":"https://app.signwith.co/templates/311/edit","created_by":{"id":42,"email":"ada@acme.co","name":"Ada Lovelace"},"archived_at":null,"created_at":"2026-09-20T09:12:44Z","updated_at":"2026-09-21T16:03:10Z"}],"has_more":true,"next_cursor":311}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"operationId":"createTemplate","tags":["Templates"],"summary":"Create a template from documents","description":"Uploads one or more documents (PDF or image, up to 10 per template, 25 MB each) and creates a\ntemplate from them. Fillable PDF form fields are converted into template fields automatically.\n\n**Text tags.** Write fields into the document itself and they're placed where the tag is, with\nthe tag text hidden: `{{Client signature;type=signature;role=Client}}`. The first part is the\nfield name, followed by `key=value` settings: `type` (any field type; default `text`), `role`\n(created on the template if new), `required` (default `true`), `options` (comma-separated, for\n`select`) and `width`/`height` in points. `{{signature;role=Client}}` on its own is a signature\nfield named \"Signature\". The same tag on several pages becomes one field (e.g. initials on every\npage). When every tag names a role, the template gets exactly those roles. Tags work in PDFs from\nany editor; keep each one on a line of its own text, or colour it white, for the cleanest result.\n\nTo place signature and other fields yourself, pass `fields` (JSON requests): each field has a\n`type`, a `role` and one or more `areas` giving its page and position as fractions of the page\nsize. Roles named in `fields` are created on the template. Otherwise, open the returned\n`edit_url` and place fields in the SignWith editor — a template needs at least one field before\nit can be sent.\n\nUse it to sync documents generated by your system into SignWith. Two request formats are\nsupported:\n\n- `application/json` — `documents` is an array of `{ name, file }` where `file` is base64\n  content (a `data:` URI prefix is allowed) or an `https://` URL SignWith downloads.\n- `multipart/form-data` — upload files directly as `documents[]`.\n\nIf `name` is omitted, the first document's filename is used. If `folder` doesn't exist it is\ncreated. Invalid `fields` return `422 invalid_field`. Triggers the `template.created` webhook.\n","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTemplateJsonRequest"},"examples":{"url":{"summary":"Document from a URL","value":{"name":"Residential lease","external_id":"lease-v3","folder":"Leasing","documents":[{"name":"Lease agreement","file":"https://files.acme.co/templates/lease-v3.pdf"}]}},"base64":{"summary":"Base64 document with password","value":{"name":"NDA","documents":[{"name":"nda.pdf","file":"JVBERi0xLjcKJeLjz9MKMSAwIG9iago8PC9UeXBlL0NhdGFsb2cvUGFnZXMgMiAwIFI+PgplbmRvYmoK..."}],"password":"s3cret"}},"withFields":{"summary":"Document with signature fields placed by the API","value":{"name":"Consulting agreement","documents":[{"name":"Consulting agreement","file":"https://files.acme.co/contracts/consulting.pdf"}],"fields":[{"name":"Client name","type":"text","role":"Client","areas":[{"page":1,"x":0.12,"y":0.18,"w":0.35,"h":0.03}]},{"name":"Client signature","type":"signature","role":"Client","areas":[{"page":3,"x":0.1,"y":0.78,"w":0.3,"h":0.06}]},{"name":"Consultant signature","type":"signature","role":"Consultant","areas":[{"page":3,"x":0.55,"y":0.78,"w":0.3,"h":0.06}]},{"name":"Payment terms","type":"select","role":"Client","required":false,"options":["Net 15","Net 30"],"areas":[{"page":2,"x":0.12,"y":0.42,"w":0.2,"h":0.03}]}]}}}},"multipart/form-data":{"schema":{"$ref":"#/components/schemas/CreateTemplateMultipartRequest"},"encoding":{"documents[]":{"contentType":"application/pdf, image/png, image/jpeg"}},"example":{"name":"Residential lease","folder":"Leasing","documents[]":["lease.pdf","addendum.pdf"]}}}},"responses":{"201":{"description":"The template was created.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Template"},"example":{"object":"template","id":311,"name":"Residential lease","external_id":"lease-v3","folder":"Leasing","roles":["Tenant","Landlord"],"edit_url":"https://app.signwith.co/templates/311/edit","created_by":{"id":42,"email":"ada@acme.co","name":"Ada Lovelace"},"archived_at":null,"created_at":"2026-09-20T09:12:44Z","updated_at":"2026-09-21T16:03:10Z","fields":[{"id":"0f9c2b7e-5d1a-4e8b-9a61-3c2e7d4f1a90","name":"Tenant name","type":"text","role":"Tenant","required":true},{"id":"6a3e1d42-8b7c-4f19-a0d5-2e9b4c7f8a13","name":"Monthly rent","type":"number","role":"Tenant","required":true},{"id":"b2d8f4a1-3c6e-4a7b-8d92-5f1e0c3a9b76","name":"Start date","type":"date","role":"Tenant","required":true},{"id":"91c7e3b5-2a4d-4f8e-b610-7d3a5c9e2f48","name":"Pets","type":"select","role":"Tenant","required":false,"options":["None","Cat","Dog"]},{"id":"4e8a2c6f-9b1d-4a3e-8c57-1f6d0b9e3a24","name":"Tenant signature","type":"signature","role":"Tenant","required":true},{"id":"c5f1a9d3-7e2b-4c8a-9f60-3b8e4d2a7c15","name":"Landlord signature","type":"signature","role":"Landlord","required":true}],"documents":[{"id":7730,"name":"Lease agreement","url":"https://app.signwith.co/file/eyJfcmFpbHMiOnsiZGF0YSI6MTIzfX0/lease-agreement.pdf","preview_image_url":"https://app.signwith.co/file/eyJfcmFpbHMiOnsiZGF0YSI6MTI0fX0/0.jpg"}]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/templates/{id}":{"parameters":[{"$ref":"#/components/parameters/TemplateId"}],"get":{"operationId":"getTemplate","tags":["Templates"],"summary":"Get a template","description":"Returns a template with its roles, fields and documents. Use it to find out which roles to\nassign signers to and which field names you can prefill before creating a signature request.\n","responses":{"200":{"description":"The template.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Template"},"examples":{"template":{"$ref":"#/components/examples/Template"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}},"patch":{"operationId":"updateTemplate","tags":["Templates"],"summary":"Update a template","description":"Renames a template, changes its `external_id` or folder, renames its roles, or replaces its\nfields. Use it to keep template metadata in sync with your system, or to place fields on a\ntemplate created without them. Only the parameters you send are changed.\n\n`roles` is matched by position: the first name renames the first role, and so on. Extra names\nadd new roles (without fields). Roles can't be removed through the API.\n\n`fields`, when sent, **replaces all of the template's fields** (send `[]` to remove them all).\nRoles named in `fields` that don't exist yet are added. Invalid fields return\n`422 invalid_field`.\n\nChanges only affect signature requests sent afterwards: requests already sent keep the fields\nand documents they were sent with. `PUT` is accepted as an alias. Triggers the\n`template.updated` webhook.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTemplateRequest"},"examples":{"metadata":{"summary":"Rename and move","value":{"name":"Residential lease (2027)","external_id":"lease-v4","folder":"Leasing","roles":["Tenant","Landlord"]}},"fields":{"summary":"Replace all fields","value":{"fields":[{"name":"Tenant signature","type":"signature","role":"Tenant","areas":[{"page":4,"x":0.1,"y":0.8,"w":0.3,"h":0.06}]},{"name":"Landlord signature","type":"signature","role":"Landlord","areas":[{"page":4,"x":0.55,"y":0.8,"w":0.3,"h":0.06}]}]}}}}}},"responses":{"200":{"description":"The updated template.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Template"},"examples":{"template":{"$ref":"#/components/examples/Template"}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/templates/{id}/duplicate":{"parameters":[{"$ref":"#/components/parameters/TemplateId"}],"post":{"operationId":"duplicateTemplate","tags":["Templates"],"summary":"Duplicate a template","description":"Creates a copy of a template, including its documents, fields and roles. Use it to create a\nvariant (for example a per-customer version) without re-uploading and re-placing fields.\nOptionally give the copy a new name, `external_id` or folder. Triggers the\n`template.created` webhook.\n","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DuplicateTemplateRequest"},"example":{"name":"Residential lease — Riverside Apartments","external_id":"lease-v3-riverside","folder":"Leasing"}}}},"responses":{"201":{"description":"The new template.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Template"},"examples":{"template":{"$ref":"#/components/examples/Template"}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/templates/{id}/archive":{"parameters":[{"$ref":"#/components/parameters/TemplateId"}],"post":{"operationId":"archiveTemplate","tags":["Templates"],"summary":"Archive a template","description":"Archives a template so it no longer shows among active templates. Use it when a document\nversion is retired. Existing signature requests are not affected. Archiving an already\narchived template succeeds and returns it unchanged. The `template.archived` webhook fires only\nthe first time. Archived templates can't be used for new signature requests\n(`422 template_archived`), and signing links of unfinished requests from them stop working.\n","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"The archived template.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Template"},"examples":{"template":{"$ref":"#/components/examples/Template"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/signature_requests":{"get":{"operationId":"listSignatureRequests","tags":["Signature requests"],"summary":"List signature requests","description":"Lists signature requests, newest first. Use it to build a dashboard of outstanding documents\nor to reconcile state if you missed webhooks. List items include signers but not their field\nvalues or the signed documents; fetch a single signature request for those.\n","parameters":[{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"name":"template_id","in":"query","description":"Only signature requests created from this template.","schema":{"type":"integer"},"example":311},{"name":"q","in":"query","description":"Case-insensitive search on signer name, email or phone.","schema":{"type":"string"},"example":"ada@acme.co"},{"name":"status","in":"query","description":"Filter by status. `open` includes requests that are `sent` or `in_progress`; `expired`\nreturns unfinished requests past their `expires_at`. Any other value returns `422 invalid_parameter`.\n","schema":{"type":"string","enum":["open","completed","declined","expired","canceled"]}}],"responses":{"200":{"description":"A page of signature requests.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/List"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/SignatureRequestSummary"}}}}]},"example":{"object":"list","data":[{"object":"signature_request","id":4812,"status":"in_progress","template":{"id":311,"name":"Residential lease"},"signing_order":"sequential","source":"api","created_by":{"id":42,"email":"ada@acme.co","name":"Ada Lovelace"},"signers":[{"object":"signer","id":9120,"signature_request_id":4812,"role":"Tenant","name":"Grace Hopper","email":"grace@example.com","phone":null,"external_id":"cust_8841","metadata":{},"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"},{"object":"signer","id":9121,"signature_request_id":4812,"role":"Landlord","name":"Ada Lovelace","email":"ada@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-27T09:44:53Z"}],"expires_at":"2026-10-27T00:00:00Z","completed_at":null,"canceled_at":null,"created_at":"2026-09-27T09:00:01Z","updated_at":"2026-09-27T09:44:53Z"}],"has_more":false,"next_cursor":null}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"operationId":"createSignatureRequest","tags":["Signature requests"],"summary":"Send a signature request","description":"Creates a signature request from a template and invites the signers. This is the main call\nfor getting a document signed from your product.\n\n- Assign each signer to a template role with `role`. Signers without a `role` fill the\n  template's roles in order. You can't send more signers than the template has roles, and\n  each role can be given to only one signer.\n- `signers` is a list of objects. Each signer needs a valid `email` or a `phone`\n  (`422 invalid_signer`); `prefill` and `metadata` must be objects (`422 invalid_parameter`).\n- `expires_at` must be an ISO 8601 date-time in the future (`422 invalid_parameter`).\n- Use `prefill` to fill fields for a signer ahead of time, keyed by field name (see\n  [`GET /templates/{id}`](#operation/getTemplate) for field names).\n- Set `send_email: false` to create the request without emailing anyone — for example to\n  embed or deliver the signers' `signing_url` yourself. Those signers have status `ready`\n  when it's their turn.\n- Set `require_email_otp: true` to require each signer to enter a one-time code sent to\n  their email before they can view and sign.\n\nThe template must be active (`422 template_archived`) and have at least one field\n(`422 template_has_no_fields` — add fields with [`PATCH /templates/{id}`](#operation/updateTemplate)\nor in the editor). The request keeps a snapshot of the template's fields and documents, so later\ntemplate edits don't change what these signers see.\n\nThe first signature request from a template uses one credit when it's signed; if you have no\ncredits left the request is rejected with `402 insufficient_credits` — see\n[Buying credits](#section/Buying-credits) for how to top up and retry. Send an\n`Idempotency-Key` so retries don't send the document twice. Triggers the\n`signature_request.created` webhook.\n","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSignatureRequestRequest"},"examples":{"sequential":{"summary":"Two signers, tenant signs first","value":{"template_id":311,"signing_order":"sequential","expires_at":"2026-10-27T00:00:00Z","reply_to":"leasing@acme.co","redirect_url":"https://acme.co/lease/signed","message":{"subject":"Your lease for 14 Riverside Ave is ready to sign","body":"Hi Grace, please review and sign your lease."},"signers":[{"role":"Tenant","name":"Grace Hopper","email":"grace@example.com","external_id":"cust_8841","metadata":{"crm_deal_id":"D-2291"},"prefill":{"Tenant name":"Grace Hopper","Monthly rent":"2150","Start date":"2026-11-01"},"require_email_otp":true},{"role":"Landlord","name":"Ada Lovelace","email":"ada@acme.co"}]}},"silent":{"summary":"No emails — deliver the signing links yourself","value":{"template_id":311,"signing_order":"parallel","send_email":false,"signers":[{"role":"Tenant","name":"Grace Hopper","email":"grace@example.com"},{"role":"Landlord","name":"Ada Lovelace","email":"ada@acme.co"}]}}}}}},"responses":{"201":{"description":"The signature request was created and signers were invited.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignatureRequest"},"example":{"object":"signature_request","id":4812,"status":"sent","template":{"id":311,"name":"Residential lease"},"signing_order":"sequential","source":"api","created_by":{"id":42,"email":"ada@acme.co","name":"Ada Lovelace"},"signers":[{"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":"sent","signing_url":"https://app.signwith.co/s/Hn3cW8yRk2Qe","sent_at":"2026-09-27T09:00:02Z","viewed_at":null,"signed_at":null,"declined_at":null,"created_at":"2026-09-27T09:00:01Z","updated_at":"2026-09-27T09:00:02Z","values":[{"field":"Tenant name","value":"Grace Hopper"},{"field":"Monthly rent","value":"2150"},{"field":"Start date","value":"2026-11-01"}]},{"object":"signer","id":9121,"signature_request_id":4812,"role":"Landlord","name":"Ada Lovelace","email":"ada@acme.co","phone":null,"external_id":null,"metadata":{},"status":"waiting","signing_url":"https://app.signwith.co/s/q8LkT2mZpV4r","sent_at":null,"viewed_at":null,"signed_at":null,"declined_at":null,"created_at":"2026-09-27T09:00:01Z","updated_at":"2026-09-27T09:00:01Z","values":[]}],"expires_at":"2026-10-27T00:00:00Z","completed_at":null,"canceled_at":null,"created_at":"2026-09-27T09:00:01Z","updated_at":"2026-09-27T09:00:01Z"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/signature_requests/{id}":{"parameters":[{"$ref":"#/components/parameters/SignatureRequestId"}],"get":{"operationId":"getSignatureRequest","tags":["Signature requests"],"summary":"Get a signature request","description":"Returns a signature request with every signer's progress and field values. Once everyone has\nsigned (`status: completed`) it also includes download links for the signed `documents`, the\n`audit_trail_url` and, when available, a `combined_document_url`. Use it after a\n`signature_request.completed` webhook to download the final files.\n","responses":{"200":{"description":"The signature request.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignatureRequest"},"examples":{"completed":{"$ref":"#/components/examples/CompletedSignatureRequest"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/signature_requests/{id}/cancel":{"parameters":[{"$ref":"#/components/parameters/SignatureRequestId"}],"post":{"operationId":"cancelSignatureRequest","tags":["Signature requests"],"summary":"Cancel a signature request","description":"Cancels a signature request so its signing links stop working — for example when a deal falls\nthrough or the document was sent with a mistake. Fully signed requests can't be canceled\n(`422 already_completed`). Canceling an already canceled request succeeds and returns it\nunchanged. Triggers the `signature_request.canceled` webhook.\n","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"The canceled signature request.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignatureRequest"},"examples":{"canceled":{"$ref":"#/components/examples/CanceledSignatureRequest"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/signature_requests/{id}/remind":{"parameters":[{"$ref":"#/components/parameters/SignatureRequestId"}],"post":{"operationId":"remindSignatureRequest","tags":["Signature requests"],"summary":"Remind waiting signers","description":"Emails the signing link again to every signer who has been invited, hasn't signed or declined\nyet, and has an email address. Use it to nudge people who haven't acted. Signers still\nwaiting for their turn in a sequential request are not reminded.\n\nA request can be reminded at most once per hour (`429 remind_too_soon`, with `Retry-After`\nset to the seconds left until it can be reminded again). Returns\n`422 not_open` for canceled, declined or expired requests and `422 nothing_to_remind` when nobody is\nwaiting.\n","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Which signers were reminded.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Reminder"},"example":{"object":"reminder","signature_request_id":4812,"reminded_signer_ids":[9121]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/signers/{id}":{"parameters":[{"name":"id","in":"path","required":true,"description":"Signer ID.","schema":{"type":"integer"},"example":9121}],"get":{"operationId":"getSigner","tags":["Signers"],"summary":"Get a signer","description":"Returns one signer with their status, signing link, field values and — once they've signed —\ntheir signed documents. Use it when you track signers individually (e.g. from a `signer.*`\nwebhook or by storing signer IDs against your own users).\n","responses":{"200":{"description":"The signer.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Signer"},"examples":{"signed":{"$ref":"#/components/examples/SignedSigner"}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}},"patch":{"operationId":"updateSigner","tags":["Signers"],"summary":"Update a signer","description":"Corrects a signer's details or prefills more of their fields before they sign — for example\nwhen a customer gave the wrong email address. Only the parameters you send are changed;\n`prefill` values are merged with existing ones.\n\nSet `resend: true` to email the signing link again (only if the signer was already invited; at most\nonce every 10 minutes per signer, otherwise `429 remind_too_soon` with `Retry-After`).\nSigners who have signed or declined can't be changed (`422 signer_finished`), nor can signers\nof a canceled, expired or declined request (`422 not_open`). The signer must keep an `email`\nor a `phone`, emails must be valid, and `prefill` must be an object (all `422 invalid_parameter`).\n`PUT` is accepted as an alias.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSignerRequest"},"example":{"email":"ada.lovelace@acme.co","prefill":{"Landlord name":"Ada Lovelace"},"resend":true}}}},"responses":{"200":{"description":"The updated signer.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Signer"},"example":{"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"}]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/documents/verify":{"post":{"operationId":"verifyDocument","tags":["Documents"],"summary":"Verify a signed PDF","description":"Checks a PDF: whether SignWith issued it (it matches a document completed in SignWith) and\nwhether each embedded digital signature is valid and the document hasn't been modified since.\nUse it when a signed document comes back to you from a third party and you need to confirm\nit's authentic. Send the PDF as base64 in a JSON `file` property, or upload it as a\nmultipart `file`.\n\nThis call doesn't change anything, so read-only API keys may use it. Returns\n`422 invalid_document` if `file` isn't a PDF.\n","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"byte","contentEncoding":"base64","description":"The PDF, base64-encoded."}}},"example":{"file":"JVBERi0xLjcKJeLjz9MKMSAwIG9iago8PC9UeXBlL0NhdGFsb2cvUGFnZXMgMiAwIFI+PgplbmRvYmoK..."}},"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","contentMediaType":"application/pdf","description":"The PDF file."}}},"encoding":{"file":{"contentType":"application/pdf"}}}}},"responses":{"200":{"description":"The verification result.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentVerification"},"example":{"object":"document_verification","issued_by_signwith":true,"signatures":[{"signer_name":"SignWith","signed_at":"2026-09-27T10:15:02Z","reason":"Signed by Grace Hopper, Ada Lovelace","valid":true,"messages":[{"type":"info","content":"Signature valid"},{"type":"info","content":"Certificate is trusted"}]}]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/credit_packs":{"get":{"operationId":"listCreditPacks","tags":["Billing"],"summary":"List credit packs","description":"Lists the credit packs that can be bought, cheapest first. Call it after a\n`402 insufficient_credits` (or when `GET /credits` shows `can_send: false`) to show the user\ntheir options before starting a checkout. The lifetime deal (`unlimited: true`) is left out\nfor users who already have it. Returns every pack in one page (`has_more` is always `false`).\n","responses":{"200":{"description":"The credit packs on sale.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/List"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/CreditPack"}}}}]},"example":{"object":"list","data":[{"object":"credit_pack","id":3,"name":"Basic","description":"10 documents","credits":10,"unlimited":false,"price":"9.00","currency":"USD","price_per_credit":"0.90"},{"object":"credit_pack","id":4,"name":"Pro","description":"25 documents","credits":25,"unlimited":false,"price":"19.00","currency":"USD","price_per_credit":"0.76"},{"object":"credit_pack","id":5,"name":"Business","description":"50 documents","credits":50,"unlimited":false,"price":"29.00","currency":"USD","price_per_credit":"0.58"},{"object":"credit_pack","id":9,"name":"Lifetime deal","description":"Unlimited documents, forever","credits":null,"unlimited":true,"price":"149.00","currency":"USD","price_per_credit":null}],"has_more":false,"next_cursor":null}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/checkouts":{"post":{"operationId":"createCheckout","tags":["Billing"],"summary":"Start a credit purchase","description":"Starts buying a credit pack and returns a hosted `checkout_url` for the user to pay on.\nPayment happens entirely on the payment provider's page; credits are added once the provider\nconfirms the payment. Poll [`GET /checkouts/{id}`](#operation/getCheckout) to find out when\nthat happens, then retry the request that failed with `402 insufficient_credits`.\n\nAn optional `discount_code` applies a discount if it is active, not used up and valid for\nthe chosen pack (`422 invalid_discount_code` otherwise); the returned `credit_pack` then\ndescribes the discounted offer. Requires a full-access key and a billing country on the\nuser's SignWith profile (`422 billing_details_required`). Buying the lifetime deal twice\nreturns `422 already_purchased`. If the payment provider can't start the payment the API\nreturns `502 payment_provider_error`.\n\nEach call starts a new checkout, so send an `Idempotency-Key` to make retries safe.\n","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCheckoutRequest"},"examples":{"basic":{"summary":"Buy a pack","value":{"credit_pack_id":4}},"discount":{"summary":"With a discount code","value":{"credit_pack_id":4,"discount_code":"LAUNCH20"}}}}}},"responses":{"201":{"description":"The checkout was started. Send the user to `checkout_url`.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Checkout"},"examples":{"pending":{"$ref":"#/components/examples/PendingCheckout"}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"},"502":{"$ref":"#/components/responses/BadGateway"}}}},"/checkouts/{id}":{"parameters":[{"name":"id","in":"path","required":true,"description":"Checkout ID (the `id` returned by `POST /checkouts`).","schema":{"type":"string","format":"uuid"},"example":"3f6b2c1a-8d4e-4b7a-9c20-5e1f7a9d3b84"}],"get":{"operationId":"getCheckout","tags":["Billing"],"summary":"Get a checkout","description":"Returns a checkout's status. Poll it after sending the user the `checkout_url`:\n`pending` means the user hasn't paid yet (or the payment is still being confirmed),\n`completed` means the credits have been added, and `failed` means the payment failed or was\ncanceled — start a new checkout to try again. `checkout_url` is only returned while the\ncheckout is `pending`. Only checkouts started by the key's user can be read.\n","responses":{"200":{"description":"The checkout.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Checkout"},"examples":{"pending":{"$ref":"#/components/examples/PendingCheckout"},"completed":{"summary":"Paid — credits added","value":{"object":"checkout","id":"3f6b2c1a-8d4e-4b7a-9c20-5e1f7a9d3b84","status":"completed","credit_pack":{"object":"credit_pack","id":4,"name":"Business","description":"50 documents","credits":50,"unlimited":false,"price":"29.00","currency":"USD","price_per_credit":"0.58"},"amount":"29.00","currency":"USD","discount_code":null,"checkout_url":null,"completed_at":"2026-09-27T11:24:09Z","created_at":"2026-09-27T11:20:31Z"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/feedback":{"post":{"operationId":"createFeedback","tags":["Feedback"],"summary":"Send feedback to the SignWith team","description":"Sends a bug report, feature request, general feedback or question to the SignWith team on\nthe user's behalf. This is how API clients and AI agents — for example the SignWith MCP\nserver (recorded with source `mcp`) — pass on problems or ideas the user mentions, without\nthe user having to leave their tool. The team is notified straight away.\n\nInclude what happened and, in `context`, identifiers that help reproduce it (the failing\n`error_code`, `signature_request_id`, etc.). Don't include passwords, API keys or document\ncontents. Read-only keys may call it. Limited to 20 messages per user per hour\n(`429 rate_limited`).\n","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFeedbackRequest"},"examples":{"bug":{"summary":"Bug reported by an AI agent","value":{"type":"bug","message":"Prefilling the \"Start date\" field with 2026-11-01 shows an empty date to the signer.","context":{"client":"claude-desktop","client_version":"1.4.2","tool":"send_signature_request","signature_request_id":4812,"template_id":311}}},"feature":{"summary":"Feature request","value":{"type":"feature_request","message":"Please let me set a different reminder schedule per signature request."}}}}}},"responses":{"201":{"description":"The feedback was received.","headers":{"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"},"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackReceipt"},"example":{"object":"feedback","id":57,"type":"bug","status":"received","message":"Thanks! The SignWith team has been notified."}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/UnprocessableEntity"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/InternalError"}}}}},"webhooks":{"signature_request.created":{"post":{"operationId":"onSignatureRequestCreated","tags":["Signature requests"],"summary":"A signature request was sent","description":"Sent when a signature request is created — from the API, the dashboard or a shared signing\nlink. `data` is a [SignatureRequest](#/components/schemas/SignatureRequest).\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignatureRequestEvent"},"example":{"id":"evt_4Kc9QmT2vXw8ZpLs7NbR3yAd","type":"signature_request.created","created_at":"2026-09-27T09:00:01Z","data":{"object":"signature_request","id":4812,"status":"sent","template":{"id":311,"name":"Residential lease"},"signing_order":"sequential","source":"api","created_by":{"id":42,"email":"ada@acme.co","name":"Ada Lovelace"},"signers":[{"object":"signer","id":9120,"signature_request_id":4812,"role":"Tenant","name":"Grace Hopper","email":"grace@example.com","phone":null,"external_id":"cust_8841","metadata":{},"status":"sent","signing_url":"https://app.signwith.co/s/Hn3cW8yRk2Qe","sent_at":"2026-09-27T09:00:02Z","viewed_at":null,"signed_at":null,"declined_at":null,"created_at":"2026-09-27T09:00:01Z","updated_at":"2026-09-27T09:00:02Z","values":[]}],"expires_at":null,"completed_at":null,"canceled_at":null,"created_at":"2026-09-27T09:00:01Z","updated_at":"2026-09-27T09:00:01Z"}}}}},"responses":{"200":{"$ref":"#/components/responses/WebhookReceived"}}}},"signature_request.completed":{"post":{"operationId":"onSignatureRequestCompleted","tags":["Signature requests"],"summary":"Every signer has signed","description":"Sent when the last signer signs. `data` is a [SignatureRequest](#/components/schemas/SignatureRequest)\nwith `status: completed`, including links to the signed documents and audit trail. If a link\nis `null`, fetch the signature request again shortly afterwards. Subscribed by default for new\nendpoints.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignatureRequestEvent"},"example":{"id":"evt_9RtB2wLx5HqN8cVm3KpZ7sYe","type":"signature_request.completed","created_at":"2026-09-27T10:15:00Z","data":{"object":"signature_request","id":4812,"status":"completed","template":{"id":311,"name":"Residential lease"},"signing_order":"sequential","source":"api","created_by":{"id":42,"email":"ada@acme.co","name":"Ada Lovelace"},"signers":[{"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":"Start date","value":"2026-11-01"},{"field":"Pets","value":"Cat"},{"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"}]},{"object":"signer","id":9121,"signature_request_id":4812,"role":"Landlord","name":"Ada Lovelace","email":"ada@acme.co","phone":null,"external_id":null,"metadata":{},"status":"signed","signing_url":null,"sent_at":"2026-09-27T09:44:53Z","viewed_at":"2026-09-27T10:12:30Z","signed_at":"2026-09-27T10:14:58Z","declined_at":null,"created_at":"2026-09-27T09:00:01Z","updated_at":"2026-09-27T10:14:58Z","values":[{"field":"Landlord signature","value":"https://app.signwith.co/file/eyJfcmFpbHMiOnsiZGF0YSI6NTYwfX0/signature.png"}],"documents":[{"name":"Lease agreement","url":"https://app.signwith.co/file/eyJfcmFpbHMiOnsiZGF0YSI6NTYxfX0/lease-agreement.pdf"}]}],"expires_at":"2026-10-27T00:00:00Z","completed_at":"2026-09-27T10:14:58Z","canceled_at":null,"created_at":"2026-09-27T09:00:01Z","updated_at":"2026-09-27T10:14:58Z","documents":[{"name":"Lease agreement","url":"https://app.signwith.co/file/eyJfcmFpbHMiOnsiZGF0YSI6NTYxfX0/lease-agreement.pdf"}],"audit_trail_url":"https://app.signwith.co/file/eyJfcmFpbHMiOnsiZGF0YSI6NTYyfX0/audit-trail.pdf","combined_document_url":null}}}}},"responses":{"200":{"$ref":"#/components/responses/WebhookReceived"}}}},"signature_request.canceled":{"post":{"operationId":"onSignatureRequestCanceled","tags":["Signature requests"],"summary":"A signature request was canceled","description":"Sent when a signature request is canceled from the API or the dashboard. `data` is a\n[SignatureRequest](#/components/schemas/SignatureRequest) with `status: canceled`.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignatureRequestEvent"},"example":{"id":"evt_2HsW7kQp9ZxT4mBn6LcR8vYd","type":"signature_request.canceled","created_at":"2026-09-28T08:30:12Z","data":{"object":"signature_request","id":4812,"status":"canceled","template":{"id":311,"name":"Residential lease"},"signing_order":"sequential","source":"api","created_by":{"id":42,"email":"ada@acme.co","name":"Ada Lovelace"},"signers":[{"object":"signer","id":9120,"signature_request_id":4812,"role":"Tenant","name":"Grace Hopper","email":"grace@example.com","phone":null,"external_id":"cust_8841","metadata":{},"status":"viewed","signing_url":"https://app.signwith.co/s/Hn3cW8yRk2Qe","sent_at":"2026-09-27T09:00:02Z","viewed_at":"2026-09-27T09:41:18Z","signed_at":null,"declined_at":null,"created_at":"2026-09-27T09:00:01Z","updated_at":"2026-09-27T09:41:18Z","values":[]}],"expires_at":null,"completed_at":null,"canceled_at":"2026-09-28T08:30:12Z","created_at":"2026-09-27T09:00:01Z","updated_at":"2026-09-28T08:30:12Z"}}}}},"responses":{"200":{"$ref":"#/components/responses/WebhookReceived"}}}},"signer.viewed":{"post":{"operationId":"onSignerViewed","tags":["Signers"],"summary":"A signer opened the document","description":"Sent when a signer opens their signing link. `data` is a [Signer](#/components/schemas/Signer)\nplus a short `signature_request` summary.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignerEvent"},"example":{"id":"evt_6NpQ3xVb8KsR2tLm9WcZ4yHe","type":"signer.viewed","created_at":"2026-09-27T09:41:18Z","data":{"object":"signer","id":9120,"signature_request_id":4812,"role":"Tenant","name":"Grace Hopper","email":"grace@example.com","phone":null,"external_id":"cust_8841","metadata":{},"status":"viewed","signing_url":"https://app.signwith.co/s/Hn3cW8yRk2Qe","sent_at":"2026-09-27T09:00:02Z","viewed_at":"2026-09-27T09:41:18Z","signed_at":null,"declined_at":null,"created_at":"2026-09-27T09:00:01Z","updated_at":"2026-09-27T09:41:18Z","values":[{"field":"Tenant name","value":"Grace Hopper"}],"signature_request":{"id":4812,"status":"sent"}}}}}},"responses":{"200":{"$ref":"#/components/responses/WebhookReceived"}}}},"signer.started":{"post":{"operationId":"onSignerStarted","tags":["Signers"],"summary":"A signer started filling in fields","description":"Sent when a signer saves their first field value. Useful for showing \"in progress\" in your UI.\n`data` is a [Signer](#/components/schemas/Signer) plus a short `signature_request` summary.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignerEvent"},"example":{"id":"evt_3TmK8vRx2NqW7pLb5HcZ9sYd","type":"signer.started","created_at":"2026-09-27T09:42:03Z","data":{"object":"signer","id":9120,"signature_request_id":4812,"role":"Tenant","name":"Grace Hopper","email":"grace@example.com","phone":null,"external_id":"cust_8841","metadata":{},"status":"viewed","signing_url":"https://app.signwith.co/s/Hn3cW8yRk2Qe","sent_at":"2026-09-27T09:00:02Z","viewed_at":"2026-09-27T09:41:18Z","signed_at":null,"declined_at":null,"created_at":"2026-09-27T09:00:01Z","updated_at":"2026-09-27T09:42:03Z","values":[{"field":"Tenant name","value":"Grace Hopper"},{"field":"Phone number","value":"+14155550123"}],"signature_request":{"id":4812,"status":"sent"}}}}}},"responses":{"200":{"$ref":"#/components/responses/WebhookReceived"}}}},"signer.signed":{"post":{"operationId":"onSignerSigned","tags":["Signers"],"summary":"A signer finished signing","description":"Sent when a signer completes their part. `data` is a [Signer](#/components/schemas/Signer)\nwith `status: signed`, their field values and signed documents, plus a short\n`signature_request` summary. Subscribed by default for new endpoints.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignerEvent"},"example":{"id":"evt_7Qm2Vt9sKd3LpXa8RzYw1bNc","type":"signer.signed","created_at":"2026-09-27T09:44:51Z","data":{"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":"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"}],"signature_request":{"id":4812,"status":"in_progress"}}}}}},"responses":{"200":{"$ref":"#/components/responses/WebhookReceived"}}}},"signer.declined":{"post":{"operationId":"onSignerDeclined","tags":["Signers"],"summary":"A signer declined to sign","description":"Sent when a signer declines. The signature request's status becomes `declined`. `data` is a\n[Signer](#/components/schemas/Signer) plus a short `signature_request` summary. Subscribed by\ndefault for new endpoints.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignerEvent"},"example":{"id":"evt_8LwR4nKx6TqB2mVp9ZcH3sYe","type":"signer.declined","created_at":"2026-09-27T12:05:40Z","data":{"object":"signer","id":9121,"signature_request_id":4812,"role":"Landlord","name":"Ada Lovelace","email":"ada@acme.co","phone":null,"external_id":null,"metadata":{},"status":"declined","signing_url":null,"sent_at":"2026-09-27T09:44:53Z","viewed_at":"2026-09-27T12:03:11Z","signed_at":null,"declined_at":"2026-09-27T12:05:40Z","created_at":"2026-09-27T09:00:01Z","updated_at":"2026-09-27T12:05:40Z","values":[],"signature_request":{"id":4812,"status":"declined"}}}}}},"responses":{"200":{"$ref":"#/components/responses/WebhookReceived"}}}},"template.created":{"post":{"operationId":"onTemplateCreated","tags":["Templates"],"summary":"A template was created","description":"Sent when a template is created — uploaded in the dashboard, created through the API, or\nduplicated. `data` is a [Template](#/components/schemas/Template).\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateEvent"},"example":{"id":"evt_5KpT9wRm3XqN7vLb2HcZ8sYd","type":"template.created","created_at":"2026-09-20T09:12:44Z","data":{"object":"template","id":311,"name":"Residential lease","external_id":"lease-v3","folder":"Leasing","roles":["Tenant","Landlord"],"edit_url":"https://app.signwith.co/templates/311/edit","created_by":{"id":42,"email":"ada@acme.co","name":"Ada Lovelace"},"archived_at":null,"created_at":"2026-09-20T09:12:44Z","updated_at":"2026-09-21T16:03:10Z","fields":[{"id":"0f9c2b7e-5d1a-4e8b-9a61-3c2e7d4f1a90","name":"Tenant name","type":"text","role":"Tenant","required":true},{"id":"6a3e1d42-8b7c-4f19-a0d5-2e9b4c7f8a13","name":"Monthly rent","type":"number","role":"Tenant","required":true},{"id":"b2d8f4a1-3c6e-4a7b-8d92-5f1e0c3a9b76","name":"Start date","type":"date","role":"Tenant","required":true},{"id":"91c7e3b5-2a4d-4f8e-b610-7d3a5c9e2f48","name":"Pets","type":"select","role":"Tenant","required":false,"options":["None","Cat","Dog"]},{"id":"4e8a2c6f-9b1d-4a3e-8c57-1f6d0b9e3a24","name":"Tenant signature","type":"signature","role":"Tenant","required":true},{"id":"c5f1a9d3-7e2b-4c8a-9f60-3b8e4d2a7c15","name":"Landlord signature","type":"signature","role":"Landlord","required":true}],"documents":[{"id":7730,"name":"Lease agreement","url":"https://app.signwith.co/file/eyJfcmFpbHMiOnsiZGF0YSI6MTIzfX0/lease-agreement.pdf","preview_image_url":"https://app.signwith.co/file/eyJfcmFpbHMiOnsiZGF0YSI6MTI0fX0/0.jpg"}]}}}}},"responses":{"200":{"$ref":"#/components/responses/WebhookReceived"}}}},"template.updated":{"post":{"operationId":"onTemplateUpdated","tags":["Templates"],"summary":"A template was changed","description":"Sent when a template's name, folder, roles, fields or documents change. `data` is a\n[Template](#/components/schemas/Template).\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateEvent"},"example":{"id":"evt_1MvK6pTx8RqW3nLb9HcZ2sYe","type":"template.updated","created_at":"2026-09-21T16:03:10Z","data":{"object":"template","id":311,"name":"Residential lease","external_id":"lease-v3","folder":"Leasing","roles":["Tenant","Landlord"],"edit_url":"https://app.signwith.co/templates/311/edit","created_by":{"id":42,"email":"ada@acme.co","name":"Ada Lovelace"},"archived_at":null,"created_at":"2026-09-20T09:12:44Z","updated_at":"2026-09-21T16:03:10Z","fields":[{"id":"0f9c2b7e-5d1a-4e8b-9a61-3c2e7d4f1a90","name":"Tenant name","type":"text","role":"Tenant","required":true},{"id":"6a3e1d42-8b7c-4f19-a0d5-2e9b4c7f8a13","name":"Monthly rent","type":"number","role":"Tenant","required":true},{"id":"b2d8f4a1-3c6e-4a7b-8d92-5f1e0c3a9b76","name":"Start date","type":"date","role":"Tenant","required":true},{"id":"91c7e3b5-2a4d-4f8e-b610-7d3a5c9e2f48","name":"Pets","type":"select","role":"Tenant","required":false,"options":["None","Cat","Dog"]},{"id":"4e8a2c6f-9b1d-4a3e-8c57-1f6d0b9e3a24","name":"Tenant signature","type":"signature","role":"Tenant","required":true},{"id":"c5f1a9d3-7e2b-4c8a-9f60-3b8e4d2a7c15","name":"Landlord signature","type":"signature","role":"Landlord","required":true}],"documents":[{"id":7730,"name":"Lease agreement","url":"https://app.signwith.co/file/eyJfcmFpbHMiOnsiZGF0YSI6MTIzfX0/lease-agreement.pdf","preview_image_url":"https://app.signwith.co/file/eyJfcmFpbHMiOnsiZGF0YSI6MTI0fX0/0.jpg"}]}}}}},"responses":{"200":{"$ref":"#/components/responses/WebhookReceived"}}}},"template.archived":{"post":{"operationId":"onTemplateArchived","tags":["Templates"],"summary":"A template was archived","description":"Sent when a template is archived. `data` is a [Template](#/components/schemas/Template) with\n`archived_at` set.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateEvent"},"example":{"id":"evt_4NqB8vKx2TmR6pLw9HcZ3sYd","type":"template.archived","created_at":"2026-09-29T14:20:00Z","data":{"object":"template","id":311,"name":"Residential lease","external_id":"lease-v3","folder":"Leasing","roles":["Tenant","Landlord"],"edit_url":"https://app.signwith.co/templates/311/edit","created_by":{"id":42,"email":"ada@acme.co","name":"Ada Lovelace"},"archived_at":"2026-09-29T14:20:00Z","created_at":"2026-09-20T09:12:44Z","updated_at":"2026-09-29T14:20:00Z","fields":[],"documents":[]}}}}},"responses":{"200":{"$ref":"#/components/responses/WebhookReceived"}}}},"webhook.test":{"post":{"operationId":"onWebhookTest","tags":["Signers"],"summary":"Test event from the dashboard","description":"Sent immediately when you click **Send test event** on a webhook's settings page, regardless\nof which events the endpoint is subscribed to. It is not retried. `data` has the same shape as\na `signer.signed` event, using the most recently signed signer in your account — or an empty\nobject if nobody has signed yet. Use it to check that your endpoint is reachable and that\nsignature verification works; don't treat it as a real signing.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookTestEvent"},"examples":{"withSigner":{"summary":"Account with signed documents","value":{"id":"evt_9ZcT3mKx7RqB2vLp8HnW4sYd","type":"webhook.test","created_at":"2026-09-27T13:00:00Z","data":{"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":"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"}],"signature_request":{"id":4812,"status":"in_progress"}}}},"empty":{"summary":"New account","value":{"id":"evt_2BxK8nTq5RmW7vLp3HcZ9sYe","type":"webhook.test","created_at":"2026-09-27T13:00:00Z","data":{}}}}}}},"responses":{"200":{"$ref":"#/components/responses/WebhookReceived"}}}}},"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","bearerFormat":"sw_live_… / sw_test_…","description":"API key from **Settings → Developers**, sent as `Authorization: Bearer <key>`.\n`sw_live_` keys act on your live account; `sw_test_` keys act on your test account.\n"}},"parameters":{"Limit":{"name":"limit","in":"query","description":"Number of items per page, 1–100. Values outside that range fall back to 20 (below 1) or 100 (above 100).","schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"example":50},"Cursor":{"name":"cursor","in":"query","description":"The `next_cursor` from the previous page. Omit it for the first page.","schema":{"type":"integer"},"example":4812},"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":false,"description":"A unique value (e.g. a UUID) that makes retries of this request safe. A successful response\nis stored for 24 hours and replayed for retries with the same key.\n","schema":{"type":"string","maxLength":255},"example":"5f1c6c1e-0b1a-4d38-9d0e-8a7a1f2f8d11"},"TemplateId":{"name":"id","in":"path","required":true,"description":"Template ID.","schema":{"type":"integer"},"example":311},"SignatureRequestId":{"name":"id","in":"path","required":true,"description":"Signature request ID.","schema":{"type":"integer"},"example":4812}},"headers":{"RateLimit-Limit":{"description":"Requests allowed per one-minute window for this API key.","schema":{"type":"integer"},"example":300},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"},"example":287},"RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"},"example":42},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":42},"Idempotent-Replayed":{"description":"`true` when this response is a replay of an earlier request with the same `Idempotency-Key`.","schema":{"type":"string","enum":["true"]}}},"responses":{"BadRequest":{"description":"The request body is not valid JSON.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_json","message":"Invalid JSON: unexpected token at '{\"template_id\": 311,'"}}}}},"Unauthorized":{"description":"The API key is missing, invalid or expired, or its account has been archived.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthenticated":{"value":{"error":{"code":"unauthenticated","message":"Missing or invalid API key. Send it as `Authorization: Bearer <key>`."}}},"api_key_expired":{"value":{"error":{"code":"api_key_expired","message":"This API key has expired. Create a new one in Settings → Developers."}}}}}}},"PaymentRequired":{"description":"Not enough credits to send this document. Buy credits with `GET /credit_packs` and\n`POST /checkouts`, then retry. See [Buying credits](#section/Buying-credits).\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"insufficient_credits","message":"Not enough credits to send this document. List credit packs with GET /api/v1/credit_packs and buy one with POST /api/v1/checkouts."}}}}},"Forbidden":{"description":"The key is read-only, or its user can't access this resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"read_only_api_key":{"value":{"error":{"code":"read_only_api_key","message":"This API key is read-only"}}},"forbidden":{"value":{"error":{"code":"forbidden","message":"You do not have access to this resource"}}}}}}},"NotFound":{"description":"The resource doesn't exist or belongs to another account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"resource":{"value":{"error":{"code":"not_found","message":"Template not found"}}},"unknown_endpoint":{"value":{"error":{"code":"not_found","message":"No API endpoint matches GET /api/v1/template/311. See https://app.signwith.co/docs/api"}}}}}}},"Conflict":{"description":"A request with the same `Idempotency-Key` is still being processed. Retry shortly.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"idempotency_key_in_use","message":"A request with this Idempotency-Key is still being processed"}}}}},"UnprocessableEntity":{"description":"The request is valid JSON but can't be processed. See `error.code`; the codes each endpoint\ncan return are described in the endpoint's description and in the error table above.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"missing_parameter":{"value":{"error":{"code":"missing_parameter","message":"Missing parameter: template_id"}}},"invalid_parameter":{"value":{"error":{"code":"invalid_parameter","message":"`signing_order` must be \"sequential\" or \"parallel\""}}},"invalid_request":{"value":{"error":{"code":"invalid_request","message":"Unknown field: Monthly rnt"}}},"missing_documents":{"value":{"error":{"code":"missing_documents","message":"Add at least one document"}}},"too_many_documents":{"value":{"error":{"code":"too_many_documents","message":"A template can have at most 10 documents"}}},"document_too_large":{"value":{"error":{"code":"document_too_large","message":"lease.pdf is larger than 25 MB"}}},"invalid_document":{"value":{"error":{"code":"invalid_document","message":"Document \"Lease agreement\" must be base64 content or an https URL"}}},"invalid_file_type":{"value":{"error":{"code":"invalid_file_type","message":"Unsupported file type: application/zip. Upload a PDF or an image."}}},"pdf_encrypted":{"value":{"error":{"code":"pdf_encrypted","message":"This PDF is password protected. Send its `password` too."}}},"missing_signers":{"value":{"error":{"code":"missing_signers","message":"`signers` must list at least one signer"}}},"invalid_signer":{"value":{"error":{"code":"invalid_signer","message":"Signer 2 has role \"Buyer\", but the template's roles are: Tenant, Landlord"}}},"already_completed":{"value":{"error":{"code":"already_completed","message":"This signature request is already completed"}}},"not_open":{"value":{"error":{"code":"not_open","message":"This signature request is no longer open"}}},"nothing_to_remind":{"value":{"error":{"code":"nothing_to_remind","message":"No signers are waiting on this signature request"}}},"invalid_field":{"value":{"error":{"code":"invalid_field","message":"Field 2: `page` must be between 1 and 3"}}},"template_has_no_fields":{"value":{"error":{"code":"template_has_no_fields","message":"This template has no fields to fill in or sign. Add fields with PATCH /api/v1/templates/311 or in the editor: https://app.signwith.co/templates/311/edit"}}},"template_archived":{"value":{"error":{"code":"template_archived","message":"This template is archived. Duplicate it or pick another template."}}},"invalid_expires_at":{"summary":"invalid_parameter (expires_at)","value":{"error":{"code":"invalid_parameter","message":"`expires_at` must be in the future"}}},"invalid_email":{"summary":"invalid_signer (email)","value":{"error":{"code":"invalid_signer","message":"Signer 1 has an invalid email: grace@example"}}},"signer_finished":{"value":{"error":{"code":"signer_finished","message":"This signer has already signed or declined"}}},"idempotency_key_reused":{"value":{"error":{"code":"idempotency_key_reused","message":"This Idempotency-Key was already used with a different request body"}}},"duplicate_role":{"summary":"invalid_signer (role given twice)","value":{"error":{"code":"invalid_signer","message":"Each role can only be given to one signer"}}},"invalid_discount_code":{"value":{"error":{"code":"invalid_discount_code","message":"This discount code is invalid, expired or not valid for this credit pack"}}},"already_purchased":{"value":{"error":{"code":"already_purchased","message":"You already have the lifetime deal"}}},"billing_details_required":{"value":{"error":{"code":"billing_details_required","message":"Add your billing country in SignWith before buying credits: https://app.signwith.co/settings/profile"}}}}}}},"TooManyRequests":{"description":"Rate limit exceeded (`rate_limited`, with `Retry-After`); more than 20 `POST /feedback`\nmessages in an hour (`rate_limited`, with `Retry-After`: seconds until the next clock hour); or — for\n`POST /signature_requests/{id}/remind` — signers were reminded less than an hour ago\n(`remind_too_soon`, with `Retry-After`).\n","headers":{"Retry-After":{"$ref":"#/components/headers/Retry-After"},"RateLimit-Limit":{"$ref":"#/components/headers/RateLimit-Limit"},"RateLimit-Remaining":{"$ref":"#/components/headers/RateLimit-Remaining"},"RateLimit-Reset":{"$ref":"#/components/headers/RateLimit-Reset"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limited":{"value":{"error":{"code":"rate_limited","message":"Rate limit of 300 requests per minute exceeded"}}},"remind_too_soon":{"value":{"error":{"code":"remind_too_soon","message":"Signers were reminded less than an hour ago"}}},"feedback_rate_limited":{"summary":"rate_limited (feedback)","value":{"error":{"code":"rate_limited","message":"You can send up to 20 feedback messages per hour"}}}}}}},"InternalError":{"description":"Something went wrong on SignWith's side. It's safe to retry with the same `Idempotency-Key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"internal_error","message":"Something went wrong on our side. Please try again; if it keeps happening, contact support."}}}}},"BadGateway":{"description":"The payment provider couldn't start the checkout. Nothing was charged; try again later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"payment_provider_error","message":"Couldn't start the payment: Payment initialization failed"}}}}},"WebhookReceived":{"description":"Return any 2xx status within 30 seconds to acknowledge the event. Other statuses, timeouts\nand connection errors are retried up to 10 times with exponential back-off.\n"}},"examples":{"PendingCheckout":{"summary":"Waiting for the user to pay","value":{"object":"checkout","id":"3f6b2c1a-8d4e-4b7a-9c20-5e1f7a9d3b84","status":"pending","credit_pack":{"object":"credit_pack","id":4,"name":"Business","description":"50 documents","credits":50,"unlimited":false,"price":"29.00","currency":"USD","price_per_credit":"0.58"},"amount":"29.00","currency":"USD","discount_code":null,"checkout_url":"https://checkout.dodopayments.com/buy/pl_2x7Kq9mTbR4vLw8N","completed_at":null,"created_at":"2026-09-27T11:20:31Z"}},"Template":{"summary":"Template with fields and documents","value":{"object":"template","id":311,"name":"Residential lease","external_id":"lease-v3","folder":"Leasing","roles":["Tenant","Landlord"],"edit_url":"https://app.signwith.co/templates/311/edit","created_by":{"id":42,"email":"ada@acme.co","name":"Ada Lovelace"},"archived_at":null,"created_at":"2026-09-20T09:12:44Z","updated_at":"2026-09-21T16:03:10Z","fields":[{"id":"0f9c2b7e-5d1a-4e8b-9a61-3c2e7d4f1a90","name":"Tenant name","type":"text","role":"Tenant","required":true},{"id":"6a3e1d42-8b7c-4f19-a0d5-2e9b4c7f8a13","name":"Monthly rent","type":"number","role":"Tenant","required":true},{"id":"b2d8f4a1-3c6e-4a7b-8d92-5f1e0c3a9b76","name":"Start date","type":"date","role":"Tenant","required":true},{"id":"91c7e3b5-2a4d-4f8e-b610-7d3a5c9e2f48","name":"Pets","type":"select","role":"Tenant","required":false,"options":["None","Cat","Dog"]},{"id":"4e8a2c6f-9b1d-4a3e-8c57-1f6d0b9e3a24","name":"Tenant signature","type":"signature","role":"Tenant","required":true},{"id":"c5f1a9d3-7e2b-4c8a-9f60-3b8e4d2a7c15","name":"Landlord signature","type":"signature","role":"Landlord","required":true}],"documents":[{"id":7730,"name":"Lease agreement","url":"https://app.signwith.co/file/eyJfcmFpbHMiOnsiZGF0YSI6MTIzfX0/lease-agreement.pdf","preview_image_url":"https://app.signwith.co/file/eyJfcmFpbHMiOnsiZGF0YSI6MTI0fX0/0.jpg"}]}},"CompletedSignatureRequest":{"summary":"Completed signature request","value":{"object":"signature_request","id":4812,"status":"completed","template":{"id":311,"name":"Residential lease"},"signing_order":"sequential","source":"api","created_by":{"id":42,"email":"ada@acme.co","name":"Ada Lovelace"},"signers":[{"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":"Start date","value":"2026-11-01"},{"field":"Pets","value":"Cat"},{"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"}]},{"object":"signer","id":9121,"signature_request_id":4812,"role":"Landlord","name":"Ada Lovelace","email":"ada@acme.co","phone":null,"external_id":null,"metadata":{},"status":"signed","signing_url":null,"sent_at":"2026-09-27T09:44:53Z","viewed_at":"2026-09-27T10:12:30Z","signed_at":"2026-09-27T10:14:58Z","declined_at":null,"created_at":"2026-09-27T09:00:01Z","updated_at":"2026-09-27T10:14:58Z","values":[{"field":"Landlord signature","value":"https://app.signwith.co/file/eyJfcmFpbHMiOnsiZGF0YSI6NTYwfX0/signature.png"}],"documents":[{"name":"Lease agreement","url":"https://app.signwith.co/file/eyJfcmFpbHMiOnsiZGF0YSI6NTYxfX0/lease-agreement.pdf"}]}],"expires_at":"2026-10-27T00:00:00Z","completed_at":"2026-09-27T10:14:58Z","canceled_at":null,"created_at":"2026-09-27T09:00:01Z","updated_at":"2026-09-27T10:14:58Z","documents":[{"name":"Lease agreement","url":"https://app.signwith.co/file/eyJfcmFpbHMiOnsiZGF0YSI6NTYxfX0/lease-agreement.pdf"}],"audit_trail_url":"https://app.signwith.co/file/eyJfcmFpbHMiOnsiZGF0YSI6NTYyfX0/audit-trail.pdf","combined_document_url":null}},"CanceledSignatureRequest":{"summary":"Canceled signature request","value":{"object":"signature_request","id":4812,"status":"canceled","template":{"id":311,"name":"Residential lease"},"signing_order":"sequential","source":"api","created_by":{"id":42,"email":"ada@acme.co","name":"Ada Lovelace"},"signers":[{"object":"signer","id":9120,"signature_request_id":4812,"role":"Tenant","name":"Grace Hopper","email":"grace@example.com","phone":null,"external_id":"cust_8841","metadata":{},"status":"viewed","signing_url":"https://app.signwith.co/s/Hn3cW8yRk2Qe","sent_at":"2026-09-27T09:00:02Z","viewed_at":"2026-09-27T09:41:18Z","signed_at":null,"declined_at":null,"created_at":"2026-09-27T09:00:01Z","updated_at":"2026-09-27T09:41:18Z","values":[]}],"expires_at":null,"completed_at":null,"canceled_at":"2026-09-28T08:30:12Z","created_at":"2026-09-27T09:00:01Z","updated_at":"2026-09-28T08:30:12Z"}},"SignedSigner":{"summary":"A signer who has signed","value":{"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"}]}},"SignerEventData":{"summary":"Signer event data","value":{"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":"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"}],"signature_request":{"id":4812,"status":"in_progress"}}}},"schemas":{"Error":{"type":"object","description":"Error envelope returned with every 4xx and 5xx response.","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Machine-readable error code. See the error table in the introduction.","enum":["invalid_json","unauthenticated","api_key_expired","insufficient_credits","read_only_api_key","insufficient_scope","not_available","forbidden","not_found","idempotency_key_in_use","idempotency_key_reused","missing_parameter","invalid_parameter","invalid_request","missing_documents","too_many_documents","document_too_large","invalid_document","invalid_file_type","invalid_field","template_has_no_fields","template_archived","pdf_encrypted","missing_signers","invalid_signer","already_completed","not_open","nothing_to_remind","signer_finished","invalid_discount_code","already_purchased","billing_details_required","rate_limited","remind_too_soon","internal_error","payment_provider_error"]},"message":{"type":"string","description":"Human-readable explanation. Don't parse it; it may change."}}}},"example":{"error":{"code":"not_found","message":"Template not found"}}},"List":{"type":"object","description":"A page of results. `data` holds the items; see [Pagination](#section/Pagination).","required":["object","data","has_more","next_cursor"],"properties":{"object":{"type":"string","const":"list"},"data":{"type":"array","items":{}},"has_more":{"type":"boolean","description":"Whether more items exist after this page."},"next_cursor":{"type":["integer","null"],"description":"Pass as `cursor` to fetch the next page. `null` on the last page."}}},"User":{"type":"object","description":"A SignWith user (a member of your team).","required":["id","email","name"],"properties":{"id":{"type":"integer","example":42},"email":{"type":"string","format":"email","example":"ada@acme.co"},"name":{"type":["string","null"],"description":"First and last name, or `null` if not set.","example":"Ada Lovelace"}}},"Me":{"type":"object","required":["object","user","account","environment","api_key"],"properties":{"object":{"type":"string","const":"me"},"user":{"$ref":"#/components/schemas/User"},"account":{"type":"object","required":["id","name"],"properties":{"id":{"type":"integer","example":7},"name":{"type":["string","null"],"example":"Acme Inc."}}},"environment":{"type":"string","enum":["live","test"],"description":"`test` for keys issued from your test account (`sw_test_`), otherwise `live`."},"api_key":{"type":"object","required":["id","name","permission","expires_at"],"properties":{"id":{"type":"integer","example":118},"name":{"type":"string","description":"The name you gave the key, or `Default key`.","example":"Production CRM"},"permission":{"type":"string","enum":["full","read"],"description":"`read` keys can only call `GET` endpoints, `POST /documents/verify` and `POST /feedback`."},"expires_at":{"type":["string","null"],"format":"date-time","description":"When the key stops working, or `null` if it never expires."}}}}},"Credits":{"type":"object","required":["object","unlimited","available","overdraft_limit","can_send","billing","purchase_url"],"properties":{"object":{"type":"string","const":"credits"},"unlimited":{"type":"boolean","description":"`true` for lifetime plans, which never run out of credits."},"available":{"type":["integer","null"],"description":"Credits left. Can be slightly negative (see `overdraft_limit`). `null` when `unlimited`.","example":12},"overdraft_limit":{"type":"integer","description":"How far below zero the balance may go before sending is blocked.","example":-3},"can_send":{"type":"boolean","description":"Whether a signature request that needs a new credit can be sent right now."},"billing":{"type":"string","description":"Plain-language summary of how credits are used.","example":"One credit per signed document: a document (template) uses a credit the first time it is signed; sending the same document again doesn't use another."},"purchase_url":{"type":"string","format":"uri","description":"Page in the SignWith dashboard where the user can buy credits. To buy from the API instead,\nuse `GET /credit_packs` and `POST /checkouts`.\n","example":"https://app.signwith.co/credit_plans"}}},"CreditPack":{"type":"object","description":"A pack of credits that can be bought with `POST /checkouts`.","required":["object","id","name","description","credits","unlimited","price","currency","price_per_credit"],"properties":{"object":{"type":"string","const":"credit_pack"},"id":{"type":"integer","example":4},"name":{"type":"string","example":"Business"},"description":{"type":["string","null"],"example":"50 documents"},"credits":{"type":["integer","null"],"description":"Credits added when bought. `null` for the lifetime deal.","example":50},"unlimited":{"type":"boolean","description":"`true` for the lifetime deal, which removes the credit limit."},"price":{"type":"string","description":"Price as a decimal string with two places.","example":"29.00"},"currency":{"type":"string","const":"USD"},"price_per_credit":{"type":["string","null"],"description":"`price` divided by `credits`, as a decimal string. `null` for the lifetime deal.","example":"0.58"}}},"Checkout":{"type":"object","description":"A credit purchase started with `POST /checkouts`.","required":["object","id","status","credit_pack","amount","currency","discount_code","checkout_url","completed_at","created_at"],"properties":{"object":{"type":"string","const":"checkout"},"id":{"type":"string","format":"uuid","description":"Checkout ID. Use it with `GET /checkouts/{id}`."},"status":{"type":"string","enum":["pending","completed","failed"],"description":"`pending` — waiting for payment or confirmation; `completed` — paid and credits added;\n`failed` — the payment failed or was canceled.\n"},"credit_pack":{"$ref":"#/components/schemas/CreditPack","description":"The pack being bought (the discounted offer when a `discount_code` was applied)."},"amount":{"type":"string","description":"Amount charged, as a decimal string.","example":"29.00"},"currency":{"type":"string","const":"USD"},"discount_code":{"type":["string","null"]},"checkout_url":{"type":["string","null"],"format":"uri","description":"Hosted payment page to send the user to. Only present while `status` is `pending`.\n"},"completed_at":{"type":["string","null"],"format":"date-time","description":"When the payment was confirmed."},"created_at":{"type":"string","format":"date-time"}}},"CreateCheckoutRequest":{"type":"object","required":["credit_pack_id"],"properties":{"credit_pack_id":{"type":"integer","description":"ID of a pack from `GET /credit_packs`.","example":4},"discount_code":{"type":"string","description":"Optional discount code for this pack.","example":"LAUNCH20"}}},"CreateFeedbackRequest":{"type":"object","required":["message"],"properties":{"type":{"type":"string","enum":["bug","feature_request","feedback","question"],"default":"feedback","description":"What kind of message this is."},"message":{"type":"string","minLength":1,"maxLength":5000,"description":"The feedback in plain language. Up to 5,000 characters."},"context":{"type":"object","description":"Optional details that help the team investigate. Only the keys below are kept; others are\ndropped.\n","additionalProperties":false,"properties":{"client":{"type":"string","description":"Name of the client or AI assistant, e.g. `claude-desktop`."},"client_version":{"type":"string"},"tool":{"type":"string","description":"The tool or operation the user was using."},"signature_request_id":{"type":["integer","string"]},"template_id":{"type":["integer","string"]},"error_code":{"type":"string","description":"The API `error.code` the user ran into, if any."},"request_id":{"type":"string"}}}}},"FeedbackReceipt":{"type":"object","description":"Confirms the feedback was received.","required":["object","id","type","status","message"],"properties":{"object":{"type":"string","const":"feedback"},"id":{"type":"integer","example":57},"type":{"type":"string","enum":["bug","feature_request","feedback","question"]},"status":{"type":"string","const":"received"},"message":{"type":"string","description":"A confirmation you can show to the user.","example":"Thanks! The SignWith team has been notified."}}},"TemplateField":{"type":"object","description":"A field placed on a template's documents. Keys with no value are omitted.","required":["id","type","required"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable field ID."},"name":{"type":"string","description":"Field name. Use it as the key in `prefill`. Omitted if the field has no name.","example":"Monthly rent"},"type":{"type":"string","description":"Field type, e.g. `text`, `signature`, `initials`, `date`, `number`, `checkbox`, `radio`,\n`select`, `multiple`, `image`, `file`, `phone`, `stamp`, `cells`.\n","example":"text"},"role":{"type":"string","description":"Name of the role that fills this field.","example":"Tenant"},"required":{"type":"boolean","description":"Whether the signer must fill the field."},"options":{"type":"array","items":{"type":"string"},"description":"Allowed values for `select`, `radio` and `multiple` fields."}}},"Document":{"type":"object","description":"A document (one uploaded file) of a template.","required":["id","name","url"],"properties":{"id":{"type":"integer","example":7730},"name":{"type":"string","description":"File name without extension.","example":"Lease agreement"},"url":{"type":"string","format":"uri","description":"Download link for the original file."},"preview_image_url":{"type":["string","null"],"format":"uri","description":"Image of the first page, if available."}}},"SignedDocument":{"type":"object","description":"A signed PDF.","required":["name","url"],"properties":{"name":{"type":"string","description":"File name without extension.","example":"Lease agreement"},"url":{"type":"string","format":"uri","description":"Download link for the signed PDF."}}},"TemplateSummary":{"type":"object","description":"A template as it appears in lists (without `fields` and `documents`).","required":["object","id","name","external_id","folder","roles","edit_url","created_by","archived_at","created_at","updated_at"],"properties":{"object":{"type":"string","const":"template"},"id":{"type":"integer","example":311},"name":{"type":"string","example":"Residential lease"},"external_id":{"type":["string","null"],"description":"Your own ID for the template.","example":"lease-v3"},"folder":{"type":["string","null"],"description":"Name of the folder the template is in.","example":"Leasing"},"roles":{"type":"array","description":"Role names in signing order.","items":{"type":"string"},"example":["Tenant","Landlord"]},"edit_url":{"type":"string","format":"uri","description":"Opens the template in the SignWith editor, where the user can place or adjust fields.","example":"https://app.signwith.co/templates/311/edit"},"created_by":{"oneOf":[{"$ref":"#/components/schemas/User"},{"type":"null"}]},"archived_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"Template":{"description":"A template, including its fields and documents.","allOf":[{"$ref":"#/components/schemas/TemplateSummary"},{"type":"object","required":["fields","documents"],"properties":{"fields":{"type":"array","items":{"$ref":"#/components/schemas/TemplateField"}},"documents":{"type":"array","items":{"$ref":"#/components/schemas/Document"}}}}]},"FieldValue":{"type":"object","description":"A signer's value for one field. For signature, initials, image and stamp fields `value` is a\ndownload URL of the image; for file fields it's an array of URLs.\n","required":["field","value"],"properties":{"field":{"type":"string","description":"Field name (or a generated name such as `Text Field 2` for unnamed fields).","example":"Monthly rent"},"value":{"description":"The value entered or prefilled.","type":["string","number","boolean","array","null"],"example":"2150"}}},"SignerSummary":{"type":"object","description":"A signer as it appears inside signature request lists (without `values` and `documents`).","required":["object","id","signature_request_id","role","name","email","phone","external_id","metadata","status","signing_url","sent_at","viewed_at","signed_at","declined_at","created_at","updated_at"],"properties":{"object":{"type":"string","const":"signer"},"id":{"type":"integer","example":9121},"signature_request_id":{"type":"integer","example":4812},"role":{"type":["string","null"],"description":"The template role this signer fills.","example":"Landlord"},"name":{"type":["string","null"],"example":"Ada Lovelace"},"email":{"type":["string","null"],"format":"email","example":"ada@acme.co"},"phone":{"type":["string","null"],"example":"+14155550123"},"external_id":{"type":["string","null"],"description":"Your own ID for this signer."},"metadata":{"type":"object","additionalProperties":true,"description":"Arbitrary key/value data you attached to the signer."},"status":{"type":"string","enum":["waiting","ready","sent","viewed","signed","declined"],"description":"`waiting` — an earlier signer in a sequential request has to sign first; `ready` — it's their\nturn but they weren't emailed (e.g. `send_email: false`, or the email is still queued), so\nshare `signing_url` yourself; `sent` — invited; `viewed` — opened the document;\n`signed` — finished signing; `declined` — declined to sign.\n"},"signing_url":{"type":["string","null"],"format":"uri","description":"The signer's private signing link. Anyone with it can sign as this signer, so only share\nit with them. `null` once they've signed, or when the request is canceled, declined or\nexpired, or its template is archived.\n"},"sent_at":{"type":["string","null"],"format":"date-time"},"viewed_at":{"type":["string","null"],"format":"date-time"},"signed_at":{"type":["string","null"],"format":"date-time"},"declined_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"Signer":{"description":"A person asked to sign in a signature request.","allOf":[{"$ref":"#/components/schemas/SignerSummary"},{"type":"object","required":["values"],"properties":{"values":{"type":"array","description":"Field values filled so far (prefilled or entered by the signer).","items":{"$ref":"#/components/schemas/FieldValue"}},"documents":{"type":"array","description":"The signer's signed documents. Present only once they've signed.","items":{"$ref":"#/components/schemas/SignedDocument"}}}}]},"SignatureRequestSummary":{"type":"object","description":"A signature request as it appears in lists.","required":["object","id","status","template","signing_order","source","created_by","signers","expires_at","completed_at","canceled_at","created_at","updated_at"],"properties":{"object":{"type":"string","const":"signature_request"},"id":{"type":"integer","example":4812},"status":{"type":"string","enum":["sent","in_progress","completed","declined","expired","canceled"],"description":"`sent` — nobody has signed yet; `in_progress` — some signers have signed;\n`completed` — everyone signed; `declined` — a signer declined; `expired` — passed\n`expires_at` before completion; `canceled` — canceled. A fully signed request is always\n`completed`, even if it was later archived.\n"},"template":{"description":"The template this request was created from.","oneOf":[{"type":"object","required":["id","name"],"properties":{"id":{"type":"integer","example":311},"name":{"type":"string","example":"Residential lease"}}},{"type":"null"}]},"signing_order":{"type":"string","enum":["sequential","parallel"]},"source":{"type":"string","description":"Where the request was created: `api` (this API), `mcp` (an AI assistant through the SignWith\nMCP server), `invite` (dashboard), `link` (shared link), `bulk` or `embed`.\n","example":"api"},"created_by":{"oneOf":[{"$ref":"#/components/schemas/User"},{"type":"null"}]},"signers":{"type":"array","description":"Signers in role order.","items":{"$ref":"#/components/schemas/SignerSummary"}},"expires_at":{"type":["string","null"],"format":"date-time"},"completed_at":{"type":["string","null"],"format":"date-time","description":"When the last signer signed."},"canceled_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"SignatureRequest":{"description":"A signature request with full signer details. `documents`, `audit_trail_url` and\n`combined_document_url` are present only when every signer has signed.\n","allOf":[{"$ref":"#/components/schemas/SignatureRequestSummary"},{"type":"object","properties":{"signers":{"type":"array","description":"Signers in role order, with their field values.","items":{"$ref":"#/components/schemas/Signer"}},"documents":{"type":"array","description":"The final signed documents.","items":{"$ref":"#/components/schemas/SignedDocument"}},"audit_trail_url":{"type":["string","null"],"format":"uri","description":"Download link for the audit trail PDF."},"combined_document_url":{"type":["string","null"],"format":"uri","description":"Download link for all documents and the audit trail merged into one PDF, if generated."}}}]},"Reminder":{"type":"object","required":["object","signature_request_id","reminded_signer_ids"],"properties":{"object":{"type":"string","const":"reminder"},"signature_request_id":{"type":"integer","example":4812},"reminded_signer_ids":{"type":"array","description":"IDs of the signers who were emailed.","items":{"type":"integer"},"example":[9121]}}},"DocumentVerification":{"type":"object","required":["object","issued_by_signwith","signatures"],"properties":{"object":{"type":"string","const":"document_verification"},"issued_by_signwith":{"type":"boolean","description":"Whether this exact file is a document completed in SignWith."},"signatures":{"type":"array","description":"Every digital signature found in the PDF. Empty if the PDF isn't digitally signed.","items":{"type":"object","required":["signer_name","signed_at","reason","valid","messages"],"properties":{"signer_name":{"type":["string","null"],"example":"SignWith"},"signed_at":{"type":["string","null"],"format":"date-time"},"reason":{"type":["string","null"]},"valid":{"type":"boolean","description":"`true` if verification produced no errors."},"messages":{"type":"array","description":"Details from verifying the signature and certificate chain.","items":{"type":"object","required":["type","content"],"properties":{"type":{"type":"string","enum":["info","warning","error"]},"content":{"type":"string"}}}}}}}}},"Prefill":{"type":"object","description":"Values to fill in for a signer before they sign, keyed by field name (see the template's\n`fields`). Values must suit the field type: text, dates as `YYYY-MM-DD`, checkboxes as\nbooleans, and for image or signature fields a base64 image or an https URL.\n","additionalProperties":true,"example":{"Tenant name":"Grace Hopper","Monthly rent":"2150","Start date":"2026-11-01"}},"CreateSignerRequest":{"type":"object","description":"A signer to invite. Needs an `email` or a `phone`.","properties":{"role":{"type":"string","description":"The template role this signer fills. If omitted, signers fill the template's roles in the\norder given.\n","example":"Tenant"},"name":{"type":"string","example":"Grace Hopper"},"email":{"type":"string","format":"email","example":"grace@example.com"},"phone":{"type":"string","description":"Phone number in international format.","example":"+14155550123"},"external_id":{"type":"string","description":"Your own ID for this signer, returned in responses and webhooks.","example":"cust_8841"},"metadata":{"type":"object","additionalProperties":true,"description":"Arbitrary key/value data stored with the signer.","example":{"crm_deal_id":"D-2291"}},"prefill":{"$ref":"#/components/schemas/Prefill"},"redirect_url":{"type":"string","format":"uri","description":"Where to send this signer after they sign. Overrides the request-level `redirect_url`."},"require_email_otp":{"type":"boolean","description":"Require each signer to enter a one-time code sent to their email before they can view and\nsign. Overrides the request-level `require_email_otp` for this signer.\n"}},"anyOf":[{"required":["email"]},{"required":["phone"]}]},"CreateSignatureRequestRequest":{"type":"object","required":["template_id","signers"],"properties":{"template_id":{"type":"integer","description":"The template to send.","example":311},"signers":{"type":"array","minItems":1,"description":"The people to invite. At most one per template role.","items":{"$ref":"#/components/schemas/CreateSignerRequest"}},"signing_order":{"type":"string","enum":["sequential","parallel"],"default":"sequential","description":"`sequential` invites signers one at a time in role order; `parallel` invites everyone at once.\n"},"send_email":{"type":"boolean","default":true,"description":"Set to `false` to create the request without emailing signers."},"message":{"type":"object","description":"Custom subject and body for the invitation email.","properties":{"subject":{"type":"string","example":"Your lease is ready to sign"},"body":{"type":"string","example":"Hi","please review and sign your lease.":null}}},"reply_to":{"type":"string","format":"email","description":"Reply-to address for emails sent to signers."},"redirect_url":{"type":"string","format":"uri","description":"Where to send signers after they sign."},"expires_at":{"type":"string","format":"date-time","description":"ISO 8601 date-time in the future (e.g. `2026-12-31T17:00:00Z`). After it the request expires\nand can no longer be signed.\n"},"require_email_otp":{"type":"boolean","default":false,"description":"Require each signer to enter a one-time code sent to their email before they can view and sign.\n"}}},"UpdateSignerRequest":{"type":"object","description":"Only the properties you send are changed.","properties":{"name":{"type":["string","null"]},"email":{"type":["string","null"],"format":"email"},"phone":{"type":["string","null"]},"external_id":{"type":["string","null"]},"metadata":{"type":"object","additionalProperties":true,"description":"Replaces the signer's metadata."},"prefill":{"type":"object","additionalProperties":true,"description":"Field values to set, keyed by field name. Merged with existing prefilled values."},"resend":{"type":"boolean","default":false,"description":"Email the signing link again after updating (only if the signer was already invited)."}}},"CreateTemplateJsonRequest":{"type":"object","required":["documents"],"properties":{"name":{"type":"string","description":"Template name. Defaults to the first document's name.","example":"Residential lease"},"external_id":{"type":"string","description":"Your own ID for the template.","example":"lease-v3"},"folder":{"type":"string","description":"Folder name. Created if it doesn't exist.","example":"Leasing"},"password":{"type":"string","description":"Password for encrypted PDFs."},"documents":{"type":"array","minItems":1,"maxItems":10,"items":{"type":"object","required":["file"],"properties":{"name":{"type":"string","description":"Document name. Defaults to `Document <n>`.","example":"Lease agreement"},"file":{"type":"string","description":"Base64-encoded PDF or image (a `data:` URI prefix is allowed), or an `https://` URL\nto download it from. Max 25 MB.\n","example":"https://files.acme.co/templates/lease-v3.pdf"}}}},"fields":{"type":"array","description":"Fields to place on the documents, in addition to any fillable PDF form fields. Roles named\nhere are added to the template (at most 10 roles).\n","items":{"$ref":"#/components/schemas/TemplateFieldInput"}}}},"TemplateFieldInput":{"type":"object","description":"A field to place on a template.","required":["type","areas"],"properties":{"name":{"type":"string","description":"Field name, used as the key in `prefill`. Defaults to e.g. `Signature 2`.","example":"Client signature"},"type":{"type":"string","enum":["text","signature","initials","date","checkbox","number","phone","select","radio","multiple","image","file","stamp"]},"role":{"type":"string","description":"Role that fills this field. Created on the template if it doesn't exist. Defaults to the\ntemplate's first role.\n","example":"Client"},"required":{"type":"boolean","default":true},"options":{"type":"array","items":{"type":"string"},"description":"Choices for `select`, `radio` and `multiple` fields (required for those types).","example":["Net 15","Net 30"]},"areas":{"type":"array","minItems":1,"description":"Where the field goes. A field can appear in several places.","items":{"$ref":"#/components/schemas/TemplateFieldArea"}}}},"TemplateFieldArea":{"type":"object","description":"A field's position on a page. `x`, `y`, `w` and `h` are fractions (0–1) of the page width and\nheight, measured from the top-left corner.\n","required":["page","x","y","w","h"],"properties":{"page":{"type":"integer","minimum":1,"description":"1-based page number; must exist in the document.","example":3},"x":{"type":"number","minimum":0,"maximum":1,"example":0.1},"y":{"type":"number","minimum":0,"maximum":1,"example":0.78},"w":{"type":"number","exclusiveMinimum":0,"maximum":1,"example":0.3},"h":{"type":"number","exclusiveMinimum":0,"maximum":1,"example":0.06},"document":{"type":"integer","minimum":0,"default":0,"description":"0-based index of the document within the template."}}},"CreateTemplateMultipartRequest":{"type":"object","required":["documents[]"],"properties":{"name":{"type":"string","description":"Template name. Defaults to the first file's name."},"external_id":{"type":"string"},"folder":{"type":"string","description":"Folder name. Created if it doesn't exist."},"password":{"type":"string","description":"Password for encrypted PDFs."},"documents[]":{"type":"array","minItems":1,"maxItems":10,"description":"PDF or image files, 25 MB max each.","items":{"type":"string","contentMediaType":"application/octet-stream"}}}},"UpdateTemplateRequest":{"type":"object","properties":{"name":{"type":"string"},"external_id":{"type":["string","null"],"description":"Your own ID for the template. Send `null` to clear it."},"folder":{"type":"string","description":"Folder name. Created if it doesn't exist."},"roles":{"type":"array","items":{"type":"string"},"description":"New role names, matched by position. Extra names add roles."},"fields":{"type":"array","description":"Replaces all of the template's fields. Roles named here are added if missing.","items":{"$ref":"#/components/schemas/TemplateFieldInput"}}}},"DuplicateTemplateRequest":{"type":"object","properties":{"name":{"type":"string","description":"Name of the copy. Defaults to the original name followed by \"(Clone)\"."},"external_id":{"type":"string"},"folder":{"type":"string","description":"Folder for the copy. Created if it doesn't exist."}}},"WebhookEventBase":{"type":"object","required":["id","type","created_at","data"],"properties":{"id":{"type":"string","description":"Unique event ID. The same across retries — use it to de-duplicate.","example":"evt_7Qm2Vt9sKd3LpXa8RzYw1bNc"},"type":{"type":"string","description":"Event type, also sent in the `X-SignWith-Event` header."},"created_at":{"type":"string","format":"date-time","description":"When the event happened."},"data":{"description":"The object the event is about, in its state at delivery time."}}},"SignatureRequestEvent":{"allOf":[{"$ref":"#/components/schemas/WebhookEventBase"},{"type":"object","properties":{"type":{"type":"string","enum":["signature_request.created","signature_request.completed","signature_request.canceled"]},"data":{"$ref":"#/components/schemas/SignatureRequest"}}}]},"SignerEventData":{"description":"A signer plus a short summary of its signature request.","allOf":[{"$ref":"#/components/schemas/Signer"},{"type":"object","required":["signature_request"],"properties":{"signature_request":{"type":"object","required":["id","status"],"properties":{"id":{"type":"integer","example":4812},"status":{"$ref":"#/components/schemas/SignatureRequestSummary/properties/status"}}}}}]},"SignerEvent":{"allOf":[{"$ref":"#/components/schemas/WebhookEventBase"},{"type":"object","properties":{"type":{"type":"string","enum":["signer.viewed","signer.started","signer.signed","signer.declined"]},"data":{"$ref":"#/components/schemas/SignerEventData"}}}]},"TemplateEvent":{"allOf":[{"$ref":"#/components/schemas/WebhookEventBase"},{"type":"object","properties":{"type":{"type":"string","enum":["template.created","template.updated","template.archived"]},"data":{"$ref":"#/components/schemas/Template"}}}]},"WebhookTestEvent":{"allOf":[{"$ref":"#/components/schemas/WebhookEventBase"},{"type":"object","properties":{"type":{"type":"string","const":"webhook.test"},"data":{"oneOf":[{"$ref":"#/components/schemas/SignerEventData"},{"type":"object","maxProperties":0,"description":"Empty when the account has no signed documents yet."}]}}}]}}}}