diff --git a/docs/API/create-image-variable-folder.api.mdx b/docs/API/create-image-variable-folder.api.mdx
index 1d5c767..986c100 100644
--- a/docs/API/create-image-variable-folder.api.mdx
+++ b/docs/API/create-image-variable-folder.api.mdx
@@ -1,7 +1,7 @@
---
id: create-image-variable-folder
title: "Create Image Variable (Folder)"
-description: "Create Image Variable (Folder)"
+description: "Create a reusable image, text, or HTML variable in a template folder or your knowledge base. Includes example request, response, and error handling."
sidebar_label: "Create Image Variable (Folder)"
hide_title: true
hide_table_of_contents: true
@@ -16,9 +16,73 @@ custom_edit_url: null
# Create Image Variable (Folder)
-
- Create Image Variable (Folder)
-
+
+This endpoint creates a reusable variable scoped to a template folder or to your organization's global knowledge base, independent of any single template. Despite the name, it is not limited to images: `mimeType` also accepts `text` and `html`, and the same endpoint is used for [Read Variables (Folder)](/docs/API/read-variables-folder) to later list.
+
+## When to use it
+
+Use this endpoint to build a shared library of content, such as a company logo, a standard address block, or boilerplate legal language, that multiple templates can reference by placeholder without duplicating the content in each one.
+
+## Example request
+
+```bash
+curl -X POST "https://api.turbodocx.com/Variable" \
+ -H "Authorization: Bearer $TURBODOCX_API_KEY" \
+ -H "x-rapiddocx-org-id: $TURBODOCX_ORG_ID" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "name": "Company Logo",
+ "placeholder": "{CompanyLogo}",
+ "mimeType": "image",
+ "text": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB...",
+ "templateFolderId": "9d2b1c63-0f77-4a9c-b1d0-2c5e6f7a8b90",
+ "allowRichTextInjection": true
+ }'
+```
+
+Optionally send `templateFolderId` (scopes the variable to that folder) or `isGlobal: true` (adds it to your org-wide knowledge base); at most one may be set, and sending both is rejected. `text` must be a base64 `data:` URI when `mimeType` is `"image"`, or plain text/HTML otherwise. `placeholder` must be unique within its folder or knowledge base and, if set, must be wrapped in curly braces, for example `{CompanyLogo}`.
+
+## Example response
+
+On success the endpoint returns the created variable:
+
+```json
+{
+ "data": {
+ "results": {
+ "variable": {
+ "id": "e4f5a6b7-8c9d-4e0f-a1b2-3c4d5e6f7a8b",
+ "name": "Company Logo",
+ "placeholder": "{CompanyLogo}",
+ "mimeType": "image",
+ "isGlobal": false,
+ "templateFolderId": "9d2b1c63-0f77-4a9c-b1d0-2c5e6f7a8b90",
+ "allowRichTextInjection": true,
+ "orgId": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
+ "createdBy": "f5e6d7c8-9a0b-4c1d-2e3f-4a5b6c7d8e9f",
+ "createdOn": "2026-05-01T14:22:10.000Z"
+ }
+ }
+ }
+}
+```
+
+## Common errors
+
+| Status | When | Response body |
+| ------ | ---- | ------------- |
+| 401 | Missing or invalid API key/token, or the organization cannot be resolved | Empty (status only) |
+| 403 | The key's role is not administrator, contributor, or user | Empty (status only) |
+| 403 | `isGlobal: true` and the key's role is `user` (creating a knowledge-base variable requires administrator or contributor) | Empty (status only) |
+| 400 | `mimeType` or `text` is missing, or both `isGlobal` and `templateFolderId` are set | `{ "message", "type": "ValidationError", "data": { "errors": [...] } }` |
+| 400 | `placeholder` is not wrapped in `{ }`, or already exists in that folder or knowledge base | `{ "message", "type": "TemplateError", "data": [{ "message", "type", "data": { "explanation", "context" } }] }` |
+
+## Related endpoints
+
+- [Read Variables (Folder)](/docs/API/read-variables-folder) to list variables you have created
+- [Update Variable by ID](/docs/API/update-variable-by-id) to edit a variable after creating it
+- [Delete Variables (by IDs)](/docs/API/delete-variables-by-i-ds) to remove variables in bulk
+
diff --git a/docs/API/create-tag.api.mdx b/docs/API/create-tag.api.mdx
index 5bc01bc..0a7c590 100644
--- a/docs/API/create-tag.api.mdx
+++ b/docs/API/create-tag.api.mdx
@@ -1,7 +1,7 @@
---
id: create-tag
title: "Create Tag"
-description: "Create Tag"
+description: "Create a reusable tag in your organization to attach to templates and variables. Includes example request, response, and error handling."
sidebar_label: "Create Tag"
hide_title: true
hide_table_of_contents: true
@@ -16,9 +16,55 @@ custom_edit_url: null
# Create Tag
-
- Create Tag
-
+
+The Create Tag endpoint adds a new tag to your organization. Tags are a flat, organization-wide label set; once created, a tag can be attached to templates (with [Edit Template Metadata](/docs/API/edit-template-metadata)) or variables to make them easier to filter and organize.
+
+## When to use it
+
+Use this endpoint to build a tag picker that lets users create new tags on the fly, or to seed a starting set of tags when provisioning an organization.
+
+## Example request
+
+```bash
+curl -X POST "https://api.turbodocx.com/Tag" \
+ -H "Authorization: Bearer $TURBODOCX_API_KEY" \
+ -H "x-rapiddocx-org-id: $TURBODOCX_ORG_ID" \
+ -H "Content-Type: application/json" \
+ -d '{"label": "legal"}'
+```
+
+## Example response
+
+```json
+{
+ "data": {
+ "results": {
+ "id": "7c1a0b52-9e88-4f0d-b3a2-1d4c6f8e2a90",
+ "label": "legal",
+ "isActive": true,
+ "orgId": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
+ "createdBy": "f5e6d7c8-9a0b-4c1d-2e3f-4a5b6c7d8e9f",
+ "createdOn": "2026-05-01T14:22:10.000Z",
+ "updatedOn": "2026-05-01T14:22:10.000Z"
+ }
+ }
+}
+```
+
+## Common errors
+
+| Status | When | Response body |
+| ------ | ---- | ------------- |
+| 401 | Missing or invalid API key/token, or the organization cannot be resolved | Empty (status only) |
+| 403 | The key's role is not administrator, contributor, or user | Empty (status only) |
+| 400 | `label` is missing or not between 1 and 255 characters | `{ "message", "type": "ValidationError", "data": { "errors": [...] } }` |
+
+## Related endpoints
+
+- [Read Tag](/docs/API/read-tag) to list existing tags before creating a duplicate
+- [Update Tag](/docs/API/update-tag) to rename a tag
+- [Delete Tags (by IDs)](/docs/API/delete-tags-by-i-ds) to remove tags you no longer need
+
diff --git a/docs/API/create-webhook.api.mdx b/docs/API/create-webhook.api.mdx
index 0dcec8f..7091f14 100644
--- a/docs/API/create-webhook.api.mdx
+++ b/docs/API/create-webhook.api.mdx
@@ -1,7 +1,7 @@
---
id: create-webhook
title: "Create Webhook"
-description: "Register a new signature webhook for the org. The `name` field is hardcoded to `signature` by the SDK. The returned `secret` is shown **once** — store it on receipt. It cannot be retrieved later; use Regenerate Webhook Secret if lost."
+description: "Register a new signature webhook for your org. The SDK always sends name=\"signature\". The returned secret is shown once; store it immediately."
sidebar_label: "Create Webhook"
hide_title: true
hide_table_of_contents: true
@@ -16,9 +16,69 @@ custom_edit_url: null
# Create Webhook
-
- Create Webhook
-
+
+The Create Webhook endpoint registers a webhook that TurboDocx calls when TurboSign events happen in your organization, such as a document being signed or completed. Each webhook needs a unique `name` among your org's active webhooks; every TurboDocx SDK sends `"signature"`. A second create call with that name conflicts (409) only while an active webhook already has it; if you paused a webhook via [Update Webhook](/docs/API/update-webhook)'s `isActive: false` instead of deleting it, creating a new one with the same name succeeds and leaves two rows sharing that name, and by-name lookups on the other endpoints may then hit either one. Delete the old webhook (see [Delete Webhook](/docs/API/delete-webhook)) before reusing its name, rather than just pausing it.
+
+## When to use it
+
+Use this endpoint once, during integration setup, to start receiving signature lifecycle events instead of polling the API. To change the URLs or subscribed events later, use [Update Webhook](/docs/API/update-webhook) rather than creating a new one.
+
+## Example request
+
+```bash
+curl -X POST "https://api.turbodocx.com/api/webhooks" \
+ -H "Authorization: Bearer $TURBODOCX_API_KEY" \
+ -H "x-rapiddocx-org-id: $TURBODOCX_ORG_ID" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "name": "signature",
+ "urls": ["https://example.com/webhooks/turbodocx"],
+ "events": ["signature.document.completed", "signature.document.voided"]
+ }'
+```
+
+`urls` accepts up to 10 HTTPS endpoints (plain HTTP is rejected); `events` must be one or more of the values listed in [Get Webhook](/docs/API/get-webhook)'s `availableEvents`. Requires an API key with the administrator role.
+
+## Example response
+
+On success the endpoint returns `201 Created`:
+
+```json
+{
+ "data": {
+ "id": "b7e2c4a1-3f9d-4e6a-8c1b-5d0f7a2e9c34",
+ "orgId": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
+ "name": "signature",
+ "urls": ["https://example.com/webhooks/turbodocx"],
+ "events": ["signature.document.completed", "signature.document.voided"],
+ "secret": "whsec_9f1a2b3c4d5e6f708192a3b4c5d6e7f8091a2b3c4d5e6f708192a3b4c5d6e7f8",
+ "isActive": true,
+ "createdBy": "f5e6d7c8-9a0b-4c1d-2e3f-4a5b6c7d8e9f",
+ "createdOn": "2026-05-01T14:22:10.000Z",
+ "updatedOn": "2026-05-01T14:22:10.000Z",
+ "secretExists": true
+ },
+ "message": "Webhook created successfully. Save the secret - it won't be shown again."
+}
+```
+
+`secret` is only ever returned in full on create and on [Regenerate Webhook Secret](/docs/API/regenerate-webhook-secret); every other endpoint returns a masked `maskedSecret` instead. Use `secret` to verify the `X-TurboDocx-Signature` header on incoming webhook calls.
+
+## Common errors
+
+| Status | When | Response body |
+| ------ | ---- | ------------- |
+| 401 | Missing or invalid API key/token, or the organization cannot be resolved | Empty (status only) |
+| 403 | The key's role is not administrator | Empty (status only) |
+| 400 | `name`, `urls`, or `events` is missing or invalid, or any URL is not HTTPS | `{ "message", "type": "ValidationError", "data": { "errors": [...] } }` |
+| 409 | A webhook named `signature` already exists in your organization | `{ "message", "error": "WebhookNameTaken", "data": { "constraint", "orgId", "name" } }` |
+
+## Related endpoints
+
+- [Get Webhook](/docs/API/get-webhook) to view the webhook you created, its delivery stats, and available event types
+- [Update Webhook](/docs/API/update-webhook) to change its URLs, events, or active state
+- [Test Webhook](/docs/API/test-webhook) to send a sample event before going live
+
diff --git a/docs/API/delete-tags-by-i-ds.api.mdx b/docs/API/delete-tags-by-i-ds.api.mdx
index 43bd89a..fb608a4 100644
--- a/docs/API/delete-tags-by-i-ds.api.mdx
+++ b/docs/API/delete-tags-by-i-ds.api.mdx
@@ -1,7 +1,7 @@
---
id: delete-tags-by-i-ds
title: "Delete Tags (by IDs)"
-description: "Delete Tags (by IDs)"
+description: "Delete one or more tags from your organization in a single call, by ID. Includes example request, response, and error handling."
sidebar_label: "Delete Tags (by IDs)"
hide_title: true
hide_table_of_contents: true
@@ -16,9 +16,49 @@ custom_edit_url: null
# Delete Tags (by IDs)
-
- Delete Tags (by IDs)
-
+
+The Delete Tags (by IDs) endpoint deactivates one or more tags in a single call. It is a soft delete: matching tags are marked inactive rather than removed from the database, so they immediately stop appearing in [Read Tag](/docs/API/read-tag) and tag pickers.
+
+## When to use it
+
+Use this endpoint to let users bulk-remove tags they no longer need, instead of calling a single-tag delete endpoint in a loop.
+
+## Example request
+
+```bash
+curl -X DELETE "https://api.turbodocx.com/Tag/Bulk/Action" \
+ -H "Authorization: Bearer $TURBODOCX_API_KEY" \
+ -H "x-rapiddocx-org-id: $TURBODOCX_ORG_ID" \
+ -H "Content-Type: application/json" \
+ -d '{"ids": ["7c1a0b52-9e88-4f0d-b3a2-1d4c6f8e2a90", "9d2b1c63-0f77-4a9c-b1d0-2c5e6f7a8b90"]}'
+```
+
+## Example response
+
+On success the endpoint returns `200 OK` with an empty data object:
+
+```json
+{
+ "data": {}
+}
+```
+
+Deletion is idempotent: IDs that do not exist, or belong to another organization, are silently skipped rather than causing an error.
+
+## Common errors
+
+| Status | When | Response body |
+| ------ | ---- | ------------- |
+| 401 | Missing or invalid API key/token, or the organization cannot be resolved | Empty (status only) |
+| 403 | The key's role is not administrator, contributor, or user | Empty (status only) |
+| 400 | `ids` is missing or not an array | `{ "message", "type": "ValidationError", "data": { "errors": [...] } }` |
+
+## Related endpoints
+
+- [Read Tag](/docs/API/read-tag) to find the tag IDs to delete
+- [Create Tag](/docs/API/create-tag) to add a new tag
+- [Update Tag](/docs/API/update-tag) to rename a tag instead of deleting it
+
diff --git a/docs/API/delete-variables-by-i-ds.api.mdx b/docs/API/delete-variables-by-i-ds.api.mdx
index a091066..80a5b56 100644
--- a/docs/API/delete-variables-by-i-ds.api.mdx
+++ b/docs/API/delete-variables-by-i-ds.api.mdx
@@ -1,7 +1,7 @@
---
id: delete-variables-by-i-ds
title: "Delete Variables (by IDs)"
-description: "Delete Variables (by IDs)"
+description: "Delete one or more knowledge-base or folder variables in a single call, by variableMapId. Includes example request, response, and errors."
sidebar_label: "Delete Variables (by IDs)"
hide_title: true
hide_table_of_contents: true
@@ -16,9 +16,48 @@ custom_edit_url: null
# Delete Variables (by IDs)
-
- Delete Variables (by IDs)
-
+
+The Delete Variables (by IDs) endpoint removes one or more variables from your knowledge base or a template folder in a single call, along with their versions, tags, and (for image variables) their stored files.
+
+## When to use it
+
+Use this endpoint to let users bulk-clean their variable library, instead of calling a single-variable delete endpoint in a loop.
+
+## Example request
+
+```bash
+curl -X DELETE "https://api.turbodocx.com/Variable/Bulk/Action" \
+ -H "Authorization: Bearer $TURBODOCX_API_KEY" \
+ -H "x-rapiddocx-org-id: $TURBODOCX_ORG_ID" \
+ -H "Content-Type: application/json" \
+ -d '{"ids": ["e4f5a6b7-8c9d-4e0f-a1b2-3c4d5e6f7a8b"]}'
+```
+
+Each entry in `ids` is a `variableMapId`, the same `id` returned by [Read Variables (Folder)](/docs/API/read-variables-folder).
+
+## Example response
+
+On success the endpoint returns `200 OK` with an empty data object:
+
+```json
+{
+ "data": {}
+}
+```
+
+## Common errors
+
+| Status | When | Response body |
+| ------ | ---- | ------------- |
+| 401 | Missing or invalid API key/token, or the organization cannot be resolved | Empty (status only) |
+| 403 | The key's role is not administrator, contributor, or user | Empty (status only) |
+| 400 | `ids` is missing or not an array | `{ "message", "type": "ValidationError", "data": { "errors": [...] } }` |
+
+## Related endpoints
+
+- [Read Variables (Folder)](/docs/API/read-variables-folder) to find the variable IDs to delete
+- [Update Variable by ID](/docs/API/update-variable-by-id) to edit a variable instead of deleting it
+
diff --git a/docs/API/delete-webhook.api.mdx b/docs/API/delete-webhook.api.mdx
index e65e2be..eaa7d93 100644
--- a/docs/API/delete-webhook.api.mdx
+++ b/docs/API/delete-webhook.api.mdx
@@ -1,7 +1,7 @@
---
id: delete-webhook
title: "Delete Webhook"
-description: "Soft-delete the org's signature webhook and its delivery history."
+description: "Permanently delete the org's signature webhook and its delivery history. This is a hard delete and cannot be undone."
sidebar_label: "Delete Webhook"
hide_title: true
hide_table_of_contents: true
@@ -16,9 +16,46 @@ custom_edit_url: null
# Delete Webhook
-
- Delete Webhook
-
+
+The Delete Webhook endpoint permanently removes a webhook and all of its delivery history. Unlike [Delete Template](/docs/API/delete-template), this is a hard delete: the webhook row and its delivery records are removed from the database, not deactivated. There is no un-delete.
+
+## When to use it
+
+Use this endpoint when you are decommissioning an integration and no longer want TurboDocx to call your endpoint. If you only want to pause delivery temporarily, use [Update Webhook](/docs/API/update-webhook) with `isActive: false` instead, so you keep the secret and delivery history.
+
+## Example request
+
+```bash
+curl -X DELETE "https://api.turbodocx.com/api/webhooks/signature" \
+ -H "Authorization: Bearer $TURBODOCX_API_KEY" \
+ -H "x-rapiddocx-org-id: $TURBODOCX_ORG_ID" \
+ -H "Accept: application/json"
+```
+
+## Example response
+
+On success the endpoint returns `200 OK`:
+
+```json
+{
+ "message": "Webhook deleted successfully"
+}
+```
+
+## Common errors
+
+| Status | When | Response body |
+| ------ | ---- | ------------- |
+| 401 | Missing or invalid API key/token, or the organization cannot be resolved | Empty (status only) |
+| 403 | The key's role is not administrator | Empty (status only) |
+| 404 | No webhook with that name exists in your organization | `{ "error": "Webhook not found" }` |
+
+## Related endpoints
+
+- [Get Webhook](/docs/API/get-webhook) to confirm the webhook's configuration before deleting it
+- [Update Webhook](/docs/API/update-webhook) to pause delivery instead of deleting
+- [Create Webhook](/docs/API/create-webhook) to register a new webhook afterward
+
diff --git a/docs/API/edit-template-metadata.api.mdx b/docs/API/edit-template-metadata.api.mdx
index 8cc7363..7bc21a5 100644
--- a/docs/API/edit-template-metadata.api.mdx
+++ b/docs/API/edit-template-metadata.api.mdx
@@ -1,7 +1,7 @@
---
id: edit-template-metadata
title: "Edit Template Metadata"
-description: "Edit Template Metadata"
+description: "Rename a template, change its description or folder, or replace its tags with a single PATCH call. Includes an example request, response, and error handling."
sidebar_label: "Edit Template Metadata"
hide_title: true
hide_table_of_contents: true
@@ -16,9 +16,48 @@ custom_edit_url: null
# Edit Template Metadata
-
- Edit Template Metadata
-
+
+The Edit Template Metadata endpoint updates a template's name, description, folder, or tags without touching its file or variables. Send only the fields you want to change; fields you omit are left as-is.
+
+## When to use it
+
+Use this endpoint to rename a template, move it into a different folder (`templateFolderId`), or replace its tags after you have already uploaded it. To change the file itself, delete the template and upload a new one with [Upload Template with Optional Default Values](/docs/API/upload-template-with-optional-default-values).
+
+## Example request
+
+```bash
+curl -X PATCH "https://api.turbodocx.com/template/2b8f1c9e-4d3a-4a7c-9f21-6b0d5e9a1c34" \
+ -H "Authorization: Bearer $TURBODOCX_API_KEY" \
+ -H "x-rapiddocx-org-id: $TURBODOCX_ORG_ID" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "name": "SOW Template (v2)",
+ "description": "Standard statement of work, updated for 2026 pricing",
+ "tags": [{"id": "7c1a0b52-9e88-4f0d-b3a2-1d4c6f8e2a90"}]
+ }'
+```
+
+Sending `tags` replaces the template's entire tag list: existing tags not included in the array are removed. Each entry only needs the tag's `id`, from [Create Tag](/docs/API/create-tag) or [Read Tag](/docs/API/read-tag).
+
+## Example response
+
+On success the endpoint returns `200 OK` with no response body.
+
+## Common errors
+
+| Status | When | Response body |
+| ------ | ---- | ------------- |
+| 401 | Missing or invalid API key/token, or the organization cannot be resolved | Empty (status only) |
+| 403 | The key's role is not administrator, contributor, or user | Empty (status only) |
+| 423 | The template is locked | `{ "error": "Resource is locked", "message", "data": { "locked": true, "lockedBy", "lockedOn" } }` |
+| 400 | A field fails validation (for example `name` under 3 characters) | `{ "message", "type": "ValidationError", "data": { "errors": [...] } }` |
+
+## Related endpoints
+
+- [Get Template by ID](/docs/API/get-template-by-id) to see the current metadata before editing
+- [Delete Template](/docs/API/delete-template) to remove a template instead of editing it
+- [Get Templates and Folders](/docs/API/get-templates-and-folders) to find the `TemplateId` to edit
+
diff --git a/docs/API/extract-template-placeholders-and-generate-preview.api.mdx b/docs/API/extract-template-placeholders-and-generate-preview.api.mdx
index a294ce2..572c7d6 100644
--- a/docs/API/extract-template-placeholders-and-generate-preview.api.mdx
+++ b/docs/API/extract-template-placeholders-and-generate-preview.api.mdx
@@ -1,7 +1,7 @@
---
id: extract-template-placeholders-and-generate-preview
title: "Extract Template Placeholders and Generate Preview"
-description: "Extract Template Placeholders and Generate Preview"
+description: "Upload a DOCX or PPTX file to extract its {placeholder} variables and fonts, and optionally render a PDF preview, before creating the template."
sidebar_label: "Extract Template Placeholders and Generate Preview"
hide_title: true
hide_table_of_contents: true
@@ -16,9 +16,65 @@ custom_edit_url: null
# Extract Template Placeholders and Generate Preview
-
- Extract Template Placeholders and Generate Preview
-
+
+The Extract Template Placeholders and Generate Preview endpoint parses an uploaded DOCX or PPTX file and returns every `{placeholder}` variable and font it found, without creating a template. By default it also renders a PDF preview of the file and returns it inline. This lets you show a user exactly what variables a file contains, and what it looks like, before they commit to uploading it as a template.
+
+## When to use it
+
+Use this endpoint to build an "upload and preview" step ahead of [Upload Template with Optional Default Values](/docs/API/upload-template-with-optional-default-values): show the detected placeholders so the user can confirm or rename them, and show the rendered PDF so they can confirm it's the right file. Pass `skipFile=true` if you only need the extracted variables and fonts and want to skip the (slower) PDF render.
+
+## Example request
+
+```bash
+curl -X POST "https://api.turbodocx.com/template/file?skipFile=true" \
+ -H "Authorization: Bearer $TURBODOCX_API_KEY" \
+ -H "x-rapiddocx-org-id: $TURBODOCX_ORG_ID" \
+ -F "file=@./sow-template.docx"
+```
+
+## Example response
+
+With `skipFile=true`:
+
+```json
+{
+ "data": {
+ "results": {
+ "filetype": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
+ "vars": [
+ {
+ "placeholder": "{CustomerName}",
+ "name": "CustomerName",
+ "mimeType": "text",
+ "order": 0,
+ "count": 1,
+ "allowRichTextInjection": false
+ }
+ ],
+ "fonts": [{ "name": "Calibri" }]
+ }
+ }
+}
+```
+
+Without `skipFile`, the response also includes `templatePdf`, the rendered PDF of the uploaded file. It is a JSON-serialized Node.js Buffer, not a base64 string: an object of the form `{"type": "Buffer", "data": [37, 80, 68, 70, ...]}`, where `data` is an array of the PDF's raw bytes. To use it, reconstruct the binary from the byte array, for example `Buffer.from(templatePdf.data)` in Node.js or `new Uint8Array(templatePdf.data)` in the browser. Pass the `vars` array as the `variables` field (JSON-stringified) when you subsequently call [Upload Template with Optional Default Values](/docs/API/upload-template-with-optional-default-values).
+
+## Common errors
+
+| Status | When | Response body |
+| ------ | ---- | ------------- |
+| 401 | Missing or invalid API key/token, or the organization cannot be resolved | Empty (status only) |
+| 403 | The key's role is not administrator, contributor, or user | Empty (status only) |
+| 400 | No file was attached, or the file could not be uploaded ("Improper File Upload") | `{ "message", "error", "data": { "explanation", "context" } }` |
+| 400 | The file type is not supported (not DOCX, PPTX, or HTML) | `{ "message": "Unsupported File Type", "error", "data": { "explanation", "context" } }` |
+| 400 | Your plan's template or storage limit is reached | `{ "message", "type", "data": { "explanation", "context" } }` |
+| 503 | The storage service is temporarily unavailable | `{ "message", "error", "data": { "explanation", "context" } }` |
+
+## Related endpoints
+
+- [Upload Template with Optional Default Values](/docs/API/upload-template-with-optional-default-values) to create the template from the same file
+- [Get Templates and Folders](/docs/API/get-templates-and-folders) to browse existing templates
+
diff --git a/docs/API/get-template-by-id.api.mdx b/docs/API/get-template-by-id.api.mdx
index 726c2b1..2c7871c 100644
--- a/docs/API/get-template-by-id.api.mdx
+++ b/docs/API/get-template-by-id.api.mdx
@@ -1,7 +1,7 @@
---
id: get-template-by-id
title: "Get Template by ID"
-description: "Get Template by ID"
+description: "Fetch a single template by ID: its metadata, tags, and merged variables (template, folder, and global). Includes example request, response, and error handling."
sidebar_label: "Get Template by ID"
hide_title: true
hide_table_of_contents: true
@@ -16,9 +16,78 @@ custom_edit_url: null
# Get Template by ID
-
- Get Template by ID
-
+
+The Get Template by ID endpoint returns a single template's full details: its metadata, creator, and the variables available to it. The variables array merges the template's own variables with any inherited from its folder and from your organization's global (knowledge base) variables, so it reflects everything the template can fill in at generation time.
+
+## When to use it
+
+Use this endpoint to load a template's details and variable list before generating a document, to check whether a template is TurboDocx-provided (and therefore read-only), or to confirm a metadata change made with [Edit Template Metadata](/docs/API/edit-template-metadata).
+
+## Example request
+
+```bash
+curl "https://api.turbodocx.com/template/2b8f1c9e-4d3a-4a7c-9f21-6b0d5e9a1c34?showTags=true" \
+ -H "Authorization: Bearer $TURBODOCX_API_KEY" \
+ -H "x-rapiddocx-org-id: $TURBODOCX_ORG_ID" \
+ -H "Accept: application/json"
+```
+
+Pass `showTags=true` to include the template's `tags` array in the response; it is omitted by default.
+
+## Example response
+
+```json
+{
+ "data": {
+ "results": {
+ "id": "2b8f1c9e-4d3a-4a7c-9f21-6b0d5e9a1c34",
+ "name": "SOW Template",
+ "description": "Standard statement of work",
+ "isActive": true,
+ "createdOn": "2026-05-01T14:22:10.000Z",
+ "updatedOn": "2026-05-01T14:22:10.000Z",
+ "createdBy": "f5e6d7c8-9a0b-4c1d-2e3f-4a5b6c7d8e9f",
+ "firstName": "Jane",
+ "lastName": "Doe",
+ "email": "jane@example.com",
+ "orgId": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
+ "templateFolderId": null,
+ "defaultFont": "Calibri",
+ "fonts": [{ "name": "Calibri" }],
+ "metadata": {},
+ "templateFileType": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
+ "isTurboDocxProvided": false,
+ "deliverableCount": 12,
+ "variables": [
+ {
+ "placeholder": "{CustomerName}",
+ "name": "CustomerName",
+ "mimeType": "text",
+ "order": 0,
+ "count": 1
+ }
+ ]
+ }
+ }
+}
+```
+
+`isTurboDocxProvided` is `true` for templates from the built-in TurboDocx library; those cannot be edited in place and must be downloaded and re-uploaded to customize. Each entry in `variables` mirrors the variable fields returned by generation, with `isTemplateFolder` set on variables inherited from the template's folder.
+
+## Common errors
+
+| Status | When | Response body |
+| ------ | ---- | ------------- |
+| 401 | Missing or invalid API key/token, or the organization cannot be resolved | Empty (status only) |
+| 404 | No active template with that ID exists in your organization | Empty (status only) |
+| 400 | The `TemplateID` path parameter is not a valid UUID | `{ "message", "type": "ValidationError", "data": { "errors": [...] } }` |
+
+## Related endpoints
+
+- [Get Templates and Folders](/docs/API/get-templates-and-folders) to list templates and find a `TemplateId`
+- [Edit Template Metadata](/docs/API/edit-template-metadata) to rename, retag, or move this template
+- [Delete Template](/docs/API/delete-template) to remove this template
+
diff --git a/docs/API/get-webhook-stats.api.mdx b/docs/API/get-webhook-stats.api.mdx
index 0190dfa..3f8fd4d 100644
--- a/docs/API/get-webhook-stats.api.mdx
+++ b/docs/API/get-webhook-stats.api.mdx
@@ -1,7 +1,7 @@
---
id: get-webhook-stats
title: "Get Webhook Stats"
-description: "Retrieve aggregate delivery statistics for the org's signature webhook over a sliding time window. Returns per-event breakdown, success rates, average response times, and last delivery timestamps."
+description: "Aggregate delivery statistics for the org's signature webhook over a custom time window: per-event breakdown, success rate, response time."
sidebar_label: "Get Webhook Stats"
hide_title: true
hide_table_of_contents: true
@@ -16,9 +16,74 @@ custom_edit_url: null
# Get Webhook Stats
-
- Get Webhook Stats
-
+
+The Get Webhook Stats endpoint returns delivery statistics for this specific webhook over a time window you choose, broken down by event type. Unlike the `deliveryStats` on [Get Webhook](/docs/API/get-webhook) (which cover your whole organization's last 30 days), this endpoint is scoped to one webhook and lets you pick the window.
+
+## When to use it
+
+Use this endpoint to build a delivery health dashboard for a single webhook: overall success rate, average response time, and which event types are failing most, over a period you control.
+
+## Example request
+
+```bash
+curl "https://api.turbodocx.com/api/webhooks/signature/stats?days=7" \
+ -H "Authorization: Bearer $TURBODOCX_API_KEY" \
+ -H "x-rapiddocx-org-id: $TURBODOCX_ORG_ID" \
+ -H "Accept: application/json"
+```
+
+`days` defaults to `30` and accepts 1 to 365.
+
+## Example response
+
+```json
+{
+ "data": {
+ "webhook": {
+ "id": "b7e2c4a1-3f9d-4e6a-8c1b-5d0f7a2e9c34",
+ "name": "signature",
+ "isActive": true,
+ "events": ["signature.document.completed", "signature.document.voided"],
+ "urls": ["https://example.com/webhooks/turbodocx"]
+ },
+ "period": { "days": 7, "from": "2026-04-25T00:00:00.000Z", "to": "2026-05-02T00:00:00.000Z" },
+ "summary": {
+ "totalDeliveries": 42,
+ "successfulDeliveries": 40,
+ "failedDeliveries": 1,
+ "pendingRetries": 1,
+ "successRate": 95.24,
+ "avgResponseTime": 184,
+ "lastSuccessfulDelivery": "2026-05-01T22:10:05.000Z",
+ "lastFailedDelivery": "2026-04-29T11:02:41.000Z"
+ },
+ "eventBreakdown": [
+ {
+ "eventType": "signature.document.completed",
+ "total": 30,
+ "successful": 29,
+ "failed": 1,
+ "successRate": 96.67
+ }
+ ]
+ }
+}
+```
+
+## Common errors
+
+| Status | When | Response body |
+| ------ | ---- | ------------- |
+| 401 | Missing or invalid API key/token, or the organization cannot be resolved | Empty (status only) |
+| 403 | The key's role is not administrator | Empty (status only) |
+| 404 | No webhook with that name exists in your organization | `{ "error": "Webhook not found" }` |
+| 400 | `days` is outside 1 to 365 | Validation error from the query schema |
+
+## Related endpoints
+
+- [Get Webhook](/docs/API/get-webhook) for the webhook's current configuration
+- [List Webhook Deliveries](/docs/API/list-webhook-deliveries) to inspect individual delivery attempts behind these numbers
+
diff --git a/docs/API/get-webhook.api.mdx b/docs/API/get-webhook.api.mdx
index f763efa..b5bef80 100644
--- a/docs/API/get-webhook.api.mdx
+++ b/docs/API/get-webhook.api.mdx
@@ -16,9 +16,75 @@ custom_edit_url: null
# Get Webhook
-
- Get Webhook
-
+
+The Get Webhook endpoint returns a webhook's current configuration (URLs, subscribed events, active state), its secret status, delivery statistics for your organization, and the full list of event types you can subscribe to.
+
+## When to use it
+
+Use this endpoint to display a webhook's settings in your own dashboard, to check whether it is active before troubleshooting missing events, or to read `availableEvents` so you can build an event-picker UI without hardcoding the list.
+
+## Example request
+
+```bash
+curl "https://api.turbodocx.com/api/webhooks/signature" \
+ -H "Authorization: Bearer $TURBODOCX_API_KEY" \
+ -H "x-rapiddocx-org-id: $TURBODOCX_ORG_ID" \
+ -H "Accept: application/json"
+```
+
+`signature` is the webhook's `name`, not its `id`; every TurboDocx SDK-created webhook uses that name.
+
+## Example response
+
+```json
+{
+ "data": {
+ "id": "b7e2c4a1-3f9d-4e6a-8c1b-5d0f7a2e9c34",
+ "orgId": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
+ "name": "signature",
+ "urls": ["https://example.com/webhooks/turbodocx"],
+ "events": ["signature.document.completed", "signature.document.voided"],
+ "isActive": true,
+ "createdBy": "f5e6d7c8-9a0b-4c1d-2e3f-4a5b6c7d8e9f",
+ "createdOn": "2026-05-01T14:22:10.000Z",
+ "updatedOn": "2026-05-01T14:22:10.000Z",
+ "secretExists": true,
+ "maskedSecret": "whs***7f8",
+ "deliveryStats": {
+ "totalDeliveries": 214,
+ "successfulDeliveries": 209,
+ "failedDeliveries": 3,
+ "pendingRetries": 2
+ },
+ "availableEvents": [
+ "signature.document.sent",
+ "signature.document.viewed",
+ "signature.document.signed",
+ "signature.document.recipient_signed",
+ "signature.document.completed",
+ "signature.document.finalization_failed",
+ "signature.document.voided"
+ ]
+ }
+}
+```
+
+`deliveryStats` covers all webhook deliveries across your organization over the last 30 days, not only this webhook's. For per-delivery detail, or stats scoped to a custom time window, use [Get Webhook Stats](/docs/API/get-webhook-stats).
+
+## Common errors
+
+| Status | When | Response body |
+| ------ | ---- | ------------- |
+| 401 | Missing or invalid API key/token, or the organization cannot be resolved | Empty (status only) |
+| 403 | The key's role is not administrator | Empty (status only) |
+| 404 | No webhook with that name exists in your organization | `{ "error": "Webhook not found" }` |
+
+## Related endpoints
+
+- [Update Webhook](/docs/API/update-webhook) to change its URLs, events, or active state
+- [Get Webhook Stats](/docs/API/get-webhook-stats) for delivery stats scoped to this webhook over a custom period
+- [List Webhook Deliveries](/docs/API/list-webhook-deliveries) to inspect individual delivery attempts
+
diff --git a/docs/API/list-webhook-deliveries.api.mdx b/docs/API/list-webhook-deliveries.api.mdx
index b4f583b..92e44b8 100644
--- a/docs/API/list-webhook-deliveries.api.mdx
+++ b/docs/API/list-webhook-deliveries.api.mdx
@@ -16,9 +16,72 @@ custom_edit_url: null
# List Webhook Deliveries
-
- List Webhook Deliveries
-
+
+The List Webhook Deliveries endpoint returns the individual delivery attempts made to your signature webhook's URLs, newest first, with each attempt's status, HTTP response code, and retry count.
+
+## When to use it
+
+Use this endpoint to build a delivery log for debugging: find which attempts failed, filter to a specific event type, or locate a delivery's `id` to pass to [Replay Webhook Delivery](/docs/API/replay-webhook-delivery).
+
+## Example request
+
+```bash
+curl "https://api.turbodocx.com/api/webhooks/signature/deliveries?limit=20&offset=0&isDelivered=false" \
+ -H "Authorization: Bearer $TURBODOCX_API_KEY" \
+ -H "x-rapiddocx-org-id: $TURBODOCX_ORG_ID" \
+ -H "Accept: application/json"
+```
+
+Supported filters: `eventType`, `isDelivered` (`true`/`false`), and `httpStatus` (an exact status code). `limit` defaults to `20`, `offset` to `0`.
+
+> **Known limitation:** `isDelivered=true` and `httpStatus` do not currently filter results correctly due to a backend issue: `isDelivered=true` returns the same (undelivered-only) results as `isDelivered=false`, and `httpStatus` is ignored entirely regardless of value. Only `isDelivered=false` behaves as documented today.
+
+## Example response
+
+```json
+{
+ "data": {
+ "results": [
+ {
+ "id": "d3a1c2b4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
+ "eventType": "signature.document.completed",
+ "url": "https://example.com/webhooks/turbodocx",
+ "httpStatus": 502,
+ "responseBody": "Bad Gateway",
+ "attemptCount": 2,
+ "maxAttempts": 3,
+ "isDelivered": false,
+ "deliveredAt": null,
+ "nextRetryAt": "2026-05-02T09:15:00.000Z",
+ "errorMessage": "Request failed with status code 502",
+ "status": "retrying",
+ "createdOn": "2026-05-02T09:05:00.000Z",
+ "updatedOn": "2026-05-02T09:10:00.000Z"
+ }
+ ],
+ "totalRecords": 1,
+ "limit": 20,
+ "offset": 0
+ }
+}
+```
+
+`status` summarizes the row as `"delivered"`, `"failed"` (all `maxAttempts` attempts exhausted), `"retrying"`, or `"pending"`. Failed deliveries retry automatically with backoff (immediate, then +1 minute, then +5 minutes) for up to `maxAttempts` (3) attempts total before landing in the dead-letter state.
+
+## Common errors
+
+| Status | When | Response body |
+| ------ | ---- | ------------- |
+| 401 | Missing or invalid API key/token, or the organization cannot be resolved | Empty (status only) |
+| 403 | The key's role is not administrator | Empty (status only) |
+| 404 | No webhook with that name exists in your organization | `{ "error": "Webhook not found" }` |
+
+## Related endpoints
+
+- [Replay Webhook Delivery](/docs/API/replay-webhook-delivery) to manually retry a delivery from this list
+- [Get Webhook Stats](/docs/API/get-webhook-stats) for aggregate numbers instead of individual deliveries
+- [Test Webhook](/docs/API/test-webhook) to generate a fresh delivery on demand
+
diff --git a/docs/API/notify-webhook.api.mdx b/docs/API/notify-webhook.api.mdx
index d9c9a8c..aa8988f 100644
--- a/docs/API/notify-webhook.api.mdx
+++ b/docs/API/notify-webhook.api.mdx
@@ -1,7 +1,7 @@
---
id: notify-webhook
title: "Notify Webhook"
-description: "Send a manual notification to all URLs configured on the org's signature webhook. Routes through the same backend handler as Test Webhook; use Test Webhook in new code. Both are exposed for API surface symmetry."
+description: "Send a manual notification to all URLs on the org's signature webhook. Same backend handler as Test Webhook; kept for API surface symmetry."
sidebar_label: "Notify Webhook"
hide_title: true
hide_table_of_contents: true
@@ -16,9 +16,66 @@ custom_edit_url: null
# Notify Webhook
-
- Notify Webhook
-
+
+The Notify Webhook endpoint sends a one-off event delivery to every URL configured on your signature webhook. It calls the exact same backend logic as [Test Webhook](/docs/API/test-webhook): both accept the same body and return the same response shape. This endpoint exists for API surface symmetry with the "notify" naming some integrations expect; new integrations should call Test Webhook instead.
+
+## When to use it
+
+Use this endpoint (or Test Webhook) to confirm your receiving endpoint handles a TurboSign event correctly, without waiting for a real document to reach that state.
+
+## Example request
+
+```bash
+curl -X POST "https://api.turbodocx.com/api/webhooks/signature/notify" \
+ -H "Authorization: Bearer $TURBODOCX_API_KEY" \
+ -H "x-rapiddocx-org-id: $TURBODOCX_ORG_ID" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "eventType": "signature.document.completed",
+ "payload": {"documentId": "doc_abc123", "status": "completed"}
+ }'
+```
+
+Both `eventType` and `payload` are optional; omit them to send a default sample payload for a default event type.
+
+## Example response
+
+```json
+{
+ "data": {
+ "deliveries": [
+ {
+ "id": "d3a1c2b4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
+ "eventType": "signature.document.completed",
+ "url": "https://example.com/webhooks/turbodocx",
+ "httpStatus": 200,
+ "attemptCount": 1,
+ "maxAttempts": 3,
+ "isDelivered": true,
+ "status": "delivered"
+ }
+ ],
+ "summary": { "total": 1, "successful": 1, "failed": 0, "errors": [] }
+ },
+ "message": "Manual notification sent successfully to all URLs"
+}
+```
+
+## Common errors
+
+| Status | When | Response body |
+| ------ | ---- | ------------- |
+| 401 | Missing or invalid API key/token, or the organization cannot be resolved | Empty (status only) |
+| 403 | The key's role is not administrator | Empty (status only) |
+| 404 | No webhook with that name exists in your organization | `{ "error": "Webhook not found" }` |
+| 400 | The webhook exists but `isActive` is `false` | `{ "error": "Cannot send notification to inactive webhook" }` |
+
+## Related endpoints
+
+- [Test Webhook](/docs/API/test-webhook) for the same behavior under TurboDocx's documented name
+- [List Webhook Deliveries](/docs/API/list-webhook-deliveries) to review past delivery attempts
+- [Get Webhook](/docs/API/get-webhook) to check the webhook's configuration first
+
diff --git a/docs/API/read-tag.api.mdx b/docs/API/read-tag.api.mdx
index b03b62c..4c48775 100644
--- a/docs/API/read-tag.api.mdx
+++ b/docs/API/read-tag.api.mdx
@@ -1,7 +1,7 @@
---
id: read-tag
title: "Read Tag"
-description: "Read Tag"
+description: "List the tags in your organization, with search and sorting. Includes example request, response, and error handling."
sidebar_label: "Read Tag"
hide_title: true
hide_table_of_contents: true
@@ -16,9 +16,59 @@ custom_edit_url: null
# Read Tag
-
- Read Tag
-
+
+The Read Tag endpoint lists the active tags in your organization, sorted alphabetically by `label` by default. Despite the singular name, it returns a paginated array, not a single tag. To fetch one tag by its ID, use `GET /Tag/:id`, which returns a single tag object under `data.results` (404 if not found).
+
+## When to use it
+
+Use this endpoint to populate a tag picker or filter dropdown, or to search for an existing tag by name before deciding whether to create a new one with [Create Tag](/docs/API/create-tag).
+
+## Example request
+
+```bash
+curl "https://api.turbodocx.com/Tag?limit=25&offset=0&query=legal" \
+ -H "Authorization: Bearer $TURBODOCX_API_KEY" \
+ -H "x-rapiddocx-org-id: $TURBODOCX_ORG_ID" \
+ -H "Accept: application/json"
+```
+
+`limit` defaults to `6`, `offset` to `0`. `query` filters by a case-insensitive match on `label`. Sort with `column0` (`label`, `createdOn`, or `updatedOn`) and `order0` (`asc` or `desc`).
+
+## Example response
+
+```json
+{
+ "data": {
+ "results": [
+ {
+ "id": "7c1a0b52-9e88-4f0d-b3a2-1d4c6f8e2a90",
+ "label": "legal",
+ "isActive": true,
+ "orgId": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
+ "createdBy": "f5e6d7c8-9a0b-4c1d-2e3f-4a5b6c7d8e9f",
+ "createdOn": "2026-05-01T14:22:10.000Z",
+ "updatedOn": "2026-05-01T14:22:10.000Z"
+ }
+ ],
+ "totalRecords": 1
+ }
+}
+```
+
+## Common errors
+
+| Status | When | Response body |
+| ------ | ---- | ------------- |
+| 401 | Missing or invalid API key/token, or the organization cannot be resolved | Empty (status only) |
+| 400 | A query parameter fails validation | `{ "message", "type": "ValidationError", "data": { "errors": [...] } }` |
+
+## Related endpoints
+
+- [Create Tag](/docs/API/create-tag) to add a new tag
+- [Update Tag](/docs/API/update-tag) to rename an existing tag
+- [Delete Tags (by IDs)](/docs/API/delete-tags-by-i-ds) to remove tags in bulk
+- `GET /Tag/:id` to fetch a single tag by ID
+
diff --git a/docs/API/read-variables-folder.api.mdx b/docs/API/read-variables-folder.api.mdx
index 93cb9e3..2429601 100644
--- a/docs/API/read-variables-folder.api.mdx
+++ b/docs/API/read-variables-folder.api.mdx
@@ -1,7 +1,7 @@
---
id: read-variables-folder
title: "Read Variables (Folder)"
-description: "Read Variables (Folder)"
+description: "List the variables in your knowledge base or a template folder, with search, tags, and pagination. Includes example request and response."
sidebar_label: "Read Variables (Folder)"
hide_title: true
hide_table_of_contents: true
@@ -16,9 +16,65 @@ custom_edit_url: null
# Read Variables (Folder)
-
- Read Variables (Folder)
-
+
+The Read Variables (Folder) endpoint lists reusable variables scoped to your organization's global knowledge base or to a specific template folder. These are standalone variables you manage independently of any one template, for reuse across many templates (for example a company address or a standard clause).
+
+## When to use it
+
+Use this endpoint to build a variable library browser, or to look up a variable's `id` before updating it with [Update Variable by ID](/docs/API/update-variable-by-id) or deleting it with [Delete Variables (by IDs)](/docs/API/delete-variables-by-i-ds).
+
+## Example request
+
+```bash
+curl "https://api.turbodocx.com/Variable?isGlobal=true&limit=25&offset=0&showTags=true" \
+ -H "Authorization: Bearer $TURBODOCX_API_KEY" \
+ -H "x-rapiddocx-org-id: $TURBODOCX_ORG_ID" \
+ -H "Accept: application/json"
+```
+
+Optionally pass `isGlobal=true` (your org-wide knowledge base) or `templateFolderId=` (a specific folder) to scope the list; at most one may be set, and passing both is rejected. Omit both to list across your accessible scope. `limit` defaults to `6`, `offset` to `0`, and `query` filters by name.
+
+## Example response
+
+```json
+{
+ "data": {
+ "results": [
+ {
+ "id": "e4f5a6b7-8c9d-4e0f-a1b2-3c4d5e6f7a8b",
+ "variableMapId": "e4f5a6b7-8c9d-4e0f-a1b2-3c4d5e6f7a8b",
+ "name": "Company Address",
+ "placeholder": "{CompanyAddress}",
+ "description": "Standard mailing address block",
+ "mimeType": "text",
+ "text": "123 Main St, Suite 400, Austin, TX 78701",
+ "isGlobal": true,
+ "templateFolderId": null,
+ "allowRichTextInjection": false,
+ "createdBy": "f5e6d7c8-9a0b-4c1d-2e3f-4a5b6c7d8e9f",
+ "updatedOn": "2026-05-01T14:22:10.000Z"
+ }
+ ],
+ "totalRecords": 1
+ }
+}
+```
+
+An image variable's `text` holds a `data:` URI rather than plain text.
+
+## Common errors
+
+| Status | When | Response body |
+| ------ | ---- | ------------- |
+| 401 | Missing or invalid API key/token, or the organization cannot be resolved | Empty (status only) |
+| 400 | Both `isGlobal` and `templateFolderId` are set, or a query parameter fails validation | `{ "message", "type": "ValidationError", "data": { "errors": [...] } }` |
+
+## Related endpoints
+
+- [Update Variable by ID](/docs/API/update-variable-by-id) to change a variable found here
+- [Delete Variables (by IDs)](/docs/API/delete-variables-by-i-ds) to remove variables in bulk
+- [Get Template by ID](/docs/API/get-template-by-id) to see how folder and global variables merge into a template
+
diff --git a/docs/API/regenerate-webhook-secret.api.mdx b/docs/API/regenerate-webhook-secret.api.mdx
index ada4d07..9329032 100644
--- a/docs/API/regenerate-webhook-secret.api.mdx
+++ b/docs/API/regenerate-webhook-secret.api.mdx
@@ -1,7 +1,7 @@
---
id: regenerate-webhook-secret
title: "Regenerate Webhook Secret"
-description: "Rotate the org's signature webhook HMAC secret. The new secret is returned **once** — store it immediately. Old HMAC signatures will fail as soon as this call succeeds."
+description: "Rotate the org's signature webhook HMAC secret. The new secret is returned once; store it immediately, since old signatures stop working right away."
sidebar_label: "Regenerate Webhook Secret"
hide_title: true
hide_table_of_contents: true
@@ -16,9 +16,51 @@ custom_edit_url: null
# Regenerate Webhook Secret
-
- Regenerate Webhook Secret
-
+
+The Regenerate Webhook Secret endpoint issues a new HMAC secret for your signature webhook and immediately replaces the old one. Use the returned secret to verify the `X-TurboDocx-Signature` header on incoming webhook calls.
+
+## When to use it
+
+Use this endpoint if the current secret may have leaked, or as part of a routine credential rotation. Because the change takes effect immediately, update your webhook receiver's stored secret before or right after calling this endpoint; deliveries signed with the old secret will fail verification on your side as soon as it rotates.
+
+## Example request
+
+```bash
+curl -X POST "https://api.turbodocx.com/api/webhooks/signature/regenerate" \
+ -H "Authorization: Bearer $TURBODOCX_API_KEY" \
+ -H "x-rapiddocx-org-id: $TURBODOCX_ORG_ID" \
+ -H "Accept: application/json"
+```
+
+## Example response
+
+```json
+{
+ "data": {
+ "id": "b7e2c4a1-3f9d-4e6a-8c1b-5d0f7a2e9c34",
+ "secret": "whsec_1a2b3c4d5e6f708192a3b4c5d6e7f8091a2b3c4d5e6f708192a3b4c5d6e7f809",
+ "regeneratedAt": "2026-05-02T09:20:00.000Z"
+ },
+ "message": "Webhook secret regenerated successfully. Save the new secret - it won't be shown again."
+}
+```
+
+The full `secret` is only returned here and on [Create Webhook](/docs/API/create-webhook); [Get Webhook](/docs/API/get-webhook) only ever returns a masked `maskedSecret`.
+
+## Common errors
+
+| Status | When | Response body |
+| ------ | ---- | ------------- |
+| 401 | Missing or invalid API key/token, or the organization cannot be resolved | Empty (status only) |
+| 403 | The key's role is not administrator | Empty (status only) |
+| 404 | No webhook with that name exists in your organization | `{ "error": "Webhook not found" }` |
+
+## Related endpoints
+
+- [Get Webhook](/docs/API/get-webhook) to confirm the secret was rotated (`maskedSecret` changes)
+- [Update Webhook](/docs/API/update-webhook) to change URLs or events without rotating the secret
+- [Test Webhook](/docs/API/test-webhook) to confirm your receiver validates the new secret correctly
+
diff --git a/docs/API/replay-webhook-delivery.api.mdx b/docs/API/replay-webhook-delivery.api.mdx
index c847a78..174fb9c 100644
--- a/docs/API/replay-webhook-delivery.api.mdx
+++ b/docs/API/replay-webhook-delivery.api.mdx
@@ -1,7 +1,7 @@
---
id: replay-webhook-delivery
title: "Replay Webhook Delivery"
-description: "Manually retry a specific past delivery by its ID. Creates a new delivery row and immediately attempts re-delivery to all configured URLs. Returns the full delivery object for the new attempt."
+description: "Manually retry one past delivery by its ID. Creates a new delivery row and immediately re-sends the event to the URL the original delivery targeted."
sidebar_label: "Replay Webhook Delivery"
hide_title: true
hide_table_of_contents: true
@@ -16,9 +16,63 @@ custom_edit_url: null
# Replay Webhook Delivery
-
- Replay Webhook Delivery
-
+
+The Replay Webhook Delivery endpoint manually retries a specific past delivery, identified by its `deliveryId`. It creates a brand-new delivery row for the attempt (the original row is left as-is) and immediately re-sends the event to the URL the original delivery was made to (not every URL configured on the webhook, if it has more than one).
+
+## When to use it
+
+Use this endpoint to retry a delivery that permanently failed (exhausted its automatic retries) after you have fixed whatever was wrong with your receiving endpoint, instead of waiting for the same event to occur again.
+
+## Example request
+
+```bash
+curl -X POST "https://api.turbodocx.com/api/webhooks/signature/replay" \
+ -H "Authorization: Bearer $TURBODOCX_API_KEY" \
+ -H "x-rapiddocx-org-id: $TURBODOCX_ORG_ID" \
+ -H "Content-Type: application/json" \
+ -d '{"deliveryId": "d3a1c2b4-5e6f-4a7b-8c9d-0e1f2a3b4c5d"}'
+```
+
+Get `deliveryId` from [List Webhook Deliveries](/docs/API/list-webhook-deliveries).
+
+## Example response
+
+On success the endpoint returns `200 OK` with the new delivery:
+
+```json
+{
+ "data": {
+ "id": "f2e1d0c9-8b7a-4695-a3b2-1c0d9e8f7a6b",
+ "eventType": "signature.document.completed",
+ "url": "https://example.com/webhooks/turbodocx",
+ "attemptCount": 0,
+ "maxAttempts": 3,
+ "isDelivered": false,
+ "status": "pending",
+ "createdOn": "2026-05-02T09:30:00.000Z",
+ "updatedOn": "2026-05-02T09:30:00.000Z"
+ },
+ "message": "Webhook delivery replayed successfully - new delivery attempt created"
+}
+```
+
+Check the new delivery's status afterward with [List Webhook Deliveries](/docs/API/list-webhook-deliveries).
+
+## Common errors
+
+| Status | When | Response body |
+| ------ | ---- | ------------- |
+| 401 | Missing or invalid API key/token, or the organization cannot be resolved | Empty (status only) |
+| 403 | The key's role is not administrator | Empty (status only) |
+| 404 | No webhook with that name exists, or `deliveryId` does not belong to it | `{ "error": "Webhook or delivery not found" }` |
+| 400 | `deliveryId` is missing or not a valid UUID | Validation error from the body schema |
+
+## Related endpoints
+
+- [List Webhook Deliveries](/docs/API/list-webhook-deliveries) to find failed deliveries to replay
+- [Test Webhook](/docs/API/test-webhook) to send a fresh sample event instead of replaying a past one
+- [Get Webhook Stats](/docs/API/get-webhook-stats) to see whether replays are improving your success rate
+
diff --git a/docs/API/test-webhook.api.mdx b/docs/API/test-webhook.api.mdx
index 004ab81..33f2d19 100644
--- a/docs/API/test-webhook.api.mdx
+++ b/docs/API/test-webhook.api.mdx
@@ -16,9 +16,68 @@ custom_edit_url: null
# Test Webhook
-
- Test Webhook
-
+
+The Test Webhook endpoint sends a sample event delivery to every URL configured on your signature webhook and returns a per-URL summary of the result. It creates a real delivery record, identical to a delivery triggered by an actual TurboSign event, so it also shows up in [List Webhook Deliveries](/docs/API/list-webhook-deliveries).
+
+## When to use it
+
+Use this endpoint right after creating or updating a webhook to confirm your receiving endpoint is reachable and returns a 2xx response, before relying on it for real signature events.
+
+## Example request
+
+```bash
+curl -X POST "https://api.turbodocx.com/api/webhooks/signature/test" \
+ -H "Authorization: Bearer $TURBODOCX_API_KEY" \
+ -H "x-rapiddocx-org-id: $TURBODOCX_ORG_ID" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "eventType": "signature.document.completed",
+ "payload": {"documentId": "doc_abc123", "status": "completed"}
+ }'
+```
+
+Both `eventType` and `payload` are optional; omit them to send a default sample payload for a default event type.
+
+## Example response
+
+```json
+{
+ "data": {
+ "deliveries": [
+ {
+ "id": "d3a1c2b4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
+ "eventType": "signature.document.completed",
+ "url": "https://example.com/webhooks/turbodocx",
+ "httpStatus": 200,
+ "attemptCount": 1,
+ "maxAttempts": 3,
+ "isDelivered": true,
+ "status": "delivered"
+ }
+ ],
+ "summary": { "total": 1, "successful": 1, "failed": 0, "errors": [] }
+ },
+ "message": "Test webhook sent successfully to all URLs"
+}
+```
+
+If a URL returns a non-2xx status or times out, its entry has `isDelivered: false` and `status: "retrying"` (while attempts remain) or `"failed"` (once all attempts are exhausted), with details in `errorMessage`. `summary.failed`/`summary.errors` do not currently reflect HTTP-level failures; they only count a database error while creating the delivery record, so a URL that returns 4xx/5xx or times out through all attempts still increments `summary.successful` and leaves `summary.errors` empty. Inspect each `deliveries[]` entry's `isDelivered`, `status`, and `errorMessage` to detect a failing receiver rather than relying on `summary.failed`.
+
+## Common errors
+
+| Status | When | Response body |
+| ------ | ---- | ------------- |
+| 401 | Missing or invalid API key/token, or the organization cannot be resolved | Empty (status only) |
+| 403 | The key's role is not administrator | Empty (status only) |
+| 404 | No webhook with that name exists in your organization | `{ "error": "Webhook not found" }` |
+| 400 | The webhook exists but `isActive` is `false` | `{ "error": "Cannot test inactive webhook" }` |
+
+## Related endpoints
+
+- [Get Webhook](/docs/API/get-webhook) to confirm the webhook's URLs and events before testing
+- [List Webhook Deliveries](/docs/API/list-webhook-deliveries) to review this and past delivery attempts
+- [Replay Webhook Delivery](/docs/API/replay-webhook-delivery) to retry a specific failed delivery
+
diff --git a/docs/API/update-tag.api.mdx b/docs/API/update-tag.api.mdx
index 2ef7f7b..6829518 100644
--- a/docs/API/update-tag.api.mdx
+++ b/docs/API/update-tag.api.mdx
@@ -1,7 +1,7 @@
---
id: update-tag
title: "Update Tag"
-description: "Update Tag"
+description: "Rename an existing tag by ID. Includes example request, response, and error handling."
sidebar_label: "Update Tag"
hide_title: true
hide_table_of_contents: true
@@ -16,9 +16,53 @@ custom_edit_url: null
# Update Tag
-
- Update Tag
-
+
+The Update Tag endpoint changes a tag's `label`. It is a `PUT`, but in practice `label` is the only field you should send. `orgId` is not an accepted body field and returns a validation error if sent. `id` is different: it isn't rejected by validation, and it isn't ignored either; the endpoint applies whatever body you send, so an `id` that differs from the `TagId` in the URL will overwrite the tag's actual `id` instead of being discarded. Omit `id` from the body and let the URL path segment identify the tag to update.
+
+## When to use it
+
+Use this endpoint to rename a tag across your organization; every template or variable already tagged with it keeps the same tag `id`, so the rename applies everywhere the tag is used.
+
+## Example request
+
+```bash
+curl -X PUT "https://api.turbodocx.com/Tag/7c1a0b52-9e88-4f0d-b3a2-1d4c6f8e2a90" \
+ -H "Authorization: Bearer $TURBODOCX_API_KEY" \
+ -H "x-rapiddocx-org-id: $TURBODOCX_ORG_ID" \
+ -H "Content-Type: application/json" \
+ -d '{"label": "legal-2026"}'
+```
+
+## Example response
+
+On success the endpoint returns `200 OK` with the updated tag object directly (not wrapped in a `data` envelope, unlike most other TurboDocx endpoints):
+
+```json
+{
+ "id": "7c1a0b52-9e88-4f0d-b3a2-1d4c6f8e2a90",
+ "label": "legal-2026",
+ "isActive": true,
+ "orgId": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
+ "createdBy": "f5e6d7c8-9a0b-4c1d-2e3f-4a5b6c7d8e9f",
+ "createdOn": "2026-05-01T14:22:10.000Z",
+ "updatedOn": "2026-05-02T09:00:00.000Z"
+}
+```
+
+## Common errors
+
+| Status | When | Response body |
+| ------ | ---- | ------------- |
+| 401 | Missing or invalid API key/token, or the organization cannot be resolved | Empty (status only) |
+| 403 | The key's role is not administrator, contributor, or user | Empty (status only) |
+| 400 | `TagId` is not a valid UUID, or `label` fails validation | `{ "message", "type": "ValidationError", "data": { "errors": [...] } }` |
+
+## Related endpoints
+
+- [Read Tag](/docs/API/read-tag) to find the `TagId` to update
+- [Create Tag](/docs/API/create-tag) to add a new tag instead
+- [Delete Tags (by IDs)](/docs/API/delete-tags-by-i-ds) to remove tags in bulk
+
diff --git a/docs/API/update-variable-by-id.api.mdx b/docs/API/update-variable-by-id.api.mdx
index 217e2f9..5b786f9 100644
--- a/docs/API/update-variable-by-id.api.mdx
+++ b/docs/API/update-variable-by-id.api.mdx
@@ -1,7 +1,7 @@
---
id: update-variable-by-id
title: "Update Variable (by ID)"
-description: "Update Variable (by ID)"
+description: "Update a knowledge-base or folder variable's name, content, or tags by ID. Includes example request, response, and error handling."
sidebar_label: "Update Variable (by ID)"
hide_title: true
hide_table_of_contents: true
@@ -16,9 +16,66 @@ custom_edit_url: null
# Update Variable (by ID)
-
- Update Variable (by ID)
-
+
+The Update Variable (by ID) endpoint replaces a knowledge-base or template-folder variable's content and metadata. Unlike [Edit Template Metadata](/docs/API/edit-template-metadata), this is a full replace, not a partial patch: `mimeType` and `text` are required on every call. `isGlobal` and `templateFolderId` are both optional; at most one may be set.
+
+## When to use it
+
+Use this endpoint to edit a reusable variable you found with [Read Variables (Folder)](/docs/API/read-variables-folder), for example correcting its text, changing its name, or replacing its tag list.
+
+## Example request
+
+```bash
+curl -X PUT "https://api.turbodocx.com/Variable/e4f5a6b7-8c9d-4e0f-a1b2-3c4d5e6f7a8b" \
+ -H "Authorization: Bearer $TURBODOCX_API_KEY" \
+ -H "x-rapiddocx-org-id: $TURBODOCX_ORG_ID" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "name": "Company Address",
+ "placeholder": "{CompanyAddress}",
+ "mimeType": "text",
+ "text": "123 Main St, Suite 400, Austin, TX 78701",
+ "allowRichTextInjection": true,
+ "isGlobal": true,
+ "tags": []
+ }'
+```
+
+`{VariableId}` in the path is the `variableMapId` returned by [Read Variables (Folder)](/docs/API/read-variables-folder), not the underlying `Variable.id`. Optionally send `isGlobal: true` or `templateFolderId`, but not both; sending both is rejected. For an image variable, set `mimeType` to `"image"` and `text` to a base64 data string.
+
+## Example response
+
+On success the endpoint returns `200 OK` with the updated variable wrapped in a `variable` key (not the `data` envelope most other TurboDocx endpoints use):
+
+```json
+{
+ "variable": {
+ "id": "e4f5a6b7-8c9d-4e0f-a1b2-3c4d5e6f7a8b",
+ "name": "Company Address",
+ "placeholder": "{CompanyAddress}",
+ "mimeType": "text",
+ "text": "123 Main St, Suite 400, Austin, TX 78701",
+ "isGlobal": true,
+ "templateFolderId": null,
+ "updatedOn": "2026-05-02T09:00:00.000Z"
+ }
+}
+```
+
+## Common errors
+
+| Status | When | Response body |
+| ------ | ---- | ------------- |
+| 401 | Missing or invalid API key/token, or the organization cannot be resolved | Empty (status only) |
+| 403 | The key's role is not administrator, contributor, or user. For `isGlobal: true` updates (as in the example above), only administrator and contributor are allowed; the `user` role is also rejected with `403`. | Empty (status only) |
+| 400 | `mimeType` or `text` is missing, or both `isGlobal` and `templateFolderId` are set | `{ "message", "type": "ValidationError", "data": { "errors": [...] } }` |
+| 409 | The variable was deleted or modified by someone else before this update landed | `{ "error", "data": { "explanation" } }` |
+
+## Related endpoints
+
+- [Read Variables (Folder)](/docs/API/read-variables-folder) to find the `variableMapId` to update
+- [Delete Variables (by IDs)](/docs/API/delete-variables-by-i-ds) to remove variables instead of editing them
+
diff --git a/docs/API/update-webhook.api.mdx b/docs/API/update-webhook.api.mdx
index 6577d59..69b9731 100644
--- a/docs/API/update-webhook.api.mdx
+++ b/docs/API/update-webhook.api.mdx
@@ -1,7 +1,7 @@
---
id: update-webhook
title: "Update Webhook"
-description: "Patch one or more fields on the org's signature webhook. All fields are optional — supply only what you want to change."
+description: "Patch one or more fields on the org's signature webhook, changing only what you send: name, URLs, events, or active state."
sidebar_label: "Update Webhook"
hide_title: true
hide_table_of_contents: true
@@ -16,9 +16,68 @@ custom_edit_url: null
# Update Webhook
-
- Update Webhook
-
+
+The Update Webhook endpoint changes a webhook's URLs, subscribed events, name, or active state. Every field is optional; send only what you want to change, and the rest is left untouched.
+
+## When to use it
+
+Use this endpoint to rotate delivery URLs, add or remove subscribed event types, or temporarily pause delivery by setting `isActive` to `false` without deleting the webhook and losing its secret and delivery history.
+
+## Example request
+
+```bash
+curl -X PATCH "https://api.turbodocx.com/api/webhooks/signature" \
+ -H "Authorization: Bearer $TURBODOCX_API_KEY" \
+ -H "x-rapiddocx-org-id: $TURBODOCX_ORG_ID" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "urls": ["https://example.com/webhooks/turbodocx"],
+ "events": ["signature.document.completed"],
+ "isActive": true
+ }'
+```
+
+`urls` and `events` each replace the webhook's full list, they do not merge with the existing values. If you include `name`, it must still be unique among your organization's active webhooks.
+
+## Example response
+
+On success the endpoint returns `200 OK` with the updated webhook, in the same shape as [Get Webhook](/docs/API/get-webhook) (without `deliveryStats` or `availableEvents`):
+
+```json
+{
+ "data": {
+ "id": "b7e2c4a1-3f9d-4e6a-8c1b-5d0f7a2e9c34",
+ "orgId": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
+ "name": "signature",
+ "urls": ["https://example.com/webhooks/turbodocx"],
+ "events": ["signature.document.completed"],
+ "isActive": true,
+ "createdBy": "f5e6d7c8-9a0b-4c1d-2e3f-4a5b6c7d8e9f",
+ "createdOn": "2026-05-01T14:22:10.000Z",
+ "updatedOn": "2026-05-02T09:10:00.000Z",
+ "secretExists": true,
+ "maskedSecret": "whs***7f8"
+ },
+ "message": "Webhook updated successfully"
+}
+```
+
+## Common errors
+
+| Status | When | Response body |
+| ------ | ---- | ------------- |
+| 401 | Missing or invalid API key/token, or the organization cannot be resolved | Empty (status only) |
+| 403 | The key's role is not administrator | Empty (status only) |
+| 404 | No webhook with that name exists in your organization | `{ "error": "Webhook not found" }` |
+| 400 | A field fails validation, or a URL in `urls` is not HTTPS | `{ "message", "type": "ValidationError", "data": { "errors": [...] } }` |
+| 409 | Renaming to a name another active webhook already uses | `{ "message", "error": "WebhookNameTaken", "data": { "constraint", "orgId", "name" } }` |
+
+## Related endpoints
+
+- [Get Webhook](/docs/API/get-webhook) to view the current configuration before editing
+- [Regenerate Webhook Secret](/docs/API/regenerate-webhook-secret) to rotate the signing secret without changing anything else
+- [Delete Webhook](/docs/API/delete-webhook) to remove the webhook entirely
+