{"openapi":"3.1.0","info":{"title":"FreeDocuSignature API","version":"1.0.0","summary":"Send agreements for signature from your own software.","description":"Create and send agreements, follow them to completion, and collect the executed PDF. Every request carries an API key as a bearer token. Deliveries in the other direction are described under `webhooks`.","contact":{"name":"FreeDocuSignature","url":"https://freedocusignature.com/developers"},"license":{"name":"Terms of service","url":"https://freedocusignature.com/legal/terms"}},"servers":[{"url":"https://freedocusignature.com","description":"Production"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"Templates","description":"What this account can send, and the roles each takes."},{"name":"Envelopes","description":"Agreements: create, follow, withdraw, download."},{"name":"Recipients","description":"The people on an agreement: resend, correct, inspect."},{"name":"Clients","description":"Counterparties on record, and their paperwork."},{"name":"Bulk sends","description":"One template across many recipients, queued."},{"name":"Folders","description":"Filing. Each standing view keeps its own tree, and a document is filed in at most one folder."}],"paths":{"/api/v1/templates/{id}/preview":{"get":{"tags":["Templates"],"summary":"The document with its field boxes drawn on it","description":"Answers 'where did my fields actually land' in one request. Returns the template's PDF with a labelled box over every field, so placement can be checked without sending a real agreement and taking the executed copy apart. It is a PDF rather than an image because pages are never rasterised on the server. The geometry is the same code the final stamp uses, so what you see here is where a value will be drawn.","operationId":"previewTemplate","security":[{"bearerAuth":["templates:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"The template's id."},{"name":"documentId","in":"query","required":false,"schema":{"type":"string","format":"uuid"},"description":"Which document, when the template has several. Defaults to the first."}],"responses":{"200":{"description":"The annotated PDF.","headers":{"X-Field-Count":{"schema":{"type":"integer"},"description":"How many boxes were drawn, so a caller can check the count without parsing the PDF."},"X-Document-Id":{"schema":{"type":"string","format":"uuid"}}},"content":{"application/pdf":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"No credentials were supplied, or the key is not valid or has been revoked. Codes: missing_credentials, invalid_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is valid but not allowed to do this, or the account is suspended. Codes: insufficient_scope, account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record for this account. Code: not_found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The template has no document. Code: no_documents.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"The stored document could not be read. Code: document_missing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests. Retry-After says how long to wait. Code: rate_limited.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on our side. Code: internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/folders":{"get":{"tags":["Folders"],"summary":"List folders","description":"One view's whole tree, flattened depth-first with parents before children. Every view's tree when `section` is omitted.","operationId":"listFolders","parameters":[{"name":"section","in":"query","required":false,"schema":{"type":"string","enum":["files","templates","drafts","awaiting","executed","closed"]},"description":"Which standing view's tree to return."}],"responses":{"200":{"description":"The tree.","content":{"application/json":{"schema":{"type":"object","properties":{"folders":{"type":"array","items":{"$ref":"#/components/schemas/Folder"}}}}}}},"401":{"description":"No credentials were supplied, or the key is not valid or has been revoked. Codes: missing_credentials, invalid_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is valid but not allowed to do this, or the account is suspended. Codes: insufficient_scope, account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests. Retry-After says how long to wait. Code: rate_limited.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on our side. Code: internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Folders"],"summary":"Create a folder","description":"Pass `parentId` to make a subfolder. A subfolder always belongs to its parent's view, so the parent's section overrides whatever `section` is sent.","operationId":"createFolder","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","minLength":1,"maxLength":120},"parentId":{"type":["string","null"],"format":"uuid","description":"The folder this one sits inside. Null or absent for the top level."},"section":{"type":"string","enum":["files","templates","drafts","awaiting","executed","closed"],"default":"files","description":"Ignored when parentId is given."}}}}}},"responses":{"201":{"description":"Created.","content":{"application/json":{"schema":{"type":"object","properties":{"folder":{"$ref":"#/components/schemas/Folder"}}}}}},"400":{"description":"Codes: invalid_request, invalid_section.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"No credentials were supplied, or the key is not valid or has been revoked. Codes: missing_credentials, invalid_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is valid but not allowed to do this, or the account is suspended. Codes: insufficient_scope, account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record for this account. Code: not_found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A request with this Idempotency-Key is still running, so this one was not started. Retry after the delay, keeping the same key. Code: idempotency_in_progress.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"This Idempotency-Key was already used for a different request body. A new request needs a new key. Code: idempotency_key_reused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests. Retry-After says how long to wait. Code: rate_limited.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on our side. Code: internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":255},"description":"A value unique to this attempt, reused unchanged on every retry of it. A retry replays the first result instead of doing the work again. A 4xx is not stored: the request was refused before anything happened, so a retry with the same key runs again. Keys are scoped to your account and kept for 24 hours."}]}},"/api/v1/folders/{id}":{"patch":{"tags":["Folders"],"summary":"Rename or move a folder","description":"A folder only moves within its own view, and never inside one of its own subfolders. Send `parentId: null` to move it to the top of its view.","operationId":"updateFolder","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"The folder's id."},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":255},"description":"A value unique to this attempt, reused unchanged on every retry of it. A retry replays the first result instead of doing the work again. A 4xx is not stored: the request was refused before anything happened, so a retry with the same key runs again. Keys are scoped to your account and kept for 24 hours."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","minProperties":1,"properties":{"name":{"type":"string","minLength":1,"maxLength":120},"parentId":{"type":["string","null"],"format":"uuid"}}}}}},"responses":{"200":{"description":"Updated.","content":{"application/json":{"schema":{"type":"object","properties":{"folder":{"$ref":"#/components/schemas/Folder"}}}}}},"400":{"description":"Codes: folder_into_itself, folder_into_descendant, folder_cross_section.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"No credentials were supplied, or the key is not valid or has been revoked. Codes: missing_credentials, invalid_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is valid but not allowed to do this, or the account is suspended. Codes: insufficient_scope, account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record for this account. Code: not_found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A request with this Idempotency-Key is still running, so this one was not started. Retry after the delay, keeping the same key. Code: idempotency_in_progress.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"This Idempotency-Key was already used for a different request body. A new request needs a new key. Code: idempotency_key_reused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests. Retry-After says how long to wait. Code: rate_limited.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on our side. Code: internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Folders"],"summary":"Move a folder to the trash","description":"Subfolders go with it. Documents are never destroyed — they are only detached, and only when the trash is finally purged, so tidying can never lose an agreement.","operationId":"deleteFolder","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"The folder's id."},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":255},"description":"A value unique to this attempt, reused unchanged on every retry of it. A retry replays the first result instead of doing the work again. A 4xx is not stored: the request was refused before anything happened, so a retry with the same key runs again. Keys are scoped to your account and kept for 24 hours."}],"responses":{"200":{"description":"In the trash.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean"}}}}}},"401":{"description":"No credentials were supplied, or the key is not valid or has been revoked. Codes: missing_credentials, invalid_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is valid but not allowed to do this, or the account is suspended. Codes: insufficient_scope, account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record for this account. Code: not_found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A request with this Idempotency-Key is still running, so this one was not started. Retry after the delay, keeping the same key. Code: idempotency_in_progress.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"This Idempotency-Key was already used for a different request body. A new request needs a new key. Code: idempotency_key_reused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests. Retry-After says how long to wait. Code: rate_limited.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on our side. Code: internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/folders/{id}/items":{"post":{"tags":["Folders"],"summary":"File documents into a folder","description":"Up to 100 of each per call. One bad id does not reject the batch: everything that could be filed is, and the rest come back in `failed` with a reason each.","operationId":"fileIntoFolder","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"The folder's id."},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":255},"description":"A value unique to this attempt, reused unchanged on every retry of it. A retry replays the first result instead of doing the work again. A 4xx is not stored: the request was refused before anything happened, so a retry with the same key runs again. Keys are scoped to your account and kept for 24 hours."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"envelopeIds":{"type":"array","maxItems":100,"items":{"type":"string"}},"templateIds":{"type":"array","maxItems":100,"items":{"type":"string"}}}}}}},"responses":{"200":{"description":"What was filed, and what was not.","content":{"application/json":{"schema":{"type":"object","properties":{"folderId":{"type":"string","format":"uuid"},"filed":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"id":{"type":"string"}}}},"failed":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"id":{"type":"string"},"code":{"type":"string"},"message":{"type":"string"}}}}}}}}},"401":{"description":"No credentials were supplied, or the key is not valid or has been revoked. Codes: missing_credentials, invalid_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is valid but not allowed to do this, or the account is suspended. Codes: insufficient_scope, account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record for this account. Code: not_found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A request with this Idempotency-Key is still running, so this one was not started. Retry after the delay, keeping the same key. Code: idempotency_in_progress.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"This Idempotency-Key was already used for a different request body. A new request needs a new key. Code: idempotency_key_reused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests. Retry-After says how long to wait. Code: rate_limited.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on our side. Code: internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/templates":{"post":{"tags":["Templates"],"operationId":"createTemplate","summary":"Build a template without opening the editor","description":"Post the documents and say where each role's fields go. Placement runs through the same resolver the send path uses, so a field anchored to \"/sig1/\" here lands exactly where one anchored to \"/sig1/\" lands there. Roles are positional: the first entry is routingOrder 1, and that is the number the send endpoints expect back. Every field is resolved before anything is written, so a template whose third role cannot be placed is refused rather than created half-built.","security":[{"bearerAuth":["templates:write"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTemplateRequest"},"example":{"name":"Mutual NDA","description":"Standard two-party NDA.","documents":[{"name":"nda.pdf","base64":"JVBERi0xLjcK…"}],"roles":[{"tabs":[{"type":"signature","anchorString":"/sig1/"},{"type":"date","anchorString":"/sig1/","anchorXOffset":200},{"type":"text","label":"Company name","anchorString":"/co1/","defaultValue":"Acme Ltd"}]},{"tabs":[{"type":"signature","anchorString":"/sig2/"}]}]}}}},"responses":{"201":{"description":"The template, ready to send.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTemplateResult"}}}},"400":{"description":"Refused, and nothing was created. Placement failures name the role they came from. Codes: invalid_json, invalid_request, invalid_document, not_a_pdf, no_documents, too_many_documents, anchor_not_found, tab_not_placed, document_not_found, page_not_found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"No credentials were supplied, or the key is not valid or has been revoked. Codes: missing_credentials, invalid_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The account is behind on payment, so it may not create work. Code: payment_required.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is valid but not allowed to do this, or the account is suspended. Codes: insufficient_scope, account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A request with this Idempotency-Key is still running, so this one was not started. Retry after the delay, keeping the same key. Code: idempotency_in_progress.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"A document is over 4 MB. Code: document_too_large.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"This Idempotency-Key was already used for a different request body. A new request needs a new key. Code: idempotency_key_reused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests. Retry-After says how long to wait. Code: rate_limited.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"The template could not be built and was removed rather than left half-made. Codes: template_not_created, internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":255},"description":"A value unique to this attempt, reused unchanged on every retry of it. A retry replays the first result instead of doing the work again. A 4xx is not stored: the request was refused before anything happened, so a retry with the same key runs again. Keys are scoped to your account and kept for 24 hours."}]},"get":{"tags":["Templates"],"operationId":"listTemplates","summary":"List the templates this account can send","description":"Newest first by last update. Each entry carries the roles it takes, with the exact `routingOrder` to send back when creating an agreement.","security":[{"bearerAuth":["templates:read"]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"description":"Values outside the range are clamped rather than refused."},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"A page of templates.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateList"}}}},"401":{"description":"No credentials were supplied, or the key is not valid or has been revoked. Codes: missing_credentials, invalid_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is valid but not allowed to do this, or the account is suspended. Codes: insufficient_scope, account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests. Retry-After says how long to wait. Code: rate_limited.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on our side. Code: internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/templates/{id}":{"get":{"tags":["Templates"],"operationId":"getTemplate","summary":"One template, with its roles and fields","description":"The roles carry the `routingOrder` to send back. Fields are listed by label, because a label is what `prefill` is keyed on and a caller cannot guess one.","security":[{"bearerAuth":["templates:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"The template's id."}],"responses":{"200":{"description":"The template.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateDetail"}}}},"401":{"description":"No credentials were supplied, or the key is not valid or has been revoked. Codes: missing_credentials, invalid_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is valid but not allowed to do this, or the account is suspended. Codes: insufficient_scope, account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record for this account. Code: not_found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests. Retry-After says how long to wait. Code: rate_limited.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on our side. Code: internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/envelopes":{"post":{"tags":["Envelopes"],"operationId":"createEnvelope","summary":"Create an agreement and send it","description":"Send either a stored template or the documents themselves — exactly one of `templateId` and `documents`. With documents, every recipient needs `tabs` saying where their fields go, by anchor text or by coordinates.","security":[{"bearerAuth":["envelopes:write"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEnvelopeRequest"},"examples":{"fromTemplate":{"summary":"From a stored template","value":{"templateId":"1f7c9c2e-2f6a-4a5e-9b1c-0a1b2c3d4e5f","title":"Hosting agreement","message":"Please review and sign by Friday.","recipients":[{"name":"Ada Lovelace","email":"ada@example.com","routingOrder":1}],"prefill":{"Company name":"Acme Ltd"},"reminderEveryDays":3,"expiresInDays":14}},"fromDocumentWithAnchors":{"summary":"A PDF, with fields placed by anchor text","value":{"documents":[{"name":"nda.pdf","base64":"JVBERi0xLjcK…"}],"title":"Mutual NDA","recipients":[{"name":"Ada Lovelace","email":"ada@example.com","routingOrder":1,"tabs":[{"type":"signature","anchorString":"/sig1/"},{"type":"date","anchorString":"/sig1/","anchorXOffset":200},{"type":"initials","anchorString":"/ini/","occurrence":"all"}]}]}},"embeddedRecipient":{"summary":"A recipient who signs inside your own application","value":{"templateId":"1f7c9c2e-2f6a-4a5e-9b1c-0a1b2c3d4e5f","title":"Onboarding pack","recipients":[{"name":"Ada Lovelace","email":"ada@example.com","routingOrder":1,"clientUserId":"user-42"}]}}}}}},"responses":{"201":{"description":"The agreement, as created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"description":"The request was refused. Codes include invalid_json, invalid_request, duplicate_routing_order, invalid_document, missing_recipient, recipient_email_invalid, recipient_has_no_tabs, anchor_not_found, tab_not_placed, page_not_found, document_not_found, not_a_pdf, no_documents, too_many_documents, template_empty, template_has_no_fields, no_fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"No credentials were supplied, or the key is not valid or has been revoked. Codes: missing_credentials, invalid_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The account is behind on payment and may not send. Code: payment_required.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is valid but not allowed to do this, or the account is suspended. Codes: insufficient_scope, account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"The template does not exist, or `clientId` names a client this account does not have. Codes: template_not_found, client_not_found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A request with this Idempotency-Key is still running, so this one was not started. Retry after the delay, keeping the same key. Code: idempotency_in_progress.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"A document is too large to arrive as JSON. Code: document_too_large.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"This Idempotency-Key was already used for a different request body. A new request needs a new key. Code: idempotency_key_reused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests. Retry-After says how long to wait. Code: rate_limited.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"The agreement could not be prepared and nothing was sent. Codes: snapshot_failed, internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":255},"description":"A value unique to this attempt, reused unchanged on every retry of it. A retry replays the first result instead of doing the work again. A 4xx is not stored: the request was refused before anything happened, so a retry with the same key runs again. Keys are scoped to your account and kept for 24 hours."}]},"get":{"tags":["Envelopes"],"operationId":"listEnvelopes","summary":"List agreements, newest first","security":[{"bearerAuth":["envelopes:read"]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25},"description":"Values outside the range are clamped rather than refused."},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0}},{"name":"status","in":"query","schema":{"type":"string"},"description":"One or more statuses, comma separated. An unrecognised value is refused with invalid_status.","example":"sent,viewed"}],"responses":{"200":{"description":"A page of agreements.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnvelopeList"}}}},"400":{"description":"An unrecognised status was supplied. Code: invalid_status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"No credentials were supplied, or the key is not valid or has been revoked. Codes: missing_credentials, invalid_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is valid but not allowed to do this, or the account is suspended. Codes: insufficient_scope, account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests. Retry-After says how long to wait. Code: rate_limited.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on our side. Code: internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/envelopes/{id}":{"patch":{"tags":["Envelopes"],"operationId":"updateEnvelope","summary":"Change how an agreement already out gets chased","description":"Only the reminder cadence. The title, the message and the documents are what the signer was shown and agreed to look at; changing those under them after the invitation has gone would not be an edit but a different agreement. This exists because omitting `reminderEveryDays` at send time otherwise left an agreement with reminders permanently off, and chasing is a decision a sender revisits after a week of silence.","security":[{"bearerAuth":["envelopes:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"The agreement's id."},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":255},"description":"A value unique to this attempt, reused unchanged on every retry of it. A retry replays the first result instead of doing the work again. A 4xx is not stored: the request was refused before anything happened, so a retry with the same key runs again. Keys are scoped to your account and kept for 24 hours."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEnvelopeRequest"},"examples":{"everyThreeDays":{"summary":"Chase every three days","value":{"reminderEveryDays":3}},"stopChasing":{"summary":"Stop chasing","value":{"reminderEveryDays":null}}}}}},"responses":{"200":{"description":"The agreement, with the new cadence.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"description":"Not a whole number from 2 to 30, and not null. Codes: invalid_json, invalid_request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"No credentials were supplied, or the key is not valid or has been revoked. Codes: missing_credentials, invalid_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is valid but not allowed to do this, or the account is suspended. Codes: insufficient_scope, account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record for this account. Code: not_found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The agreement is past draft, sent or viewed, so nobody is waiting to be reminded. Code: not_editable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"This Idempotency-Key was already used for a different request body. A new request needs a new key. Code: idempotency_key_reused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests. Retry-After says how long to wait. Code: rate_limited.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on our side. Code: internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"tags":["Envelopes"],"operationId":"getEnvelope","summary":"One agreement and the state of every party on it","security":[{"bearerAuth":["envelopes:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"The agreement's id."}],"responses":{"200":{"description":"The agreement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"401":{"description":"No credentials were supplied, or the key is not valid or has been revoked. Codes: missing_credentials, invalid_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is valid but not allowed to do this, or the account is suspended. Codes: insufficient_scope, account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record for this account. Code: not_found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests. Retry-After says how long to wait. Code: rate_limited.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on our side. Code: internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/envelopes/{id}/void":{"post":{"tags":["Envelopes"],"operationId":"voidEnvelope","summary":"Withdraw an agreement that is still out","description":"Voided, never deleted: the record and its audit trail are kept. An agreement that is already fully executed cannot be voided.","security":[{"bearerAuth":["envelopes:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"The agreement's id."},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":255},"description":"A value unique to this attempt, reused unchanged on every retry of it. A retry replays the first result instead of doing the work again. A 4xx is not stored: the request was refused before anything happened, so a retry with the same key runs again. Keys are scoped to your account and kept for 24 hours."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["reason"],"properties":{"reason":{"type":"string","minLength":1,"maxLength":500,"description":"Why it is being withdrawn. Kept in the audit trail."}}},"example":{"reason":"Superseded by a revised draft."}}}},"responses":{"200":{"description":"The agreement, now voided.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Envelope"}}}},"400":{"description":"No reason was given. Codes: invalid_json, invalid_request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"No credentials were supplied, or the key is not valid or has been revoked. Codes: missing_credentials, invalid_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is valid but not allowed to do this, or the account is suspended. Codes: insufficient_scope, account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record for this account. Code: not_found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"It cannot be voided in its current state. Codes: already_completed, already_voided.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"This Idempotency-Key was already used for a different request body. A new request needs a new key. Code: idempotency_key_reused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests. Retry-After says how long to wait. Code: rate_limited.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on our side. Code: internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/envelopes/{id}/document":{"get":{"tags":["Envelopes"],"operationId":"downloadExecutedDocument","summary":"The executed PDF","description":"Every signature stamped in, the certificate of completion appended, and the document's SHA-256 on every page. Available only once every party has signed; the unsigned original is never returned here. Each download is recorded in the audit trail.","security":[{"bearerAuth":["envelopes:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"The agreement's id."}],"responses":{"200":{"description":"The executed PDF.","headers":{"X-Document-Sha256":{"schema":{"type":"string"},"description":"The document's SHA-256, matching what is stamped on every page. Absent if the hash was never recorded."},"Content-Disposition":{"schema":{"type":"string"}}},"content":{"application/pdf":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"No credentials were supplied, or the key is not valid or has been revoked. Codes: missing_credentials, invalid_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is valid but not allowed to do this, or the account is suspended. Codes: insufficient_scope, account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record for this account. Code: not_found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not everyone has signed, so there is no executed copy yet. Code: not_executed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests. Retry-After says how long to wait. Code: rate_limited.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on our side. Code: internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/envelopes/{id}/views":{"post":{"tags":["Envelopes"],"operationId":"createRecipientView","summary":"A short-lived URL that drops a recipient into signing","description":"For a recipient signing inside your own application. The URL is deliberately not the recipient's emailed token, which has to survive weeks in an inbox; this one lasts minutes.","security":[{"bearerAuth":["envelopes:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"The agreement's id."},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":255},"description":"A value unique to this attempt, reused unchanged on every retry of it. A retry replays the first result instead of doing the work again. A 4xx is not stored: the request was refused before anything happened, so a retry with the same key runs again. Keys are scoped to your account and kept for 24 hours."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateViewRequest"},"example":{"clientUserId":"user-42","returnUrl":"https://example.com/signing-complete","embedOrigin":{"type":"string","maxLength":300,"example":"https://app.yourdomain.com","description":"Required to display this URL in an iframe. The bare origin of the page that will frame it — scheme, host, optional port; no path and no wildcards; https except http://localhost. Signing pages refuse framing by default, so the returned URL carries a signature permitting exactly this origin. Use the URL unchanged; editing it voids the permission."},"expiresInMinutes":15}}}},"responses":{"201":{"description":"The signing URL.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecipientView"}}}},"400":{"description":"Neither recipientId nor clientUserId was given. Codes: invalid_json, invalid_request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"No credentials were supplied, or the key is not valid or has been revoked. Codes: missing_credentials, invalid_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is valid but not allowed to do this, or the account is suspended. Codes: insufficient_scope, account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such agreement, or no such recipient on it. Codes: not_found, recipient_not_found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"It cannot be signed now. Codes: not_signable, already_signed, already_declined.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"This Idempotency-Key was already used for a different request body. A new request needs a new key. Code: idempotency_key_reused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests. Retry-After says how long to wait. Code: rate_limited.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on our side. Code: internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/envelopes/{id}/recipients/{recipientId}":{"get":{"tags":["Recipients"],"operationId":"getRecipient","summary":"One recipient of one agreement","security":[{"bearerAuth":["envelopes:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"The agreement's id."},{"name":"recipientId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"The recipient's id, as returned on the agreement."}],"responses":{"200":{"description":"The recipient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Recipient"}}}},"401":{"description":"No credentials were supplied, or the key is not valid or has been revoked. Codes: missing_credentials, invalid_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is valid but not allowed to do this, or the account is suspended. Codes: insufficient_scope, account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such recipient on that agreement. Code: not_found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests. Retry-After says how long to wait. Code: rate_limited.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on our side. Code: internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"tags":["Recipients"],"operationId":"updateRecipient","summary":"Correct a recipient's name or address before they sign","description":"Changing the address retires the old link and issues a new one in the same act: the first link went to whoever holds the wrong address, and leaving it alive would let a stranger sign. Changing only the name leaves the existing link working. Either way the amendment goes on the audit trail. A live key emails the new link; a test key retires the old one and sends nothing.","security":[{"bearerAuth":["envelopes:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"The agreement's id."},{"name":"recipientId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"The recipient's id, as returned on the agreement."},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":255},"description":"A value unique to this attempt, reused unchanged on every retry of it. A retry replays the first result instead of doing the work again. A 4xx is not stored: the request was refused before anything happened, so a retry with the same key runs again. Keys are scoped to your account and kept for 24 hours."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRecipientRequest"},"example":{"email":"ada.lovelace@example.com"}}}},"responses":{"200":{"description":"What changed, and whether the new link was delivered. Read `message`: a correction that could not be delivered leaves the recipient with no working link at all.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRecipientResult"}}}},"400":{"description":"Nothing to change, or the address is not usable. Codes: invalid_json, invalid_request, recipient_email_invalid, recipient_incomplete.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"No credentials were supplied, or the key is not valid or has been revoked. Codes: missing_credentials, invalid_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is valid but not allowed to do this, or the account is suspended. Codes: insufficient_scope, account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such recipient on that agreement. Code: not_found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"There is no point issuing another link: the agreement has moved on, or this person has already signed or declined. Code: not_correctable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"This Idempotency-Key was already used for a different request body. A new request needs a new key. Code: idempotency_key_reused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests. Retry-After says how long to wait. Code: rate_limited.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on our side. Code: internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/envelopes/{id}/recipients/{recipientId}/resend":{"post":{"tags":["Recipients"],"operationId":"resendInvitation","summary":"Send a recipient's invitation again","description":"This mints a new link and retires the old one, including any copy that was forwarded on. Only the digest of a link is stored, so the original cannot be reproduced in any case. Takes no request body.","security":[{"bearerAuth":["envelopes:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"The agreement's id."},{"name":"recipientId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"The recipient's id, as returned on the agreement."},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":255},"description":"A value unique to this attempt, reused unchanged on every retry of it. A retry replays the first result instead of doing the work again. A 4xx is not stored: the request was refused before anything happened, so a retry with the same key runs again. Keys are scoped to your account and kept for 24 hours."}],"responses":{"200":{"description":"The new link was sent, or retired without sending under a test key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResendResult"}}}},"401":{"description":"No credentials were supplied, or the key is not valid or has been revoked. Codes: missing_credentials, invalid_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is valid but not allowed to do this, or the account is suspended. Codes: insufficient_scope, account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such recipient on that agreement. Code: not_found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"There is no point sending another link: the agreement has moved on, or this person has already signed or declined. Code: not_resendable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"This Idempotency-Key was already used for a different request body. A new request needs a new key. Code: idempotency_key_reused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests. Retry-After says how long to wait. Code: rate_limited.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on our side. Code: internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"The email could not be delivered. The earlier link has already been retired, so check the address and try again. Code: delivery_failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/envelopes/{id}/remind":{"post":{"tags":["Envelopes"],"operationId":"remindEnvelope","summary":"Chase everyone still outstanding, now","description":"For when the sender's cadence cannot serve — the deadline moved, the deal closes today. It skips the minimum-gap rule the scheduler applies, but keeps every rule that protects the recipient: never past a closed signing window, never beyond the agreement's own maximum, never someone who has signed or declined. Reminders spend the same budget the scheduler spends, and each one issues a fresh link. Takes no request body.","security":[{"bearerAuth":["envelopes:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"The agreement's id."},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":255},"description":"A value unique to this attempt, reused unchanged on every retry of it. A retry replays the first result instead of doing the work again. A 4xx is not stored: the request was refused before anything happened, so a retry with the same key runs again. Keys are scoped to your account and kept for 24 hours."}],"responses":{"200":{"description":"Who was reminded and who was not. A 200 with `reminded: 0` is normal — read `skipped` for the reason against each recipient.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemindResult"}}}},"401":{"description":"No credentials were supplied, or the key is not valid or has been revoked. Codes: missing_credentials, invalid_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is valid but not allowed to do this, or the account is suspended. Codes: insufficient_scope, account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record for this account. Code: not_found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Nobody can be chased. Codes: not_remindable, window_closed, reminders_disabled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"This Idempotency-Key was already used for a different request body. A new request needs a new key. Code: idempotency_key_reused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests. Retry-After says how long to wait. Code: rate_limited.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on our side. Code: internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/envelopes/{id}/audit":{"get":{"tags":["Envelopes"],"operationId":"getEnvelopeAudit","summary":"The evidence trail behind one agreement","description":"The same facts the certificate of completion carries, in a form a records system can store. The log is append-only by database trigger, so there is nothing here that writes to it.","security":[{"bearerAuth":["envelopes:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"The agreement's id."},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":500,"default":200}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"The trail, newest first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditTrail"}}}},"401":{"description":"No credentials were supplied, or the key is not valid or has been revoked. Codes: missing_credentials, invalid_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is valid but not allowed to do this, or the account is suspended. Codes: insufficient_scope, account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record for this account. Code: not_found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests. Retry-After says how long to wait. Code: rate_limited.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on our side. Code: internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/clients":{"get":{"tags":["Clients"],"operationId":"listClients","summary":"List counterparties, newest first","description":"Trashed clients are excluded, matching what the app shows: they are restorable for thirty days and invisible everywhere else until then.","security":[{"bearerAuth":["clients:read"]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0}},{"name":"search","in":"query","schema":{"type":"string"},"description":"Case-insensitive match on name or email."}],"responses":{"200":{"description":"A page of clients.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientList"}}}},"401":{"description":"No credentials were supplied, or the key is not valid or has been revoked. Codes: missing_credentials, invalid_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is valid but not allowed to do this, or the account is suspended. Codes: insufficient_scope, account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests. Retry-After says how long to wait. Code: rate_limited.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on our side. Code: internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Clients"],"operationId":"createClient","summary":"Create a counterparty","description":"Only the name is required. A counterparty often exists in the records before anyone has their email address.","security":[{"bearerAuth":["clients:write"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateClientRequest"},"example":{"name":"Acme Ltd","contactName":"Ada Lovelace","email":"ada@acme.com"}}}},"responses":{"201":{"description":"The client, as created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Client"}}}},"400":{"description":"Refused. Codes: invalid_json, invalid_request, name_required, email_invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"No credentials were supplied, or the key is not valid or has been revoked. Codes: missing_credentials, invalid_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is valid but not allowed to do this, or the account is suspended. Codes: insufficient_scope, account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A request with this Idempotency-Key is still running, so this one was not started. Retry after the delay, keeping the same key. Code: idempotency_in_progress.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"This Idempotency-Key was already used for a different request body. A new request needs a new key. Code: idempotency_key_reused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests. Retry-After says how long to wait. Code: rate_limited.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on our side. Code: internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":255},"description":"A value unique to this attempt, reused unchanged on every retry of it. A retry replays the first result instead of doing the work again. A 4xx is not stored: the request was refused before anything happened, so a retry with the same key runs again. Keys are scoped to your account and kept for 24 hours."}]}},"/api/v1/clients/{id}":{"get":{"tags":["Clients"],"operationId":"getClient","summary":"One counterparty, with the agreements sent to them","description":"Agreement summaries are included because that is almost always why a client is looked up. Up to a hundred, newest first; the full shape is on the envelopes endpoint.","security":[{"bearerAuth":["clients:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"The client's id."}],"responses":{"200":{"description":"The client and their agreements.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientDetail"}}}},"401":{"description":"No credentials were supplied, or the key is not valid or has been revoked. Codes: missing_credentials, invalid_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is valid but not allowed to do this, or the account is suspended. Codes: insufficient_scope, account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such client, or it has been trashed. Code: not_found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests. Retry-After says how long to wait. Code: rate_limited.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on our side. Code: internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/bulk-sends":{"post":{"tags":["Bulk sends"],"operationId":"createBulkSend","summary":"One template, many agreements, one call","description":"This QUEUES the batch; it does not send it. The response is 202 and the agreements go out as the scheduler works through them, so a caller that treats 202 as \"sent\" will look for paperwork that has not left yet. Poll the returned id for progress.","security":[{"bearerAuth":["envelopes:write"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBulkSendRequest"},"example":{"templateId":"1f7c9c2e-2f6a-4a5e-9b1c-0a1b2c3d4e5f","title":"Annual policy acknowledgement","rows":[{"recipients":[{"name":"Ada Lovelace","email":"ada@acme.com","routingOrder":1}],"prefill":{"Department":"Engineering"}},{"recipients":[{"name":"Alan Turing","email":"alan@acme.com","routingOrder":1}],"title":"Annual policy acknowledgement — Alan Turing"}],"expiresInDays":21}}}},"responses":{"202":{"description":"Accepted and queued. Nothing has been sent yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkSendQueued"}}}},"400":{"description":"Refused. Codes: invalid_json, invalid_request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"No credentials were supplied, or the key is not valid or has been revoked. Codes: missing_credentials, invalid_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The account is behind on payment. Checked once here rather than per row. Code: payment_required.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is valid but not allowed to do this, or the account is suspended. Codes: insufficient_scope, account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such template. Code: template_not_found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A request with this Idempotency-Key is still running, so this one was not started. Retry after the delay, keeping the same key. Code: idempotency_in_progress.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"This Idempotency-Key was already used for a different request body. A new request needs a new key. Code: idempotency_key_reused.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests. Retry-After says how long to wait. Code: rate_limited.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on our side. Code: internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":255},"description":"A value unique to this attempt, reused unchanged on every retry of it. A retry replays the first result instead of doing the work again. A 4xx is not stored: the request was refused before anything happened, so a retry with the same key runs again. Keys are scoped to your account and kept for 24 hours."}]},"get":{"tags":["Bulk sends"],"operationId":"listBulkSends","summary":"Batches this account has queued, newest first","security":[{"bearerAuth":["envelopes:read"]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"A page of batches.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkSendList"}}}},"401":{"description":"No credentials were supplied, or the key is not valid or has been revoked. Codes: missing_credentials, invalid_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is valid but not allowed to do this, or the account is suspended. Codes: insufficient_scope, account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests. Retry-After says how long to wait. Code: rate_limited.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on our side. Code: internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/bulk-sends/{id}":{"get":{"tags":["Bulk sends"],"operationId":"getBulkSend","summary":"A batch's progress, row by row","description":"Per-row status is the point: a batch of five hundred where four addresses bounce has to say which four.","security":[{"bearerAuth":["envelopes:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"The batch's id."},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":500,"default":200}},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0}},{"name":"status","in":"query","schema":{"type":"string","enum":["failed"]},"description":"Pass `failed` to see only the rows that did not go out. Any other value is ignored and every row is returned."}],"responses":{"200":{"description":"The batch and a page of its rows.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkSendDetail"}}}},"401":{"description":"No credentials were supplied, or the key is not valid or has been revoked. Codes: missing_credentials, invalid_key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is valid but not allowed to do this, or the account is suspended. Codes: insufficient_scope, account_suspended.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such batch. Code: not_found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Too many requests. Retry-After says how long to wait. Code: rate_limited.","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Something went wrong on our side. Code: internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"webhooks":{"envelope.sent":{"post":{"summary":"The agreement has gone out to its recipients.","description":"Sent to every endpoint on the account subscribed to this event. Verify the signature over `timestamp + \".\" + rawBody` before parsing. Answer 2xx quickly; anything else counts as a failure and is retried with a widening gap for about a day.","parameters":[{"name":"x-freedocusignature-signature","in":"header","required":true,"schema":{"type":"string"},"description":"Base64 HMAC-SHA256 of `timestamp + \".\" + rawBody`, keyed with the endpoint's signing secret."},{"name":"x-freedocusignature-timestamp","in":"header","required":true,"schema":{"type":"string"},"description":"Unix seconds. Reject anything more than a few minutes old; this is what stops a captured delivery being replayed later."},{"name":"x-freedocusignature-event","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-freedocusignature-delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"},"description":"Stable across retries of the same delivery, so it is what to deduplicate on."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/WebhookEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/EnvelopeSentData"}}}]}}}},"responses":{"200":{"description":"Acknowledged. Any 2xx will do."}}}},"envelope.viewed":{"post":{"summary":"A recipient opened it for the first time. Sent on the status change, not on every fetch.","description":"Sent to every endpoint on the account subscribed to this event. Verify the signature over `timestamp + \".\" + rawBody` before parsing. Answer 2xx quickly; anything else counts as a failure and is retried with a widening gap for about a day.","parameters":[{"name":"x-freedocusignature-signature","in":"header","required":true,"schema":{"type":"string"},"description":"Base64 HMAC-SHA256 of `timestamp + \".\" + rawBody`, keyed with the endpoint's signing secret."},{"name":"x-freedocusignature-timestamp","in":"header","required":true,"schema":{"type":"string"},"description":"Unix seconds. Reject anything more than a few minutes old; this is what stops a captured delivery being replayed later."},{"name":"x-freedocusignature-event","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-freedocusignature-delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"},"description":"Stable across retries of the same delivery, so it is what to deduplicate on."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/WebhookEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/SignerEventData"}}}]}}}},"responses":{"200":{"description":"Acknowledged. Any 2xx will do."}}}},"envelope.signer_signed":{"post":{"summary":"One party signed. `allPartiesSigned` says whether that was the last one.","description":"Sent to every endpoint on the account subscribed to this event. Verify the signature over `timestamp + \".\" + rawBody` before parsing. Answer 2xx quickly; anything else counts as a failure and is retried with a widening gap for about a day.","parameters":[{"name":"x-freedocusignature-signature","in":"header","required":true,"schema":{"type":"string"},"description":"Base64 HMAC-SHA256 of `timestamp + \".\" + rawBody`, keyed with the endpoint's signing secret."},{"name":"x-freedocusignature-timestamp","in":"header","required":true,"schema":{"type":"string"},"description":"Unix seconds. Reject anything more than a few minutes old; this is what stops a captured delivery being replayed later."},{"name":"x-freedocusignature-event","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-freedocusignature-delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"},"description":"Stable across retries of the same delivery, so it is what to deduplicate on."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/WebhookEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/SignerSignedData"}}}]}}}},"responses":{"200":{"description":"Acknowledged. Any 2xx will do."}}}},"envelope.signer_declined":{"post":{"summary":"A party declined, with their reason. One decline closes the agreement for everyone.","description":"Sent to every endpoint on the account subscribed to this event. Verify the signature over `timestamp + \".\" + rawBody` before parsing. Answer 2xx quickly; anything else counts as a failure and is retried with a widening gap for about a day.","parameters":[{"name":"x-freedocusignature-signature","in":"header","required":true,"schema":{"type":"string"},"description":"Base64 HMAC-SHA256 of `timestamp + \".\" + rawBody`, keyed with the endpoint's signing secret."},{"name":"x-freedocusignature-timestamp","in":"header","required":true,"schema":{"type":"string"},"description":"Unix seconds. Reject anything more than a few minutes old; this is what stops a captured delivery being replayed later."},{"name":"x-freedocusignature-event","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-freedocusignature-delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"},"description":"Stable across retries of the same delivery, so it is what to deduplicate on."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/WebhookEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/SignerDeclinedData"}}}]}}}},"responses":{"200":{"description":"Acknowledged. Any 2xx will do."}}}},"envelope.completed":{"post":{"summary":"Everyone has signed and the executed copy exists.","description":"Sent to every endpoint on the account subscribed to this event. Verify the signature over `timestamp + \".\" + rawBody` before parsing. Answer 2xx quickly; anything else counts as a failure and is retried with a widening gap for about a day.","parameters":[{"name":"x-freedocusignature-signature","in":"header","required":true,"schema":{"type":"string"},"description":"Base64 HMAC-SHA256 of `timestamp + \".\" + rawBody`, keyed with the endpoint's signing secret."},{"name":"x-freedocusignature-timestamp","in":"header","required":true,"schema":{"type":"string"},"description":"Unix seconds. Reject anything more than a few minutes old; this is what stops a captured delivery being replayed later."},{"name":"x-freedocusignature-event","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-freedocusignature-delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"},"description":"Stable across retries of the same delivery, so it is what to deduplicate on."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/WebhookEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/EnvelopeCompletedData"}}}]}}}},"responses":{"200":{"description":"Acknowledged. Any 2xx will do."}}}},"envelope.voided":{"post":{"summary":"The sender withdrew it.","description":"Sent to every endpoint on the account subscribed to this event. Verify the signature over `timestamp + \".\" + rawBody` before parsing. Answer 2xx quickly; anything else counts as a failure and is retried with a widening gap for about a day.","parameters":[{"name":"x-freedocusignature-signature","in":"header","required":true,"schema":{"type":"string"},"description":"Base64 HMAC-SHA256 of `timestamp + \".\" + rawBody`, keyed with the endpoint's signing secret."},{"name":"x-freedocusignature-timestamp","in":"header","required":true,"schema":{"type":"string"},"description":"Unix seconds. Reject anything more than a few minutes old; this is what stops a captured delivery being replayed later."},{"name":"x-freedocusignature-event","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-freedocusignature-delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"},"description":"Stable across retries of the same delivery, so it is what to deduplicate on."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/WebhookEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/EnvelopeVoidedData"}}}]}}}},"responses":{"200":{"description":"Acknowledged. Any 2xx will do."}}}},"envelope.expired":{"post":{"summary":"The signing window closed with the agreement unsigned.","description":"Sent to every endpoint on the account subscribed to this event. Verify the signature over `timestamp + \".\" + rawBody` before parsing. Answer 2xx quickly; anything else counts as a failure and is retried with a widening gap for about a day.","parameters":[{"name":"x-freedocusignature-signature","in":"header","required":true,"schema":{"type":"string"},"description":"Base64 HMAC-SHA256 of `timestamp + \".\" + rawBody`, keyed with the endpoint's signing secret."},{"name":"x-freedocusignature-timestamp","in":"header","required":true,"schema":{"type":"string"},"description":"Unix seconds. Reject anything more than a few minutes old; this is what stops a captured delivery being replayed later."},{"name":"x-freedocusignature-event","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-freedocusignature-delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"},"description":"Stable across retries of the same delivery, so it is what to deduplicate on."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/WebhookEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/EnvelopeExpiredData"}}}]}}}},"responses":{"200":{"description":"Acknowledged. Any 2xx will do."}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Your API key, created in Settings then Developer. A live key begins `fds_live_`; a test key begins `fds_test_` and behaves identically except that no invitation is emailed and what it creates is excluded from anything that counts or charges. Each key carries scopes — `envelopes:read`, `envelopes:write`, `templates:read`, `templates:write`, `clients:read`, `clients:write` — so a reporting job need not hold one that can send in your name."}},"schemas":{"Folder":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"parentId":{"type":["string","null"],"format":"uuid","description":"Null at the top level of its view."},"section":{"type":"string","enum":["files","templates","drafts","awaiting","executed","closed"],"description":"Which standing view's tree this folder belongs to. It never changes."},"depth":{"type":"integer","description":"How deep in its tree, so a flat list can be indented without nesting."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"Error":{"type":"object","required":["error"],"description":"One shape for every failure. Branch on `code`, which is stable; `message` is for a human reading a log and may be reworded.","properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","example":"insufficient_scope"},"message":{"type":"string"},"scope":{"type":"string","example":"folders:write","description":"Present on 403 insufficient_scope: the exact permission the key is missing. Lets a caller tell a filing problem from a credential that has stopped working, without parsing the message."}}}}},"EnvelopeStatus":{"type":"string","enum":["draft","sent","viewed","completed","declined","voided","expired"]},"RecipientStatus":{"type":"string","enum":["pending","viewed","signed","declined"]},"FieldType":{"type":"string","enum":["signature","initials","text","date","name","email","checkbox"]},"Recipient":{"type":"object","required":["id","name","email","routingOrder","status"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"email":{"type":"string"},"routingOrder":{"type":"integer","minimum":1,"description":"One-based, the same number you send when creating the agreement. When the agreement is sequential it is also the order people sign in."},"status":{"$ref":"#/components/schemas/RecipientStatus"},"clientUserId":{"type":["string","null"],"description":"Set when this recipient signs inside your own application."},"invitedAt":{"type":["string","null"],"format":"date-time"},"viewedAt":{"type":["string","null"],"format":"date-time"},"signedAt":{"type":["string","null"],"format":"date-time"},"declinedAt":{"type":["string","null"],"format":"date-time"},"declineReason":{"type":["string","null"]}}},"Envelope":{"type":"object","required":["id","status","title","testMode","recipients","executedDocument"],"properties":{"id":{"type":"string","format":"uuid"},"status":{"$ref":"#/components/schemas/EnvelopeStatus"},"title":{"type":"string"},"message":{"type":["string","null"]},"templateId":{"type":["string","null"],"format":"uuid","description":"Null when the agreement was created from documents posted directly."},"clientId":{"type":["string","null"],"format":"uuid","description":"Which client on record this is filed under, if any."},"testMode":{"type":"boolean","description":"Made by a test key: nobody was emailed and it counts towards nothing. Check this before treating an agreement as one a counterparty is waiting on."},"sequential":{"type":"boolean","description":"When true, recipients must sign in routing order."},"createdAt":{"type":["string","null"],"format":"date-time"},"sentAt":{"type":["string","null"],"format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"},"expiresAt":{"type":["string","null"],"format":"date-time"},"voidedReason":{"type":["string","null"]},"reminderEveryDays":{"type":["integer","null"],"description":"Null means reminders are off for this agreement."},"executedDocument":{"type":"object","required":["available","sha256"],"properties":{"available":{"type":"boolean","description":"True once the executed copy exists and can be fetched from the document endpoint."},"sha256":{"type":["string","null"]}}},"recipients":{"type":"array","items":{"$ref":"#/components/schemas/Recipient"}}}},"EnvelopeList":{"type":"object","required":["envelopes","limit","offset"],"properties":{"envelopes":{"type":"array","items":{"$ref":"#/components/schemas/Envelope"}},"limit":{"type":"integer"},"offset":{"type":"integer"}}},"TabPlacement":{"type":"object","required":["type"],"description":"Where one field goes. Give either `anchorString` or a `page` with `x` and `y`. Anchors are preferred: coordinates stop being right the moment a clause is added, while an anchor moves with the words it was measured from. Offsets and sizes are in points, and y grows downward. The same resolver places fields on the send path and on a template, so an anchor behaves identically in both.","properties":{"type":{"$ref":"#/components/schemas/FieldType"},"label":{"type":["string","null"],"maxLength":120},"required":{"type":"boolean","default":true},"anchorString":{"type":"string","minLength":1,"maxLength":200},"anchorXOffset":{"type":"number","minimum":-2000,"maximum":2000},"anchorYOffset":{"type":"number","minimum":-2000,"maximum":2000},"ignoreCase":{"type":"boolean"},"matchWholeWord":{"type":"boolean"},"occurrence":{"type":"string","enum":["first","all"],"default":"first","description":"`all` places one field at every match, which is how initials land on every page from a single instruction."},"documentIndex":{"type":"integer","minimum":0,"maximum":9,"default":0,"description":"Which document in `documents` this coordinate placement refers to, counting from zero. Out of range is refused with document_not_found. Anchored tabs ignore this and search every document."},"page":{"type":"integer","minimum":1,"maximum":500,"description":"One-based, within the chosen document."},"x":{"type":"number","minimum":0,"maximum":5000,"description":"Points from the left."},"y":{"type":"number","minimum":0,"maximum":5000,"description":"Points from the top."},"width":{"type":"number","minimum":4,"maximum":2000},"height":{"type":"number","minimum":4,"maximum":2000}}},"Tab":{"description":"A field on an agreement being sent.","allOf":[{"$ref":"#/components/schemas/TabPlacement"},{"type":"object","properties":{"value":{"type":["string","null"],"maxLength":4000,"description":"A starting value the signer can change. Never accepted for a signature."}}}]},"TemplateTab":{"description":"A field on a template. Identical to a send-path tab except for the default: a template carries `defaultValue`, which becomes the starting value on every agreement made from it, where the send path's `value` applies to one agreement only.","allOf":[{"$ref":"#/components/schemas/TabPlacement"},{"type":"object","properties":{"defaultValue":{"type":["string","null"],"maxLength":4000,"description":"A default the signer may change. Never accepted for a signature."}}}]},"CreateEnvelopeRecipient":{"type":"object","required":["name","email","routingOrder"],"properties":{"name":{"type":"string","minLength":1,"maxLength":120},"email":{"type":"string","minLength":3,"maxLength":200},"routingOrder":{"type":"integer","minimum":1,"maximum":50,"description":"One-based, and the exact number the templates endpoint hands back. When the agreement is sequential it is also the order people sign in."},"clientUserId":{"type":"string","minLength":1,"maxLength":200,"description":"Present means this person signs inside your own application: no invitation is emailed, and you ask for a signing URL instead."},"tabs":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/Tab"},"description":"Required when sending `documents`. Ignored when sending a `templateId`, which already carries its field layout."}}},"CreateEnvelopeDocument":{"type":"object","required":["name","base64"],"properties":{"name":{"type":"string","minLength":1,"maxLength":200},"base64":{"type":"string","minLength":8,"description":"The PDF, base64 encoded. A `data:` prefix is tolerated. Capped at 4 MB per document, because base64 inflates a file by a third and the request has to fit in one body."}}},"CreateEnvelopeRequest":{"type":"object","required":["title","recipients"],"description":"Provide exactly one of `templateId` and `documents`.","properties":{"templateId":{"type":"string","format":"uuid"},"documents":{"type":"array","minItems":1,"maxItems":10,"items":{"$ref":"#/components/schemas/CreateEnvelopeDocument"}},"title":{"type":"string","minLength":1,"maxLength":200,"description":"What the recipient sees they are being asked to sign."},"message":{"type":"string","maxLength":2000},"status":{"type":"string","enum":["sent","draft"],"default":"sent","description":"`draft` prepares the agreement and emails nobody."},"recipients":{"type":"array","minItems":1,"maxItems":25,"items":{"$ref":"#/components/schemas/CreateEnvelopeRecipient"}},"clientId":{"type":"string","format":"uuid","description":"File the agreement under a client on record. An id belonging to another account is refused with client_not_found."},"prefill":{"type":"object","additionalProperties":{"type":"string","maxLength":4000},"description":"Starting values for text-like fields, keyed by the field's label in the template. Only text, date, name and email fields can be prefilled."},"reminderEveryDays":{"type":["integer","null"],"minimum":2,"maximum":30,"description":"Null turns reminders off. Two days is the floor."},"expiresInDays":{"type":["integer","null"],"minimum":1,"maximum":365}}},"CreateViewRequest":{"type":"object","description":"Provide either `recipientId` or `clientUserId`.","properties":{"recipientId":{"type":"string","format":"uuid"},"clientUserId":{"type":"string","minLength":1,"maxLength":200},"returnUrl":{"type":"string","format":"uri","maxLength":2000,"description":"Where to send the browser once signing finishes."},"expiresInMinutes":{"type":"integer","minimum":1,"maximum":60,"default":15,"description":"How long the URL stays usable."}}},"RecipientView":{"type":"object","required":["url","recipientId","expiresAt"],"properties":{"url":{"type":"string","format":"uri"},"recipientId":{"type":"string","format":"uuid"},"expiresAt":{"type":"string","format":"date-time"}}},"TemplateSummary":{"type":"object","required":["id","name","roles","documents","pages","sendable"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"roles":{"type":"array","items":{"type":"object","required":["routingOrder"],"properties":{"routingOrder":{"type":"integer","minimum":1}}}},"documents":{"type":"integer"},"pages":{"type":"integer"},"sendable":{"type":"boolean","description":"False means it cannot be sent yet, because nothing marks where it needs signing."},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"}}},"TemplateList":{"type":"object","required":["templates","limit","offset"],"properties":{"templates":{"type":"array","items":{"$ref":"#/components/schemas/TemplateSummary"}},"limit":{"type":"integer"},"offset":{"type":"integer"}}},"TemplateDetail":{"type":"object","required":["id","name","sendable","documents","roles"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"sendable":{"type":"boolean"},"documents":{"type":"array","items":{"type":"object","required":["id","filename","pageCount","position"],"properties":{"id":{"type":"string","format":"uuid"},"filename":{"type":"string"},"pageCount":{"type":"integer"},"position":{"type":"integer"}}}},"roles":{"type":"array","items":{"type":"object","required":["routingOrder","fields"],"properties":{"routingOrder":{"type":"integer","minimum":1},"fields":{"type":"array","items":{"type":"object","required":["type","required","page","prefillable"],"properties":{"type":{"$ref":"#/components/schemas/FieldType"},"label":{"type":["string","null"]},"required":{"type":"boolean"},"page":{"type":"integer","minimum":1,"description":"One-based."},"prefillable":{"type":"boolean","description":"Whether this field's label can be used as a `prefill` key. A signature never can."}}}}}}},"createdAt":{"type":["string","null"],"format":"date-time"},"updatedAt":{"type":["string","null"],"format":"date-time"}}},"UpdateRecipientRequest":{"type":"object","description":"Give a name, an email address, or both. An empty body is refused.","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"email":{"type":"string","minLength":3,"maxLength":200}}},"UpdateRecipientResult":{"type":"object","required":["recipientId","name","email","previousLinkRetired","delivered","message"],"properties":{"recipientId":{"type":"string","format":"uuid"},"name":{"type":"string"},"email":{"type":"string"},"previousLinkRetired":{"type":"boolean","description":"True when the address changed. The old link stops working at that moment, whether or not the new one was delivered."},"delivered":{"type":"boolean"},"testMode":{"type":"boolean"},"message":{"type":"string","description":"Plain English for a human reading a log. Worth surfacing on failure."}}},"ResendResult":{"type":"object","required":["recipientId","email","delivered","message"],"properties":{"recipientId":{"type":"string","format":"uuid"},"email":{"type":"string"},"delivered":{"type":"boolean"},"testMode":{"type":"boolean","description":"Present and true only when a test key was used."},"message":{"type":"string"}}},"CreateTemplateRequest":{"type":"object","required":["name","documents","roles"],"properties":{"name":{"type":"string","minLength":1,"maxLength":200},"description":{"type":"string","maxLength":2000},"documents":{"type":"array","minItems":1,"maxItems":10,"items":{"$ref":"#/components/schemas/CreateEnvelopeDocument"}},"roles":{"type":"array","minItems":1,"maxItems":25,"description":"One entry per role, in signing order. Positional: the first entry is routingOrder 1.","items":{"type":"object","required":["tabs"],"properties":{"tabs":{"type":"array","minItems":1,"maxItems":100,"items":{"$ref":"#/components/schemas/TemplateTab"}}}}}}},"CreateTemplateResult":{"type":"object","required":["id","name","documents","roles","fields","sendable"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"documents":{"type":"integer","description":"How many documents were stored."},"roles":{"type":"array","description":"The routingOrder to send back for each role.","items":{"type":"object","required":["routingOrder"],"properties":{"routingOrder":{"type":"integer","minimum":1}}}},"fields":{"type":"integer","description":"How many fields were placed. A tab with `occurrence: \"all\"` contributes one per match, so this can exceed the number of tabs sent."},"sendable":{"type":"boolean","description":"Always true on a successful create: a template that could not be placed is refused rather than returned unsendable."}}},"UpdateEnvelopeRequest":{"type":"object","required":["reminderEveryDays"],"properties":{"reminderEveryDays":{"type":["integer","null"],"minimum":2,"maximum":30,"description":"Days between reminders, or null to stop chasing. Two days is the floor: a nudge a day is not a nudge, and the person being chased did not choose to be in this inbox."}}},"RemindResult":{"type":"object","required":["envelopeId","reminded","recipients","skipped","testMode"],"properties":{"envelopeId":{"type":"string","format":"uuid"},"reminded":{"type":"integer","description":"How many emails actually went out."},"recipients":{"type":"array","items":{"type":"string"},"description":"The addresses that were reminded."},"skipped":{"type":"array","description":"Everyone who was not reminded, and why. A recipient who was never invited, has hit the agreement's reminder limit, or whose email bounced appears here.","items":{"type":"object","required":["recipientId","email","reason"],"properties":{"recipientId":{"type":"string","format":"uuid"},"email":{"type":"string"},"reason":{"type":"string"}}}},"testMode":{"type":"boolean"}}},"AuditEvent":{"type":"object","required":["id","event"],"properties":{"id":{"type":"string","format":"uuid"},"event":{"type":"string","description":"What happened, e.g. envelope_sent, invitation_delivered, signer_viewed, signer_signed, document_downloaded. Free text, so treat an unfamiliar value as informational rather than an error."},"occurredAt":{"type":["string","null"],"format":"date-time","description":"The server's clock, never the client's."},"ipAddress":{"type":["string","null"]},"userAgent":{"type":["string","null"]},"device":{"type":["object","null"],"additionalProperties":true},"clientTimezone":{"type":["string","null"],"description":"Self-reported by the browser; recorded as a claim, not a fact."},"clientLocale":{"type":["string","null"]},"recipient":{"type":["object","null"],"description":"The party this event concerns. Name and email are null if the signer row has since gone.","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":["string","null"]},"email":{"type":["string","null"]}}},"documentSha256":{"type":["string","null"]},"meta":{"type":["object","null"],"additionalProperties":true}}},"AuditTrail":{"type":"object","required":["envelopeId","events","limit","offset"],"properties":{"envelopeId":{"type":"string","format":"uuid"},"events":{"type":"array","items":{"$ref":"#/components/schemas/AuditEvent"}},"limit":{"type":"integer"},"offset":{"type":"integer"}}},"Client":{"type":"object","required":["id","name"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"contactName":{"type":["string","null"]},"email":{"type":["string","null"]},"phone":{"type":["string","null"]},"address":{"type":["string","null"]},"createdAt":{"type":["string","null"],"format":"date-time"}}},"ClientList":{"type":"object","required":["clients","limit","offset"],"properties":{"clients":{"type":"array","items":{"$ref":"#/components/schemas/Client"}},"limit":{"type":"integer"},"offset":{"type":"integer"}}},"ClientDetail":{"allOf":[{"$ref":"#/components/schemas/Client"},{"type":"object","required":["agreements"],"properties":{"agreements":{"type":"array","description":"Up to a hundred, newest first.","items":{"type":"object","required":["id","title","status"],"properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"status":{"$ref":"#/components/schemas/EnvelopeStatus"},"sentAt":{"type":["string","null"],"format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"}}}}}}]},"CreateClientRequest":{"type":"object","required":["name"],"properties":{"name":{"type":"string","minLength":1,"maxLength":200},"contactName":{"type":["string","null"],"maxLength":200},"email":{"type":["string","null"],"maxLength":200},"phone":{"type":["string","null"],"maxLength":80},"address":{"type":["string","null"],"maxLength":1000}}},"BulkSendStatus":{"type":"string","enum":["queued","processing","done","partial"],"description":"`partial` means the batch finished but not every row got out."},"BulkSendRowInput":{"type":"object","required":["recipients"],"properties":{"recipients":{"type":"array","minItems":1,"maxItems":25,"items":{"type":"object","required":["name","email","routingOrder"],"properties":{"name":{"type":"string","minLength":1,"maxLength":120},"email":{"type":"string","minLength":3,"maxLength":200},"routingOrder":{"type":"integer","minimum":1,"maximum":50}}}},"prefill":{"type":"object","additionalProperties":{"type":"string","maxLength":4000}},"title":{"type":"string","minLength":1,"maxLength":200,"description":"Overrides the batch title for this one agreement."}}},"CreateBulkSendRequest":{"type":"object","required":["templateId","title","rows"],"properties":{"templateId":{"type":"string","format":"uuid"},"title":{"type":"string","minLength":1,"maxLength":200},"message":{"type":"string","maxLength":2000},"rows":{"type":"array","minItems":1,"maxItems":1000,"items":{"$ref":"#/components/schemas/BulkSendRowInput"}},"reminderEveryDays":{"type":["integer","null"],"minimum":2,"maximum":30},"expiresInDays":{"type":["integer","null"],"minimum":1,"maximum":365}}},"BulkSendQueued":{"type":"object","required":["id","status","queued","note"],"properties":{"id":{"type":"string","format":"uuid","description":"Poll this for progress."},"status":{"type":"string","enum":["queued"]},"queued":{"type":"integer","description":"How many rows were accepted."},"note":{"type":"string"}}},"BulkSendSummary":{"type":"object","required":["id","templateId","title","status","total","sent","failed","testMode"],"properties":{"id":{"type":"string","format":"uuid"},"templateId":{"type":"string","format":"uuid"},"title":{"type":"string"},"status":{"$ref":"#/components/schemas/BulkSendStatus"},"total":{"type":"integer"},"sent":{"type":"integer"},"failed":{"type":"integer"},"testMode":{"type":"boolean"},"createdAt":{"type":["string","null"],"format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"}}},"BulkSendList":{"type":"object","required":["bulkSends","limit","offset"],"properties":{"bulkSends":{"type":"array","items":{"$ref":"#/components/schemas/BulkSendSummary"}},"limit":{"type":"integer"},"offset":{"type":"integer"}}},"BulkSendRowResult":{"type":"object","required":["position","status","recipients"],"properties":{"position":{"type":"integer","description":"The row's place in the batch, from zero."},"status":{"type":"string","enum":["pending","sent","failed"],"description":"`pending` means the scheduler has not reached this row yet."},"envelopeId":{"type":["string","null"],"format":"uuid","description":"Set once the agreement exists."},"error":{"type":["string","null"]},"recipients":{"type":"array","items":{"type":"string"},"description":"Addresses only. Prefill values are not echoed back, since they carry whatever was in the spreadsheet."},"completedAt":{"type":["string","null"],"format":"date-time"}}},"BulkSendDetail":{"allOf":[{"$ref":"#/components/schemas/BulkSendSummary"},{"type":"object","required":["pending","rows","limit","offset"],"properties":{"pending":{"type":"integer","description":"total minus sent minus failed."},"rows":{"type":"array","items":{"$ref":"#/components/schemas/BulkSendRowResult"}},"limit":{"type":"integer"},"offset":{"type":"integer"}}}]},"WebhookEnvelope":{"type":"object","required":["event","occurredAt","accountId","data"],"description":"Every delivery has this shape. `occurredAt` is stamped when the thing happened, not when the delivery was attempted, so a retry hours later still reports the truth.","properties":{"event":{"type":"string","enum":["envelope.sent","envelope.viewed","envelope.signer_signed","envelope.signer_declined","envelope.completed","envelope.voided","envelope.expired"]},"occurredAt":{"type":"string","format":"date-time"},"accountId":{"type":"string","format":"uuid"},"data":{"type":"object"}}},"EnvelopeSentData":{"type":"object","properties":{"envelopeId":{"type":"string","format":"uuid"},"title":{"type":"string"},"templateId":{"type":["string","null"],"format":"uuid"},"sentAt":{"type":"string","format":"date-time"},"expiresAt":{"type":["string","null"],"format":"date-time"},"signers":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"email":{"type":"string"},"routingOrder":{"type":"integer","description":"One-based in this payload."},"clientUserId":{"type":["string","null"]}}}}}},"SignerEventData":{"type":"object","properties":{"envelopeId":{"type":"string","format":"uuid"},"title":{"type":"string"},"signerId":{"type":"string","format":"uuid"},"signerName":{"type":"string"},"signerEmail":{"type":"string"},"viewedAt":{"type":"string","format":"date-time"}}},"SignerSignedData":{"type":"object","properties":{"envelopeId":{"type":"string","format":"uuid"},"title":{"type":"string"},"signerId":{"type":"string","format":"uuid"},"signerName":{"type":"string"},"signerEmail":{"type":"string"},"signedAt":{"type":"string","format":"date-time"},"allPartiesSigned":{"type":"boolean","description":"True when this signature was the last one outstanding."}}},"SignerDeclinedData":{"type":"object","properties":{"envelopeId":{"type":"string","format":"uuid"},"title":{"type":"string"},"signerId":{"type":"string","format":"uuid"},"signerName":{"type":"string"},"signerEmail":{"type":"string"},"reason":{"type":"string"},"declinedAt":{"type":"string","format":"date-time"}}},"EnvelopeCompletedData":{"type":"object","properties":{"envelopeId":{"type":"string","format":"uuid"},"title":{"type":"string"},"completedAt":{"type":"string","format":"date-time"},"signers":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"email":{"type":"string"},"status":{"$ref":"#/components/schemas/RecipientStatus"}}}}}},"EnvelopeVoidedData":{"type":"object","properties":{"envelopeId":{"type":"string","format":"uuid"},"title":{"type":"string"},"reason":{"type":"string"},"voidedAt":{"type":"string","format":"date-time"}}},"EnvelopeExpiredData":{"type":"object","properties":{"envelopeId":{"type":"string","format":"uuid"},"title":{"type":"string"},"expiredAt":{"type":"string","format":"date-time"}}}}}}