{
  "openapi": "3.1.1",
  "info": {
    "title": "SignSwifly API",
    "description": "Send documents for signature, follow them as they are signed, and collect the sealed copies — from your own\nsystems. Everything here can also be done in the app; the API does it the same way, under the same rules.\n\n# API keys\n\nMake an API key in **Settings → API & webhooks** (owners and admins, Solo plan and up). A key looks like\n`ssk_live_…`, is shown once, and is sent on every request:\n\n```\nAuthorization: Bearer ssk_live_abcdefghjkmnpqrs_…\n```\n\nA key **acts as the owner or admin who made it**: envelopes it sends have them as the sender, and every action\nis on the envelope's audit trail as theirs, with `API key “name” (ssk_live_…)` and your system's user agent where\na person's browser would be. If that person leaves the workspace, or stops being an owner or admin, the key stops\nworking: make a new one under someone who is.\nKeys can be given an expiry; a key's name, scopes and expiry can be changed, and the key deleted, at any time,\neach taking effect on its next request.\n\nEach key has **scopes**, and each operation below says which it needs: `envelopes:read`, `envelopes:write`,\n`templates:read`, `documents:read`, `webhooks:manage`. Give a key the fewest it needs. `GET /api/v1/me` needs\nnone, and says who a key acts as.\n\nKeep keys on your servers. The API doesn't answer browsers on other sites, and a key in a web page is a key\nanyone can read.\n\n# Test mode\n\nTo build and try an integration without sending anything real, make a **test key**: choose **Test** when you\nmake the key. A test key looks like `ssk_test_…` and works as a live key does, with the same scopes, limits,\nanswers and errors, except:\n\n- **Its envelopes are test envelopes.** They go only to people in your team (the addresses your workspace's\n  members sign in with), say TEST in the app, at the top of every email (with `[TEST]` in the subject) and on\n  the signing page, and don't use your plan's envelopes, drafts or email allowance. Up to\n  50 can be sent a day.\n- **Nothing is texted.** A test envelope's recipients can't be texted a link or a code, and nobody can be left\n  for a signer to name (a nominee, or a witness the signer names).\n- **Nothing is sealed.** A completed test envelope's documents and certificate are drawn as sealed copies\n  would be, with TEST across every page and no seal. SignSwifly hasn't signed them, the verify page doesn't\n  know them, and they aren't saved to SharePoint, kept by a legal hold or included in a workspace export.\n- **It's deleted after 7 days.** A test envelope goes, documents, trail and all, 7 days after it was made,\n  whatever state it's in.\n- **A test key sees only test envelopes, and a live key only real ones.** The same goes for webhook\n  endpoints: a test key lists and changes test endpoints, and a live key live ones. Each says which it is in\n  `test`.\n\nWebhooks keep to the same line: a **test endpoint** (choose **Test** when you add it in Settings, or add it\nwith a test key) is told about test envelopes only, and a live endpoint about real envelopes only, so a\nsystem acting on real envelopes never acts on a test. Every delivery says which in `test`.\n\nTo try the API without writing any code, use the [console](/developers/console) with a test key, or import\nthe [Postman collection](/developers/signswifly-api.postman_collection.json).\n\n# Errors\n\nErrors are [RFC 7807](https://www.rfc-editor.org/rfc/rfc7807) problem details\n(`application/problem+json`): a `title`, a `detail` written for a developer to act on, a stable `code` to\nbranch on, and a `traceId` to quote to support.\n\n| Status | code | Meaning |\n|---|---|---|\n| 400 | `bad_request` | The request couldn't be read: invalid JSON, a missing field, a cursor this API didn't issue. |\n| 400 | `bad_idempotency_key` | The Idempotency-Key header isn't 1 to 255 printable characters. |\n| 401 | `unauthorized` | No key, or one that is wrong, deleted, revoked, expired, or whose maker has left. |\n| 403 | `plan_required` | The workspace is on the Free plan; the API needs Solo or above. |\n| 403 | `workspace_paused` | SignSwifly has paused the workspace's sending (Terms, clause 14). Contact support. |\n| 403 | `account_suspended` | SignSwifly has suspended the person who made the key. Contact support. |\n| 403 | `missing_scope` | The key doesn't have the scope this operation needs. |\n| 404 | `not_found` | Nothing with that id in this workspace. Another workspace's ids read the same way. |\n| 409 | `idempotency_in_progress` | A request with the same Idempotency-Key is still running. |\n| 409 | `conflict` | Something else changed the envelope at the same moment. Try again. |\n| 413 | `too_large` | The request is bigger than allowed. |\n| 422 | `refused` | A rule refused it: the envelope isn't in a state for that, a plan limit, a field without options… The detail says which. |\n| 422 | `idempotency_key_reused` | That Idempotency-Key was used for a different request. |\n| 429 | `rate_limited` | Too many requests. Wait for the `Retry-After` header. |\n| 500 | `internal_error` | Our fault. Try again; quote the traceId if it persists. |\n| 503 | `busy` | SignSwifly is busy with other documents. Nothing was done: wait for the `Retry-After` header and send the request again, with the same Idempotency-Key. |\n\n# Rate limits\n\nEach key may make **600 requests a minute**. Every response carries\n`X-RateLimit-Limit` and `X-RateLimit-Remaining`; a `429` carries `Retry-After`, in seconds. Webhooks are the\nway to hear about changes — polling status is for catching up, not for watching.\n\n# Idempotency\n\n`POST /envelopes`, `POST /envelopes/from-template` and `POST /envelopes/{id}/send` take an\n`Idempotency-Key` header — a UUID of your own is ideal. Send the same request again with the same key (after a\ntimeout, say) and you get the first answer back, marked `Idempotent-Replayed: true`, and nothing happens twice.\nKeys last 24 hours. A request that was refused doesn't keep its key, so you can fix it and retry with the same one.\n\n# Word documents\n\nA `.docx`, `.doc` or `.rtf` in `POST /envelopes` becomes a PDF as the envelope is made, and only the PDF is\nkept: the Word file is never stored, and tags typed in it never become fields. Its fonts are embedded (Calibri\nis drawn in Carlito, which has the same widths, so pages break as in Word), its comments are removed, and\npictures or links to other places are unlinked. One with tracked changes is refused with `422 refused` and a\n`detail` saying to accept or reject them in Word first. A file past the size limits (more than 10 pictures,\nsay), or one that isn't a Word file inside (a web page saved as `.doc`), is converted the simpler way instead,\nas before, never refused; its fonts and page breaks may then differ from Word's, and the answer doesn't say so.\n\n# Pagination\n\nLists return `{ \"data\": [...], \"hasMore\": true, \"nextCursor\": \"…\" }`. Pass `nextCursor` back as `?cursor=` for\nthe next page; `limit` is 1 to 100 (25 by default).\n\n# Embedded signing\n\nA recipient added with `\"delivery\": \"inPerson\"` signs in your own app rather than from an email: once it is\ntheir turn, `POST /envelopes/{id}/recipients/{recipientId}/signing-link` gives a fresh link to open for them\n(the send response includes these links too). Open it full-page or in a new window: signing pages can't be\nshown inside another site's frame, so nobody can be tricked into signing through one. Each link replaces the\none before, and each is on the audit trail. Links are only given for in-person signers: an emailed signer's link is proof they hold that address,\nand it stays theirs alone.\n\n# Webhooks\n\nRegister an HTTPS endpoint in **Settings → API & webhooks** or with `POST /webhooks`, choosing its events:\n\n| Event | When |\n|---|---|\n| `envelope.sent` | An envelope was sent for signature. |\n| `recipient.viewed` | A recipient opened it for the first time. |\n| `recipient.signed` | A recipient signed; others may still be to. |\n| `envelope.completed` | Everyone signed and the documents were sealed. |\n| `envelope.declined` | A recipient declined, which ends the envelope. `data.reason` has what they said. |\n| `envelope.expired` | It ran out of time. |\n| `envelope.voided` | The sender voided it. |\n| `recipient.delivery_failed` | An email to a recipient bounced or was refused. `data.reason` says how. |\n\n`recipient.viewed` is sent once for each recipient: for the first time they open it while it's their turn,\nhowever often they open it after. A signing group is one recipient, so it's sent when the first person in the\ngroup opens it. If the sender corrects someone's address, the corrected person's first view is sent, under the\nsame recipient `id`. A first view from before an endpoint was listening, or while it was off or the workspace\nwas on Free, isn't sent later. The envelope's audit trail records every view.\n\nEach delivery is a `POST` of JSON:\n\n```json\n{\n  \"id\": \"evt_4f0c…\",\n  \"type\": \"recipient.signed\",\n  \"createdAt\": \"2026-09-29T01:02:03Z\",\n  \"apiVersion\": \"v1\",\n  \"workspaceId\": \"…\",\n  \"test\": false,\n  \"data\": {\n    \"envelope\": { \"id\": \"…\", \"subject\": \"Lease\", \"status\": \"sent\", \"createdAt\": \"…\", \"sentAt\": \"…\" },\n    \"recipient\": { \"id\": \"…\", \"name\": \"Jane Citizen\", \"email\": \"jane@example.com\", \"role\": \"signer\",\n                   \"status\": \"signed\", \"routingOrder\": 1 }\n  }\n}\n```\n\n`test` is `true` for a test envelope's events, which go to test endpoints only (see Test mode).\n\nAnswer with any `2xx` within 10 seconds; do the work afterwards. Anything else — another status, a\nredirect, a timeout — is retried with backoff (1 minute, 5 minutes, 30 minutes, 2 hours, then every 5 to 12\nhours) for about **three days**, then marked failed. An endpoint whose every delivery has failed for three\ndays is switched off, and the workspace's owner and admins are emailed. Retries are made by a job that runs\nevery 15 minutes, so a retry can be that much later than scheduled. Delivery is **at least once**: use\n`id` to ignore a repeat. Order isn't guaranteed; `createdAt` says when each thing happened.\n\nOn the Free plan nothing is sent, and what happens while the workspace is on Free is never sent, even once\nit's back on a paid plan. A delivery already waiting is marked failed if its next try comes while on Free, and\ncarries on if it comes after the move back.\n\nThe delivery log in Settings (and `GET /webhooks/{id}/deliveries`) shows each delivery's status, response\ncode, latency and the start of what your endpoint answered, for 30 days. Any delivery can be sent again, and a\ntest event sent at any time.\n\nEndpoints must be HTTPS on the public internet: addresses that resolve to private, loopback or link-local\nnetworks are refused when you register them and again at every delivery. Redirects aren't followed.\n\n## Verifying a delivery\n\nEvery delivery carries `SignSwifly-Signature: t=<unix seconds>,v1=<hex>`: an HMAC-SHA256, keyed with the\nendpoint's signing secret (`whsec_…`, shown once when you make the endpoint or rotate its secret), over the\ntimestamp, a full stop, and the **raw** request body. Check it against the raw bytes before parsing them,\ncompare in constant time, and refuse anything older than five minutes so a recorded delivery can't be\nreplayed. `SignSwifly-Event-Id` and `SignSwifly-Event-Type` repeat the event's id and type.\n\nC#:\n\n```csharp\nusing System.Security.Cryptography;\nusing System.Text;\n\nstatic bool VerifySignSwifly(string secret, string signatureHeader, string rawBody, TimeSpan? tolerance = null)\n{\n    long? timestamp = null;\n    var signatures = new List<string>();\n    foreach (var part in signatureHeader.Split(','))\n    {\n        var pair = part.Split('=', 2);\n        if (pair.Length != 2) continue;\n        if (pair[0].Trim() == \"t\" && long.TryParse(pair[1].Trim(), out var t)) timestamp = t;\n        else if (pair[0].Trim() == \"v1\") signatures.Add(pair[1].Trim());\n    }\n    if (timestamp is null || signatures.Count == 0) return false;\n    var age = DateTimeOffset.UtcNow.ToUnixTimeSeconds() - timestamp.Value;\n    if (Math.Abs(age) > (tolerance ?? TimeSpan.FromMinutes(5)).TotalSeconds) return false;\n\n    var expected = Encoding.ASCII.GetBytes(Convert.ToHexStringLower(HMACSHA256.HashData(\n        Encoding.UTF8.GetBytes(secret), Encoding.UTF8.GetBytes($\"{timestamp}.{rawBody}\"))));\n    var matched = false;\n    foreach (var signature in signatures)\n        matched |= CryptographicOperations.FixedTimeEquals(expected, Encoding.ASCII.GetBytes(signature));\n    return matched;\n}\n```\n\nJavaScript (Node):\n\n```javascript\nconst crypto = require(\"crypto\");\n\nfunction verifySignSwifly(secret, signatureHeader, rawBody, toleranceSeconds = 300) {\n  let timestamp = null;\n  const signatures = [];\n  for (const part of String(signatureHeader || \"\").split(\",\")) {\n    const at = part.indexOf(\"=\");\n    if (at < 0) continue;\n    const key = part.slice(0, at).trim(), value = part.slice(at + 1).trim();\n    if (key === \"t\") timestamp = Number(value);\n    else if (key === \"v1\") signatures.push(value);\n  }\n  if (!Number.isInteger(timestamp) || signatures.length === 0) return false;\n  if (Math.abs(Math.floor(Date.now() / 1000) - timestamp) > toleranceSeconds) return false;\n\n  const expected = Buffer.from(\n    crypto.createHmac(\"sha256\", secret).update(`${timestamp}.${rawBody}`, \"utf8\").digest(\"hex\"));\n  let matched = false;\n  for (const signature of signatures) {\n    const given = Buffer.from(signature);\n    if (given.length === expected.length && crypto.timingSafeEqual(given, expected)) matched = true;\n  }\n  return matched;\n}\n\n// Express: verify against the raw bytes, before anything parses them.\napp.post(\"/webhooks/signswifly\", express.raw({ type: \"application/json\" }), (req, res) => {\n  const ok = verifySignSwifly(process.env.SIGNSWIFLY_WEBHOOK_SECRET,\n    req.get(\"SignSwifly-Signature\"), req.body.toString(\"utf8\"));\n  if (!ok) return res.sendStatus(400);\n  const event = JSON.parse(req.body.toString(\"utf8\"));\n  // De-duplicate on event.id: a delivery can arrive more than once.\n  res.sendStatus(200);\n});\n```",
    "version": "v1"
  },
  "servers": [
    {
      "url": "https://anz.signswifly.com.au"
    }
  ],
  "paths": {
    "/api/v1/me": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "Who this key acts as",
        "description": "The workspace, the key, its scopes, and the owner or admin it acts as. Needs no scope: a quick check a key works.\n\nNeeds no scope.",
        "operationId": "getMe",
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Me"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/envelopes": {
      "get": {
        "tags": [
          "Envelopes"
        ],
        "summary": "List envelopes",
        "description": "Newest first, 25 to a page (limit up to 100). status narrows to draft, sent, completed, declined, voided or expired; archived=true lists the archived ones instead.\n\nNeeds the `envelopes:read` scope.",
        "operationId": "listEnvelopes",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "archived",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PageOfEnvelopeSummary"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Envelopes"
        ],
        "summary": "Create an envelope from documents",
        "description": "Documents (base64), recipients, fields and options in one request; set send to true to send it straight away. All or nothing: a refusal leaves no draft behind. Takes an Idempotency-Key header.\n\nNeeds the `envelopes:write` scope.",
        "operationId": "createEnvelope",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateEnvelopeRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EnvelopeActionResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/envelopes/from-template": {
      "post": {
        "tags": [
          "Envelopes"
        ],
        "summary": "Create an envelope from a template",
        "description": "Fill the template's roles and variables (see GET /templates/{id}); set send to true to send it straight away. Takes an Idempotency-Key header.\n\nNeeds the `envelopes:write` scope.",
        "operationId": "createEnvelopeFromTemplate",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateFromTemplateRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EnvelopeActionResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/envelopes/{envelopeId}": {
      "get": {
        "tags": [
          "Envelopes"
        ],
        "summary": "Get an envelope",
        "description": "Needs the `envelopes:read` scope.",
        "operationId": "getEnvelope",
        "parameters": [
          {
            "name": "envelopeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/envelopes/{envelopeId}/status": {
      "get": {
        "tags": [
          "Envelopes"
        ],
        "summary": "Get an envelope's status and each recipient's progress",
        "description": "Small enough to poll; webhooks are the better way to hear of changes.\n\nNeeds the `envelopes:read` scope.",
        "operationId": "getEnvelopeStatus",
        "parameters": [
          {
            "name": "envelopeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EnvelopeStatus"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/envelopes/{envelopeId}/send": {
      "post": {
        "tags": [
          "Envelopes"
        ],
        "summary": "Send a draft",
        "description": "Emails (or texts) everyone whose turn it is. In-person signers' links come back in signingLinks. Takes an Idempotency-Key header.\n\nNeeds the `envelopes:write` scope.",
        "operationId": "sendEnvelope",
        "parameters": [
          {
            "name": "envelopeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EnvelopeActionResult"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/envelopes/{envelopeId}/void": {
      "post": {
        "tags": [
          "Envelopes"
        ],
        "summary": "Void an envelope",
        "description": "Stops a sent envelope: nobody can sign it from here on.\n\nNeeds the `envelopes:write` scope.",
        "operationId": "voidEnvelope",
        "parameters": [
          {
            "name": "envelopeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/envelopes/{envelopeId}/remind": {
      "post": {
        "tags": [
          "Envelopes"
        ],
        "summary": "Remind everyone whose turn it is",
        "description": "Anyone whose invitation bounced is not emailed (a text still goes, if they get one): they come back with remindersPaused true. Everyone else whose turn it is was reminded.\n\nNeeds the `envelopes:write` scope.",
        "operationId": "remindEnvelope",
        "parameters": [
          {
            "name": "envelopeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/envelopes/{envelopeId}/recipients/{recipientId}/resend": {
      "post": {
        "tags": [
          "Envelopes"
        ],
        "summary": "Send one recipient their invitation again",
        "description": "With a new link; any link they already hold keeps working.\n\nNeeds the `envelopes:write` scope.",
        "operationId": "resendInvitation",
        "parameters": [
          {
            "name": "envelopeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "recipientId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/envelopes/{envelopeId}/recipients/{recipientId}/signing-link": {
      "post": {
        "tags": [
          "Envelopes"
        ],
        "summary": "Get a signing link for an in-person signer",
        "description": "Embedded signing: a fresh link for a recipient added with delivery inPerson, whose turn it is, to open for them in your own app. It replaces any link issued before, and is on the envelope's trail. Not available for emailed signers, whose link is theirs alone.\n\nNeeds the `envelopes:write` scope.",
        "operationId": "getSigningLink",
        "parameters": [
          {
            "name": "envelopeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "recipientId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SigningLink"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/envelopes/{envelopeId}/documents/{documentId}/sealed": {
      "get": {
        "tags": [
          "Documents"
        ],
        "summary": "Download a signed, sealed document",
        "description": "Needs the `documents:read` scope.",
        "operationId": "downloadSealedDocument",
        "parameters": [
          {
            "name": "envelopeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "documentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/envelopes/{envelopeId}/combined": {
      "get": {
        "tags": [
          "Documents"
        ],
        "summary": "Download every sealed document and the certificate as one PDF",
        "description": "Where the envelope completed with a combined PDF (combinedDocumentAvailable).\n\nNeeds the `documents:read` scope.",
        "operationId": "downloadCombinedDocument",
        "parameters": [
          {
            "name": "envelopeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/envelopes/{envelopeId}/certificate": {
      "get": {
        "tags": [
          "Documents"
        ],
        "summary": "Download the certificate of completion",
        "description": "Needs the `documents:read` scope.",
        "operationId": "downloadCertificate",
        "parameters": [
          {
            "name": "envelopeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/templates": {
      "get": {
        "tags": [
          "Templates"
        ],
        "summary": "List templates",
        "description": "Most recently changed first. Only active ones can make an envelope.\n\nNeeds the `templates:read` scope.",
        "operationId": "listTemplates",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PageOfTemplateSummary"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/templates/{templateId}": {
      "get": {
        "tags": [
          "Templates"
        ],
        "summary": "Get a template's roles and variables",
        "description": "Needs the `templates:read` scope.",
        "operationId": "getTemplate",
        "parameters": [
          {
            "name": "templateId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Template"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/webhooks": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "summary": "List webhook endpoints",
        "description": "Needs the `webhooks:manage` scope.",
        "operationId": "listWebhooks",
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WebhookEndpoint"
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Register a webhook endpoint",
        "description": "An HTTPS URL on the public internet, and the events to send to it (\"*\" for all). The signing secret comes back this once.\n\nNeeds the `webhooks:manage` scope.",
        "operationId": "createWebhook",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWebhookRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpointWithSecret"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/webhooks/{endpointId}": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Get a webhook endpoint",
        "description": "Needs the `webhooks:manage` scope.",
        "operationId": "getWebhook",
        "parameters": [
          {
            "name": "endpointId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpoint"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Change a webhook endpoint, or switch it off or on",
        "description": "Needs the `webhooks:manage` scope.",
        "operationId": "updateWebhook",
        "parameters": [
          {
            "name": "endpointId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateWebhookRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpoint"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Remove a webhook endpoint",
        "description": "Needs the `webhooks:manage` scope.",
        "operationId": "deleteWebhook",
        "parameters": [
          {
            "name": "endpointId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "204": {
            "description": "No Content"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/webhooks/{endpointId}/rotate-secret": {
      "post": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Replace an endpoint's signing secret",
        "description": "The new secret signs from the next delivery, and comes back this once; the old one stops at once.\n\nNeeds the `webhooks:manage` scope.",
        "operationId": "rotateWebhookSecret",
        "parameters": [
          {
            "name": "endpointId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEndpointWithSecret"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/webhooks/{endpointId}/test": {
      "post": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Send a test event to an endpoint, now",
        "description": "Needs the `webhooks:manage` scope.",
        "operationId": "sendTestWebhook",
        "parameters": [
          {
            "name": "endpointId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookDelivery"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/webhooks/{endpointId}/deliveries": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "summary": "An endpoint's delivery log",
        "description": "Newest first, 25 at a time; pass the last one's createdAt as ?before= for the next. Kept for 30 days.\n\nNeeds the `webhooks:manage` scope.",
        "operationId": "listWebhookDeliveries",
        "parameters": [
          {
            "name": "endpointId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "before",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WebhookDelivery"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/webhooks/{endpointId}/deliveries/{deliveryId}/resend": {
      "post": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Send one delivery again, now",
        "description": "The same event id and body, freshly signed.\n\nNeeds the `webhooks:manage` scope.",
        "operationId": "resendWebhookDelivery",
        "parameters": [
          {
            "name": "endpointId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "deliveryId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookDelivery"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "CreateEnvelopeRequest": {
        "required": [
          "subject",
          "message",
          "documents",
          "recipients"
        ],
        "type": "object",
        "properties": {
          "subject": {
            "type": "string"
          },
          "message": {
            "type": [
              "null",
              "string"
            ]
          },
          "documents": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DocumentUpload"
            }
          },
          "recipients": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NewRecipient"
            }
          },
          "fields": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/NewField"
            }
          },
          "options": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/EnvelopeOptions"
              }
            ]
          },
          "send": {
            "type": "boolean",
            "description": "Send it straight away. Otherwise it is created as a draft, to send with POST /envelopes/{id}/send.",
            "default": false
          }
        },
        "description": "A new envelope from PDF (or Word, or image) documents, the people it goes to, and the fields each fills in."
      },
      "CreateFromTemplateRequest": {
        "required": [
          "templateId"
        ],
        "type": "object",
        "properties": {
          "templateId": {
            "type": "string",
            "format": "uuid"
          },
          "variables": {
            "type": [
              "null",
              "object"
            ],
            "additionalProperties": {
              "type": "string"
            },
            "description": "Values for the template's variables, by name. An optional clause (kind clause) takes yes or no (also true, false, y, n, 1 or 0); left out, it takes the template's default."
          },
          "recipients": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/RoleFill"
            },
            "description": "Who fills each of the template's roles. A role left out takes its default name and email."
          },
          "send": {
            "type": "boolean",
            "default": false
          }
        },
        "description": "A new envelope from one of the workspace's active templates."
      },
      "CreateWebhookRequest": {
        "required": [
          "url",
          "events"
        ],
        "type": "object",
        "properties": {
          "url": {
            "type": "string"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "description": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "Document": {
        "required": [
          "id",
          "fileName",
          "pageCount",
          "sealed"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "fileName": {
            "type": "string"
          },
          "pageCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "sealed": {
            "type": "boolean",
            "description": "Whether the signed, sealed copy exists: GET …/documents/{id}/sealed."
          }
        }
      },
      "DocumentUpload": {
        "required": [
          "fileName",
          "contentBase64"
        ],
        "type": "object",
        "properties": {
          "fileName": {
            "type": "string",
            "description": "With its extension: .pdf, .docx or an image. Word and images are turned into PDF."
          },
          "contentBase64": {
            "type": "string",
            "description": "The file's bytes, base64-encoded."
          }
        }
      },
      "Envelope": {
        "required": [
          "id",
          "subject",
          "message",
          "status",
          "createdAt",
          "sentAt",
          "completedAt",
          "expiresAt",
          "archived",
          "senderEmail",
          "tags",
          "recipients",
          "documents",
          "combinedDocumentAvailable",
          "certificateAvailable"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "subject": {
            "type": "string"
          },
          "message": {
            "type": [
              "null",
              "string"
            ]
          },
          "status": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "sentAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "completedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "expiresAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "archived": {
            "type": "boolean"
          },
          "senderEmail": {
            "type": [
              "null",
              "string"
            ]
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "recipients": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Recipient"
            }
          },
          "documents": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Document"
            }
          },
          "combinedDocumentAvailable": {
            "type": "boolean",
            "description": "Whether GET /envelopes/{id}/combined has a PDF to give."
          },
          "certificateAvailable": {
            "type": "boolean",
            "description": "Whether GET /envelopes/{id}/certificate has a certificate to give: once completed."
          },
          "test": {
            "type": "boolean",
            "description": "A test envelope, made with a test key: see Test mode.",
            "default": false
          }
        },
        "description": "An envelope: its state, who it is for and how far each has got, and its documents."
      },
      "EnvelopeActionResult": {
        "required": [
          "envelope",
          "signingLinks"
        ],
        "type": "object",
        "properties": {
          "envelope": {
            "$ref": "#/components/schemas/Envelope"
          },
          "signingLinks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SigningLink"
            }
          }
        },
        "description": "The envelope after an action, and a signing link for each in-person signer whose turn it now is."
      },
      "EnvelopeOptions": {
        "type": "object",
        "properties": {
          "validityDays": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "description": "Days signers have, 1 to 365; 0 for no expiry.",
            "format": "int32"
          },
          "remindersEnabled": {
            "type": [
              "null",
              "boolean"
            ]
          },
          "reminderEveryDays": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "description": "1, 3, 7, 30 or 90.",
            "format": "int32"
          },
          "completionEmails": {
            "type": [
              "null",
              "string"
            ],
            "description": "allRecipientsAndSender, senderOnly or none."
          },
          "completionMessage": {
            "type": [
              "null",
              "string"
            ]
          },
          "tags": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "string"
            }
          }
        },
        "description": "How the envelope runs. Anything left out takes the workspace's defaults."
      },
      "EnvelopeStatus": {
        "required": [
          "id",
          "status",
          "sentAt",
          "completedAt",
          "expiresAt",
          "recipients"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string"
          },
          "sentAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "completedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "expiresAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "recipients": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RecipientProgress"
            }
          }
        },
        "description": "Where an envelope has got to, without its documents: cheap enough to poll."
      },
      "EnvelopeSummary": {
        "required": [
          "id",
          "subject",
          "status",
          "createdAt",
          "sentAt",
          "completedAt",
          "expiresAt",
          "archived",
          "recipientCount",
          "signedCount"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "subject": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "sentAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "completedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "expiresAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "archived": {
            "type": "boolean"
          },
          "recipientCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "signedCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "test": {
            "type": "boolean",
            "description": "A test envelope, made with a test key: see Test mode.",
            "default": false
          }
        },
        "description": "An envelope as a list shows it."
      },
      "Me": {
        "required": [
          "workspaceId",
          "keyName",
          "keyHint",
          "scopes",
          "actsAs"
        ],
        "type": "object",
        "properties": {
          "workspaceId": {
            "type": "string",
            "format": "uuid"
          },
          "keyName": {
            "type": "string"
          },
          "keyHint": {
            "type": "string"
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "actsAs": {
            "type": "string",
            "description": "The owner or admin the key acts as: the sender of anything it sends."
          },
          "test": {
            "type": "boolean",
            "description": "A test key (ssk_test_…): what it makes are test envelopes and test endpoints. See Test mode.",
            "default": false
          }
        },
        "description": "Who a key acts as, and what it may do."
      },
      "NewField": {
        "required": [
          "document",
          "recipient",
          "type",
          "page",
          "x",
          "y",
          "width",
          "height"
        ],
        "type": "object",
        "properties": {
          "document": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "Which document, by its position in documents, from 0.",
            "format": "int32"
          },
          "recipient": {
            "type": "string",
            "description": "The ref of the recipient who fills it in."
          },
          "type": {
            "type": "string",
            "description": "signature, initials, dateSigned, text, checkbox, signerName, dropdown, radio, approveDecline or fileUpload."
          },
          "page": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "From 1.",
            "format": "int32"
          },
          "x": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "y": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "width": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "height": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "required": {
            "type": "boolean",
            "default": true
          },
          "label": {
            "type": [
              "null",
              "string"
            ]
          },
          "options": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "string"
            },
            "description": "For dropdown and radio: the choices."
          }
        },
        "description": "A field to fill in. Coordinates are PDF points (1/72 inch) from the page's top-left corner."
      },
      "NewRecipient": {
        "required": [
          "ref",
          "name",
          "email"
        ],
        "type": "object",
        "properties": {
          "ref": {
            "type": "string",
            "description": "Your name for this recipient within the request, which fields and witnesses refer to: \"buyer\", \"r1\"."
          },
          "name": {
            "type": "string"
          },
          "email": {
            "type": [
              "null",
              "string"
            ]
          },
          "role": {
            "type": [
              "null",
              "string"
            ],
            "description": "signer (the default), witness or viewer."
          },
          "routingOrder": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "Who signs when: the same number signs at the same time, a higher one after. Defaults to 1. A witness is the exception: see witnessFor.",
            "format": "int32",
            "default": 1
          },
          "delivery": {
            "type": [
              "null",
              "string"
            ],
            "description": "email (the default), inPerson — signs in your own app with a link from POST …/signing-link — or sms (Scale, or Solo and Team with the SMS add-on)."
          },
          "mobile": {
            "type": [
              "null",
              "string"
            ],
            "description": "A mobile number. With delivery sms it is how they are reached; otherwise the link is texted too."
          },
          "requireSmsVerification": {
            "type": "boolean",
            "description": "Make them enter a code texted to that mobile before signing (Scale, or Solo and Team with the SMS add-on).",
            "default": false
          },
          "witnessFor": {
            "type": [
              "null",
              "string"
            ],
            "description": "For a witness: the ref of the signer they witness. Give the witness a higher routingOrder than that signer. The witness is asked as soon as that signer has signed, even while others on earlier steps are still signing, and anyone on a later step than the witness waits for them."
          },
          "message": {
            "type": [
              "null",
              "string"
            ],
            "description": "A note shown to this recipient only."
          }
        }
      },
      "PageOfEnvelopeSummary": {
        "required": [
          "data",
          "hasMore",
          "nextCursor"
        ],
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EnvelopeSummary"
            }
          },
          "hasMore": {
            "type": "boolean"
          },
          "nextCursor": {
            "type": [
              "null",
              "string"
            ]
          }
        },
        "description": "One page of a list. Pass nextCursor back as ?cursor= for the next page."
      },
      "PageOfTemplateSummary": {
        "required": [
          "data",
          "hasMore",
          "nextCursor"
        ],
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TemplateSummary"
            }
          },
          "hasMore": {
            "type": "boolean"
          },
          "nextCursor": {
            "type": [
              "null",
              "string"
            ]
          }
        },
        "description": "One page of a list. Pass nextCursor back as ?cursor= for the next page."
      },
      "ProblemDetails": {
        "type": "object",
        "properties": {
          "type": {
            "type": [
              "null",
              "string"
            ]
          },
          "title": {
            "type": [
              "null",
              "string"
            ]
          },
          "status": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "detail": {
            "type": [
              "null",
              "string"
            ]
          },
          "instance": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "Recipient": {
        "required": [
          "id",
          "name",
          "email",
          "role",
          "status",
          "routingOrder",
          "delivery",
          "sentAt",
          "viewedAt",
          "signedAt",
          "declineReason",
          "currentTurn",
          "signingGroup",
          "undelivered"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "email": {
            "type": [
              "null",
              "string"
            ]
          },
          "role": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "routingOrder": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "delivery": {
            "type": "string",
            "description": "email, inPerson or sms."
          },
          "sentAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "viewedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "signedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "declineReason": {
            "type": [
              "null",
              "string"
            ]
          },
          "currentTurn": {
            "type": "boolean",
            "description": "Whether it is this recipient's turn now. A witness's turn comes as soon as the signer they witness has signed, even while others before them are still signing."
          },
          "signingGroup": {
            "type": [
              "null",
              "string"
            ],
            "description": "The signing group this step went to, if it did."
          },
          "undelivered": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "description": "Set when an email to them bounced or was refused.",
                "$ref": "#/components/schemas/Undelivered"
              }
            ]
          },
          "remindersPaused": {
            "type": "boolean",
            "description": "True while their reminders are paused because their invitation bounced: the reminders, and POST /envelopes/{id}/remind, skip their email (a text still goes, if they get one). Resending, correcting the address, or the sender choosing to keep reminding them in the app lifts it.",
            "default": false
          }
        },
        "description": "A recipient and their progress. role is signer, witness or viewer; status is pending, sent, viewed, signed or declined."
      },
      "RecipientProgress": {
        "required": [
          "id",
          "name",
          "role",
          "status",
          "routingOrder",
          "signedAt",
          "currentTurn",
          "undelivered"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "role": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "routingOrder": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "signedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "currentTurn": {
            "type": "boolean"
          },
          "undelivered": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/Undelivered"
              }
            ]
          }
        }
      },
      "RoleFill": {
        "required": [
          "roleId"
        ],
        "type": "object",
        "properties": {
          "roleId": {
            "type": "string",
            "description": "The role's id, from GET /templates/{id}.",
            "format": "uuid"
          },
          "name": {
            "type": [
              "null",
              "string"
            ]
          },
          "email": {
            "type": [
              "null",
              "string"
            ]
          },
          "mobile": {
            "type": [
              "null",
              "string"
            ],
            "description": "For a role that is sent a code before signing."
          },
          "skip": {
            "type": "boolean",
            "description": "Leave an optional role out of this envelope.",
            "default": false
          }
        }
      },
      "SigningLink": {
        "required": [
          "recipientId",
          "name",
          "url"
        ],
        "type": "object",
        "properties": {
          "recipientId": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "url": {
            "type": "string"
          }
        },
        "description": "A link that opens the signing page for one in-person signer. Open it for them in your own app; it replaces any link issued before."
      },
      "Template": {
        "required": [
          "id",
          "name",
          "description",
          "status",
          "subject",
          "roles",
          "variables",
          "documents"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": [
              "null",
              "string"
            ]
          },
          "status": {
            "type": "string"
          },
          "subject": {
            "type": [
              "null",
              "string"
            ]
          },
          "roles": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TemplateRole"
            }
          },
          "variables": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TemplateVariable"
            }
          },
          "documents": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TemplateDocument"
            }
          }
        },
        "description": "A template: the roles to fill and the variables to give when making an envelope from it. A document with format word is drawn from its wording each time the template is used: values are written into its sentences, each optional clause is kept or left out as answered, and each field is placed where its field tag is, such as [[Signature:tenant]] for the role whose key is tenant."
      },
      "TemplateDocument": {
        "required": [
          "id",
          "fileName",
          "pageCount"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "fileName": {
            "type": "string"
          },
          "pageCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "description": "Pages in the document. For a Word document (format word), the pages of its preview: it may change once values are filled in and optional clauses kept or left out.",
            "format": "int32"
          },
          "format": {
            "type": [
              "null",
              "string"
            ],
            "description": "word for a document drawn from its Word wording each time the template is used; pdf for a fixed PDF, whose values are written over its pages. Given for a template whose documents can be Word documents."
          }
        }
      },
      "TemplateRole": {
        "required": [
          "id",
          "label",
          "role",
          "routingOrder",
          "defaultName",
          "defaultEmail",
          "optional",
          "delivery",
          "needsMobile"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "label": {
            "type": "string",
            "description": "What the template calls this role, such as \"Tenant\"."
          },
          "role": {
            "type": "string"
          },
          "routingOrder": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "defaultName": {
            "type": [
              "null",
              "string"
            ]
          },
          "defaultEmail": {
            "type": [
              "null",
              "string"
            ]
          },
          "optional": {
            "type": "boolean"
          },
          "delivery": {
            "type": "string"
          },
          "needsMobile": {
            "type": "boolean",
            "description": "A mobile must be given for this role: it is sent a code before signing."
          },
          "key": {
            "type": [
              "null",
              "string"
            ],
            "description": "What a field tag in a Word document names this role by: [[Signature:tenant]] is a signature for the role whose key is tenant. Given once the template has had a Word document."
          }
        }
      },
      "TemplateSummary": {
        "required": [
          "id",
          "name",
          "description",
          "status",
          "updatedAt",
          "roleCount",
          "variableCount",
          "tags"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": [
              "null",
              "string"
            ]
          },
          "status": {
            "type": "string"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "roleCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "variableCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "TemplateVariable": {
        "required": [
          "name",
          "kind",
          "validation",
          "required",
          "defaultValue",
          "tableColumns"
        ],
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "description": "text, richText, image, table or clause. A clause is an optional part of a Word document's wording, kept or left out: give it yes or no."
          },
          "validation": {
            "type": "string",
            "description": "none, email, number, date, futureDate, pastDate or australianMobile."
          },
          "required": {
            "type": "boolean"
          },
          "defaultValue": {
            "type": [
              "null",
              "string"
            ],
            "description": "For text variables, and yes or no for a clause; pictures and tables aren't repeated here."
          },
          "tableColumns": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "string"
            },
            "description": "For a table: its column headings, in order. Give its value as a JSON array of rows, each an array of cells in this order, such as [[\"Discovery\",\"Week 2\"]]. Cells wrap within their columns, and rows that don't fit below where the document places the table go on pages added at the end of the document, which pageCount includes. More columns than fit across the page, a row taller than a page, more than 2,000 rows, or more than 100 pages added for one table, is refused. In a Word document (format word) the table is part of the wording instead: its rows continue across the pages within the document, its heading row repeated, and no pages are added at the end; more than 2,000 rows is refused."
          }
        }
      },
      "Undelivered": {
        "required": [
          "email",
          "at"
        ],
        "type": "object",
        "properties": {
          "email": {
            "type": "string"
          },
          "at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "UpdateWebhookRequest": {
        "type": "object",
        "properties": {
          "url": {
            "type": [
              "null",
              "string"
            ]
          },
          "events": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "string"
            }
          },
          "description": {
            "type": [
              "null",
              "string"
            ]
          },
          "enabled": {
            "type": [
              "null",
              "boolean"
            ]
          }
        },
        "description": "Changes what is given and leaves the rest."
      },
      "WebhookDelivery": {
        "required": [
          "id",
          "eventId",
          "eventType",
          "envelopeId",
          "status",
          "attempts",
          "createdAt",
          "lastAttemptAt",
          "responseStatus",
          "latencyMs",
          "responseBody",
          "error",
          "nextAttemptAt"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "eventId": {
            "type": "string"
          },
          "eventType": {
            "type": "string"
          },
          "envelopeId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "description": "pending, delivered or failed."
          },
          "attempts": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastAttemptAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "responseStatus": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "latencyMs": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "responseBody": {
            "type": [
              "null",
              "string"
            ],
            "description": "The start of what your endpoint answered."
          },
          "error": {
            "type": [
              "null",
              "string"
            ]
          },
          "nextAttemptAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          }
        }
      },
      "WebhookEndpoint": {
        "required": [
          "id",
          "url",
          "description",
          "events",
          "secretHint",
          "enabled",
          "disabledReason",
          "createdAt",
          "lastSuccessAt",
          "failingSince"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "url": {
            "type": "string"
          },
          "description": {
            "type": [
              "null",
              "string"
            ]
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "secretHint": {
            "type": "string",
            "description": "The last characters of the signing secret, to tell secrets apart."
          },
          "enabled": {
            "type": "boolean"
          },
          "disabledReason": {
            "type": [
              "null",
              "string"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastSuccessAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "failingSince": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "test": {
            "type": "boolean",
            "description": "A test endpoint: it hears about test envelopes only, and is made with a test key. See Test mode.",
            "default": false
          }
        }
      },
      "WebhookEndpointWithSecret": {
        "required": [
          "endpoint",
          "secret"
        ],
        "type": "object",
        "properties": {
          "endpoint": {
            "$ref": "#/components/schemas/WebhookEndpoint"
          },
          "secret": {
            "type": "string"
          }
        },
        "description": "An endpoint and its signing secret. The secret is shown this once; keep it where your receiver can read it."
      }
    },
    "securitySchemes": {
      "ApiKey": {
        "type": "http",
        "description": "An API key from Settings → API & webhooks.",
        "scheme": "bearer",
        "bearerFormat": "ssk_live_… or ssk_test_…"
      }
    }
  },
  "security": [
    {
      "ApiKey": [ ]
    }
  ],
  "tags": [
    {
      "name": "Account"
    },
    {
      "name": "Envelopes"
    },
    {
      "name": "Documents"
    },
    {
      "name": "Templates"
    },
    {
      "name": "Webhooks"
    }
  ]
}