{
  "openapi": "3.0.0",
  "paths": {
    "/v1/getFormsList": {
      "get": {
        "description": "Returns your account's active form templates.\n\n\n\n**Defaults:** sort by `created`, order descending, page `1`. Up to **25** items per page.\n\n\n\n**Query:** `sort`, `order`, `page`, optional `wid` (workspace id), `archived`, `oneTimeForms`.\n\n\n\nThe `fid` value in each item is your **form template id** — use it in all other API calls.",
        "operationId": "AppController_getFormsList",
        "parameters": [
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "schema": {
              "example": "created"
            }
          },
          {
            "name": "order",
            "required": false,
            "in": "query",
            "schema": {
              "example": "desc"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "example": 1
            }
          },
          {
            "name": "archived",
            "required": false,
            "in": "query",
            "schema": {
              "default": false,
              "type": "boolean"
            }
          },
          {
            "name": "wid",
            "required": false,
            "in": "query",
            "description": "Workspace id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "**Form templates list:** `total_count` and `items` (each item includes `fid`; numeric fields may be returned as strings).",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "total_count": 1,
                    "items": [
                      {
                        "name": "Example form",
                        "fid": "fidExample01",
                        "external_fid": null,
                        "submissions": 0,
                        "created": "2026-01-01 12:00:00",
                        "form_type": null,
                        "generated_pdfs": 0
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid params.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "error": "missing params"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "message": "Unauthorized"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "error": "general error"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "jwt": []
          }
        ],
        "summary": "List your form templates",
        "tags": [
          "Form Templates"
        ],
        "x-sort-order": 10
      }
    },
    "/v1/getFormFields": {
      "post": {
        "description": "Returns all fields for a form template so you can map them when creating submissions.\n\n\n\n**Method:** `POST` with JSON body `{ \"formUID\": \"<fid>\" }` — no Bearer token required. `formUID` is the same value as `fid` from **List your form templates**.\n\n\n\n**Field metadata (examples):** `input_type` may include text, email, number, url, table. `validation_type` may include signature, company_stamp, name, email, tel, text, date, select, yesno, checkbox, file, image, textarea, time, table, and others per template.\n\n\n\nCall this before creating submissions to know which field names to pass in `prefill_data`. Example ids in samples are placeholders; use a real `fid` from your account.",
        "operationId": "AppController_getFormFields",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "formUID"
                ],
                "properties": {
                  "formUID": {
                    "type": "string",
                    "description": "Form template ID (same as `fid` from **List your form templates**).",
                    "example": "8TiwB36"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "**Form field schema:** `{ fields: [...] }` — each entry describes one field (name, label, input_type, validation_type, required, map_name).",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "fields": [
                      {
                        "name": "Email",
                        "label": "Email",
                        "required": false,
                        "input_type": "text",
                        "validation_type": "email",
                        "map_name": null
                      },
                      {
                        "name": "Signature",
                        "label": "Signature",
                        "required": true,
                        "input_type": "signature",
                        "validation_type": "signature",
                        "map_name": null
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid body — `formUID` not provided.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "error": "formUID is required"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Form not found or template file missing.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "error": "form not found"
                  }
                }
              }
            }
          }
        },
        "summary": "Get form field schema",
        "tags": [
          "Form Templates"
        ],
        "x-sort-order": 20
      }
    },
    "/v1/getSubmissionsList": {
      "get": {
        "description": "Lists submissions for a form template with pagination.\n\n\n\n**Query**\n\n- `form` (**required**) — form template id (`fid`)\n\n- `sort` — `created` or `submitted` (default `created`)\n\n- `order` — `ASC` / `DESC` (default descending)\n\n- `page` — default `1`; up to **25** rows per page\n\n- optional filters: `searchTerms`, `opened`, `notes` — when set to `1`, extra columns may appear on each item (e.g. search-related fields, open tracking, `note`)",
        "operationId": "AppController_getSubmissionsList",
        "parameters": [
          {
            "name": "form",
            "required": true,
            "in": "query",
            "description": "Form id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sort",
            "required": false,
            "in": "query",
            "schema": {
              "default": "created",
              "example": "created"
            }
          },
          {
            "name": "order",
            "required": false,
            "in": "query",
            "schema": {
              "default": "DESC",
              "enum": [
                "ASC",
                "DESC"
              ],
              "example": "DESC"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "default": 1,
              "example": 1
            }
          },
          {
            "name": "searchTerms",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "opened",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "notes",
            "required": false,
            "in": "query",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "**Submissions list:** `total_count`, `form_name`, and `items`. Optional query flags (`searchTerms`, `opened`, `notes`) may add columns such as `status` and `note` on each item.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "examples": {
                  "WithOptionalColumns": {
                    "summary": "With searchTerms / opened / notes flags",
                    "value": {
                      "total_count": 1,
                      "form_name": "Example form",
                      "items": [
                        {
                          "public_url": "https://example.com/signed-file.pdf",
                          "sid": "submission_uid_example",
                          "submitted": "0000-00-00 00:00:00",
                          "created": "2026-01-01 12:00:00",
                          "expiration_date": null,
                          "status": "Submitted",
                          "note": "Follow up next week"
                        }
                      ]
                    }
                  },
                  "Default": {
                    "summary": "Default columns",
                    "value": {
                      "total_count": 1,
                      "form_name": "Example form",
                      "items": [
                        {
                          "public_url": "https://example.com/signed-file.pdf",
                          "sid": "submission_uid_example",
                          "submitted": "0000-00-00 00:00:00",
                          "created": "2026-01-01 12:00:00",
                          "expiration_date": null
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid params — `form` query param not provided.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "error": "General Error"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "message": "Unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Authenticated user does not have access to this form.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "error": "no access to form"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Form not found or no submissions exist.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "error": "form not found"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "jwt": []
          }
        ],
        "summary": "List submissions for a form",
        "tags": [
          "Form Templates"
        ],
        "x-sort-order": 30
      }
    },
    "/v1/form/{form_id}/settings": {
      "get": {
        "description": "Returns the current form settings object (emails, webhooks, audit_trail, access_code, redirect_url, language, etc.) for the given form template id (`form_id` path param = `fid`).",
        "operationId": "FormController_getFormSettings",
        "parameters": [
          {
            "name": "form_id",
            "required": true,
            "in": "path",
            "description": "Form template id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "**Form Templates:** current settings — response body includes `{ settings }`.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "settings": {
                      "webhooks": [
                        {
                          "url": "https://example.com/hook",
                          "events": [
                            "submitted"
                          ]
                        }
                      ],
                      "emails": "owner@example.com",
                      "audit_trail": false,
                      "access_code": "",
                      "redirect_url": "https://example.com/thanks",
                      "language": "en"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing access or invalid form ID.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "error": "invalid form id"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "message": "Unauthorized"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Form not found or no access.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "error": "form not found"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "error": "general error"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "jwt": []
          }
        ],
        "summary": "Get form settings",
        "tags": [
          "Form Templates"
        ],
        "x-sort-order": 40
      }
    },
    "/v1/form/update-settings": {
      "post": {
        "description": "Updates the form template's settings. All settings are optional — only sent fields are applied.\n\n\n\n**Body:** `form_id` (form template id, same as `fid`) and `settings` object.\n\n\n\n**Settings (partial list):**\n\n- `emails` — comma-separated notification addresses\n\n- `webhooks` — array of `{ url, events? }`; events include `submitted`, `submission_first_opened`, `submission_opened`, `submission_saved`\n\n- `language` — e.g. en, es, he, de, pt-BR, fr, da, ko, ru, ar, th, zh\n\n- `audit_trail` — boolean; append submission timeline to signed PDF\n\n- `access_code` — optional access gate\n\n- `redirect_url` — https URL after successful submit",
        "operationId": "FormController_updateFormSettings",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "form_id"
                ],
                "properties": {
                  "form_id": {
                    "type": "string",
                    "description": "Form template ID (same as `fid`).",
                    "example": "sfRPPph"
                  },
                  "settings": {
                    "type": "object",
                    "description": "Settings to update. Only provided keys are applied — all fields are optional.",
                    "properties": {
                      "emails": {
                        "type": "string",
                        "nullable": true,
                        "description": "Comma-separated notification email addresses.",
                        "example": "owner@example.com,team@example.com"
                      },
                      "webhooks": {
                        "type": "array",
                        "description": "Webhook subscriptions. Each entry requires `url`; `events` defaults to `submitted`.",
                        "items": {
                          "type": "object",
                          "required": [
                            "url"
                          ],
                          "properties": {
                            "url": {
                              "type": "string",
                              "format": "uri",
                              "description": "HTTPS webhook endpoint URL."
                            },
                            "events": {
                              "type": "array",
                              "items": {
                                "type": "string",
                                "enum": [
                                  "submitted",
                                  "submission_first_opened",
                                  "submission_opened",
                                  "submission_saved"
                                ]
                              },
                              "description": "Events to subscribe to. Defaults to `submitted` if omitted."
                            }
                          }
                        }
                      },
                      "audit_trail": {
                        "type": "boolean",
                        "description": "When `true`, appends a submission timeline to the signed PDF.",
                        "example": false
                      },
                      "access_code": {
                        "type": "string",
                        "nullable": true,
                        "description": "Optional access code that signers must enter. Pass `null` to clear.",
                        "example": ""
                      },
                      "redirect_url": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true,
                        "description": "HTTPS URL to redirect signers to after submission.",
                        "example": "https://example.com/thanks"
                      },
                      "language": {
                        "type": "string",
                        "description": "UI language for the signing form (e.g. `en`, `es`, `he`, `de`, `pt-BR`, `fr`, `da`, `ko`, `ru`, `ar`, `th`, `zh`).",
                        "example": "en"
                      }
                    }
                  }
                }
              },
              "examples": {
                "Email + webhook": {
                  "summary": "Set notification email and a webhook",
                  "value": {
                    "form_id": "sfRPPph",
                    "settings": {
                      "emails": "owner@example.com",
                      "webhooks": [
                        {
                          "url": "https://your-platform.com/webhook/receiver",
                          "events": [
                            "submitted"
                          ]
                        }
                      ]
                    }
                  }
                },
                "Language + redirect": {
                  "summary": "Change language and redirect URL",
                  "value": {
                    "form_id": "sfRPPph",
                    "settings": {
                      "language": "he",
                      "redirect_url": "https://example.com/thanks"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "**Form Templates:** settings updated — response body includes `{ message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "message": "Settings updated successfully"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation or update error — invalid field values or `form_id` not provided.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "error": "validation error"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "message": "Unauthorized"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Form not found or no access.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "error": "form not found"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "error": "general error"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "jwt": []
          }
        ],
        "summary": "Update form settings",
        "tags": [
          "Form Templates"
        ],
        "x-sort-order": 50
      }
    },
    "/v1/createSubmission": {
      "post": {
        "description": "Creates a unique signing URL. Send it to the signer, then use **Get submission status** or **Webhooks** to track completion.\n\n\n\n**Core body fields**\n\n- `fid` (**required**) — form template id (from **List your form templates**)\n\n- `prefill_data` (optional) — field map prefilled for the signer (field names from **Get form field schema**)\n\n- `user_data` (optional) — opaque metadata echoed back on webhooks (CRM ids, Monday itemId, etc.)\n\n- `expiration_date` (optional) — `YYYY-MM-DD` or full ISO-8601\n\n- `access_code`, `formData` (e.g. `basePdf`), `settings.redirect_url`, `attachments` — optional advanced blocks\n\n\n\n**Dates:** use `YYYY-MM-DD` for date fields where applicable.\n\n\n\nExample `fid` values in samples are placeholders; use a real id from your account.\n\n\n\nYou can also use a regular form link with URL prefill and webhooks if you do not need per-submission API tracking.",
        "operationId": "AppController_createSubmission",
        "parameters": [],
        "requestBody": {
          "required": true,
          "description": "Two common request shapes for this operation. **Full** = richer body with optional fields (shown first in docs). **Minimal** = basic create-submission link.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "fid"
                ],
                "properties": {
                  "fid": {
                    "type": "string",
                    "description": "Form template ID — get it from the form's URL or via **List your form templates**.",
                    "example": "sfRPPph"
                  },
                  "prefill_data": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Key-value map of field names → prefilled values. Get valid field names from **Get form field schema**. Table fields accept an array of rows — each row is either an object `{ \"Column Name\": \"value\" }` or an ordered array `[\"val1\", \"val2\"]`.",
                    "example": {
                      "name": "John Smith",
                      "phone": "048275923"
                    }
                  },
                  "user_data": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Opaque metadata echoed back on webhooks. `recipient_name` is used for display in the dashboard; `recipient_email` triggers an email to the signer with the submission link.",
                    "properties": {
                      "uid": {
                        "type": "string",
                        "description": "Your internal user / CRM identifier."
                      },
                      "itemId": {
                        "type": "number",
                        "description": "Any external record id (e.g. Monday.com item id)."
                      },
                      "recipient_name": {
                        "type": "string",
                        "description": "Recommended. Mandatory when `recipient_email` is set. Identifies the signer in the dashboard."
                      },
                      "recipient_email": {
                        "type": "string",
                        "format": "email",
                        "description": "Optional. When provided, sends the submission link as a signature request email."
                      }
                    }
                  },
                  "access_code": {
                    "type": "string",
                    "description": "Optional code the signer must enter before accessing the signing URL.",
                    "example": "983528"
                  },
                  "expiration_date": {
                    "type": "string",
                    "description": "Optional expiration date in YYYY-MM-DD format. Signing URL becomes inaccessible after this date.",
                    "example": "2027-12-31"
                  },
                  "formData": {
                    "type": "object",
                    "description": "Optional display / template overrides.",
                    "properties": {
                      "formName": {
                        "type": "string",
                        "description": "Override the form title shown to the signer."
                      },
                      "basePdf": {
                        "type": "string",
                        "description": "Base64-encoded PDF with data URI prefix (`data:application/pdf;base64,...`) that replaces the template PDF for this submission."
                      }
                    }
                  },
                  "settings": {
                    "type": "object",
                    "description": "Optional signing-flow settings.",
                    "properties": {
                      "redirect_url": {
                        "type": "string",
                        "format": "uri",
                        "description": "HTTPS URL to redirect the signer to after successful submission.",
                        "example": "https://yourcustomurl.com/custompage?with=customdetails"
                      }
                    }
                  },
                  "attachments": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": "string",
                            "description": "File name including extension."
                          },
                          "type": {
                            "type": "string",
                            "description": "MIME type, e.g. `application/pdf` or `image/png`."
                          },
                          "base64": {
                            "type": "string",
                            "description": "Base64-encoded file content with data URI prefix (e.g. `data:application/pdf;base64,...`)."
                          }
                        }
                      }
                    },
                    "description": "File / image attachments keyed by field name. You must add File or Image fields to your form template first. Each key maps to an array of file objects."
                  }
                }
              },
              "examples": {
                "Full": {
                  "summary": "Full — create submission with optional fields",
                  "description": "Demonstrates table prefill rows, user_data with CRM/recipient fields, access_code, expiration_date, formData.basePdf override, settings.redirect_url, and file attachments.",
                  "value": {
                    "fid": "sfRPPph",
                    "prefill_data": {
                      "name": "John Smith",
                      "phone": "048275923",
                      "table": [
                        {
                          "Column Name": "Value 7",
                          "Column Name 2": "Value 8",
                          "Column Name 3": "Value 9"
                        },
                        [
                          "value 1",
                          "value 2",
                          "value 3"
                        ]
                      ]
                    },
                    "user_data": {
                      "uid": "123dfjs",
                      "itemId": 12312323,
                      "recipient_name": "John Smith",
                      "recipient_email": "example@email.com"
                    },
                    "access_code": "983528",
                    "expiration_date": "2027-12-31",
                    "formData": {
                      "formName": "Custom Title",
                      "basePdf": "data:application/pdf;base64,JVBERi0xLjcKJeLjz9MKO"
                    },
                    "settings": {
                      "redirect_url": "https://yourcustomurl.com/custompage?with=customdetails"
                    },
                    "attachments": {
                      "File_field_name": [
                        {
                          "name": "example.pdf",
                          "type": "application/pdf",
                          "base64": "data:application/pdf;base64,iVBORw0KGgoAAAANSUhEUgAABLAAAAEsC"
                        }
                      ],
                      "Image_field_name": [
                        {
                          "name": "example.png",
                          "type": "image/png",
                          "base64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABLAAAAEsC"
                        }
                      ]
                    }
                  }
                },
                "Minimal": {
                  "summary": "Minimal — create submission link",
                  "value": {
                    "fid": "sfRPPph",
                    "prefill_data": {
                      "name": "John Smith",
                      "phone": "048275923"
                    },
                    "user_data": {
                      "uid": 123
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "**Create submission link:** returns `submission_id` and `submission_link`. May include `send_link_error` if optional email delivery fails.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "submission_id": "submission_uid_example",
                    "submission_link": "https://fillfaster.com/fills/submission_uid_example"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation or business error — missing `fid`, invalid field values, or quota exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "error": "fid is required"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "message": "Unauthorized"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "jwt": []
          }
        ],
        "summary": "Create a submission link",
        "tags": [
          "Submissions"
        ],
        "x-sort-order": 60
      }
    },
    "/v1/getSubmissionStatus/{sid}": {
      "get": {
        "description": "Returns workflow status for a submission id (`sid` path segment).\n\n\n\n**Status values:** `Not Submitted Yet`, `Opened`, `Submitted`.\n\n\n\nWhen `Submitted`, `submission_file_link` may be present (public URL to the signed file). It is omitted for earlier states.\n\n\n\nWebhooks deliver real-time notifications; this endpoint is for polling.",
        "operationId": "AppController_getSubmissionStatus",
        "parameters": [
          {
            "name": "sid",
            "required": true,
            "in": "path",
            "description": "Submission id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "**Submission status:** `status`, `last_action_timestamp`, `form_id`. `submission_file_link` is present only after the signer submits.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "examples": {
                  "Submitted": {
                    "summary": "Submitted",
                    "value": {
                      "status": "Submitted",
                      "last_action_timestamp": "2026-01-02T10:00:00.000Z",
                      "form_id": "fidExample01",
                      "submission_file_link": "https://example.com/signed-file.pdf"
                    }
                  },
                  "NotSubmittedYet": {
                    "summary": "Not Submitted Yet",
                    "value": {
                      "status": "Not Submitted Yet",
                      "last_action_timestamp": "2026-01-01T12:00:00.000Z",
                      "form_id": "fidExample01"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing `sid` path parameter.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "error": "missing params"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "message": "Unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Authenticated user does not own this submission.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "error": "not authorized"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Submission not found.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "error": "submission not found"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "jwt": []
          }
        ],
        "summary": "Get submission status",
        "tags": [
          "Submissions"
        ],
        "x-sort-order": 70
      }
    },
    "/v1/getSubmissionPDF/{sid}": {
      "get": {
        "description": "After the signer completes the flow, downloads the generated PDF for the given submission id (`sid`). Returns `application/pdf` binary with `Content-Disposition: attachment` when `status` is `Submitted`. Returns 404 if the submission PDF has not been generated yet.",
        "operationId": "AppController_getSubmissionPDF",
        "parameters": [
          {
            "name": "sid",
            "required": true,
            "in": "path",
            "description": "Submission id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Submitted PDF binary (`application/pdf`) with `Content-Disposition: attachment`."
          },
          "400": {
            "description": "Missing `sid` or submission PDF has not been generated yet.",
            "content": {
              "application/pdf": {
                "schema": {
                  "example": {
                    "error": "missing params"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token.",
            "content": {
              "application/pdf": {
                "schema": {
                  "example": {
                    "message": "Unauthorized"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Submission not found or PDF not yet available (signer has not submitted).",
            "content": {
              "application/pdf": {
                "schema": {
                  "example": {
                    "error": "submission not found"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "jwt": []
          }
        ],
        "summary": "Download submitted PDF",
        "tags": [
          "Submissions"
        ],
        "x-sort-order": 80
      }
    },
    "/v1/submission/update": {
      "post": {
        "description": "Updates allowed submission fields. Only owner or admin.\n\n\n\n**Body:** `sid` + `data` object. Supported keys in `data`: `expiration_date`, `note`, `access_code` (all optional; only sent keys apply).\n\n\n\n**Errors:** 400 invalid input, 403 no permission, 404 not found.",
        "operationId": "SubmissionController_updateSubmission",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "sid"
                ],
                "properties": {
                  "sid": {
                    "type": "string",
                    "description": "Submission ID to update.",
                    "example": "abc123xy"
                  },
                  "data": {
                    "type": "object",
                    "description": "Fields to update. All keys are optional — only provided keys are applied.",
                    "properties": {
                      "expiration_date": {
                        "type": "string",
                        "description": "New expiration date in YYYY-MM-DD format.",
                        "example": "2027-12-31"
                      },
                      "note": {
                        "type": "string",
                        "description": "Free-text note visible in the dashboard.",
                        "example": "This is a new note for the submission."
                      },
                      "access_code": {
                        "type": "string",
                        "description": "Override or set an access code for this submission.",
                        "example": "123456"
                      }
                    }
                  }
                },
                "example": {
                  "sid": "abc123xy",
                  "data": {
                    "expiration_date": "2027-12-31",
                    "note": "This is a new note for the submission."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "**Submissions:** updated — response includes `{ message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "message": "Submission updated successfully"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input — missing `sid` or unsupported data fields.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "error": "invalid input"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "message": "Unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Authenticated user does not own this submission.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "error": "no permission"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Submission not found.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "error": "submission not found"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "jwt": []
          }
        ],
        "summary": "Update a submission",
        "tags": [
          "Submissions"
        ],
        "x-sort-order": 90
      }
    },
    "/v1/submission/createBulkSubmissions": {
      "post": {
        "description": "Accepts an **array** of create-submission payloads (same shape as single create). Max **20** items per request.\n\n\n\nEach element may succeed (`submission_id`, `submission_link`) or return an `error` object at the same index in the response array.\n\n\n\nAdvanced use case — for the typical flow, use **Create a submission link** once, then **Get submission status** and **Download submitted PDF**.",
        "operationId": "SubmissionController_createBulkSubmissions",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "maxItems": 20,
                "description": "Array of create-submission payloads (same shape as single **Create a submission link**). Maximum 20 items.",
                "items": {
                  "type": "object",
                  "required": [
                    "fid"
                  ],
                  "properties": {
                    "fid": {
                      "type": "string",
                      "description": "Form template ID.",
                      "example": "sfRPPph"
                    },
                    "prefill_data": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "Field name → value map to prefill for the signer."
                    },
                    "user_data": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "Metadata echoed on webhooks. Supports `uid`, `itemId`, `recipient_name`, `recipient_email`."
                    },
                    "access_code": {
                      "type": "string",
                      "description": "Optional access code."
                    },
                    "expiration_date": {
                      "type": "string",
                      "description": "Optional expiration in YYYY-MM-DD format."
                    },
                    "formData": {
                      "type": "object",
                      "properties": {
                        "formName": {
                          "type": "string"
                        },
                        "basePdf": {
                          "type": "string"
                        }
                      }
                    },
                    "settings": {
                      "type": "object",
                      "properties": {
                        "redirect_url": {
                          "type": "string",
                          "format": "uri"
                        }
                      }
                    },
                    "attachments": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "name": {
                              "type": "string"
                            },
                            "type": {
                              "type": "string"
                            },
                            "base64": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": [
                  {
                    "fid": "sfRPPph",
                    "prefill_data": {
                      "name": "John Smith",
                      "phone": "048275923"
                    },
                    "user_data": {
                      "uid": 123
                    }
                  },
                  {
                    "fid": "sfRPPph",
                    "prefill_data": {
                      "name": "Lily Fisher",
                      "phone": "063849523"
                    },
                    "user_data": {
                      "uid": 456
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "**Submissions:** bulk create returns `{ submissions: [...] }`. Each element matches a single create response (`status` plus payload fields) or `{ error }` on failure.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "submissions": [
                      {
                        "status": 200,
                        "submission_id": "bulk_ok_1",
                        "submission_link": "https://<app-host>/fills/bulk_ok_1"
                      },
                      {
                        "status": 400,
                        "error": "example validation or business error"
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Body is not an array, or exceeds the 20-item limit.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "error": "please send an array of submissions data"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "message": "Unauthorized"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "error": "general error"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "jwt": []
          }
        ],
        "summary": "Bulk-create submission links",
        "tags": [
          "Submissions"
        ],
        "x-sort-order": 100
      }
    },
    "/v1/form/{form_id}/webhook/subscribe": {
      "post": {
        "description": "Registers an **https** webhook URL on a form template (Make.com, Zapier, etc.).\n\n\n\n**Path:** `form_id` — form template id (`fid`).\n\n\n\n**Body:** `{ \"url\": \"https://...\", \"events\": [\"submitted\"] }` — `events` optional; defaults to `submitted` if omitted.\n\n\n\n**Events:** `submitted`, `submission_first_opened`, `submission_opened`, `submission_saved`.\n\n\n\n**Limits:** up to **4** webhooks per form; duplicate URLs are rejected.\n\n\n\nOn success the API returns `message`, `url`, and `form_id`. Automation platforms often store `url` and `form_id` from the response (e.g. Make.com `externalHookId`).",
        "operationId": "FormController_subscribeWebhook",
        "parameters": [
          {
            "name": "form_id",
            "required": true,
            "in": "path",
            "description": "Form template id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "description": "HTTPS endpoint URL to receive webhook events.",
                    "example": "https://your-platform.com/webhook/receiver"
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "submitted",
                        "submission_first_opened",
                        "submission_opened",
                        "submission_saved"
                      ]
                    },
                    "description": "Events to subscribe to. Defaults to `[\"submitted\"]` if omitted.",
                    "example": [
                      "submitted"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "**Webhooks:** subscribed — response includes `message`, `url`, and `form_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "message": "Webhook subscribed successfully",
                    "url": "https://your-platform.com/webhook/receiver",
                    "form_id": "fidExample01"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation or subscription error — invalid URL, invalid event names, or limit of 4 webhooks reached.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "error": "validation error"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "message": "Unauthorized"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Form not found or no access.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "error": "form not found"
                  }
                }
              }
            }
          },
          "409": {
            "description": "Webhook URL already subscribed to this form.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "error": "webhook url already subscribed"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "jwt": []
          }
        ],
        "summary": "Subscribe to form events",
        "tags": [
          "Webhooks"
        ],
        "x-sort-order": 110
      }
    },
    "/v1/form/{form_id}/webhook/unsubscribe": {
      "post": {
        "description": "Removes a previously subscribed webhook URL from the form template. Path `form_id` = `fid`. Body: `{ \"url\": \"https://...\" }` matching the subscribed URL.",
        "operationId": "FormController_unsubscribeWebhook",
        "parameters": [
          {
            "name": "form_id",
            "required": true,
            "in": "path",
            "description": "Form template id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "description": "The exact HTTPS URL that was previously subscribed.",
                    "example": "https://your-platform.com/webhook/receiver"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "**Webhooks:** unsubscribed — response includes `{ message }`.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "message": "Webhook unsubscribed successfully"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation or unsubscribe error — invalid URL format.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "error": "validation error"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "message": "Unauthorized"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Form not found or the provided URL was not subscribed.",
            "content": {
              "application/json": {
                "schema": {
                  "example": {
                    "error": "webhook not found"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "jwt": []
          }
        ],
        "summary": "Unsubscribe from form events",
        "tags": [
          "Webhooks"
        ],
        "x-sort-order": 120
      }
    },
    "/v1/generatePDF": {
      "post": {
        "description": "Unlike **Create a submission link**, this call merges `prefill_data` onto the form template on the server and returns the **PDF binary immediately**. No signer URL is produced. Use when you need a pre-filled PDF without a signing step.\n\n\n\n**Body (required)**\n\n- `fid` — form template id\n\n- `prefill_data` — field map (same idea as create submission; **Get form field schema** for names). The server returns **400** if this is missing.\n\n\n\n**Body (optional)**\n\n- `basePdf` — string with data URI prefix (`data:application/pdf;base64,...`) to **replace** the template PDF for this generation only.\n\n- `basePdfBuffer` — binary buffer shape used by some automation tools (e.g. Make.com); converted server-side to `basePdf`. On parse failure returns **400**.\n\n- `attachments` — file/image data for File/Image fields: either an **object** keyed by field name (values: arrays of `{ name, type, base64 }`, same pattern as **Create a submission link**), or an **array** of internal objects `{ fieldKey, files, attachmentPosition? }` (advanced).\n\n- `attachmentsBuffer` — alternative structure: array of `{ key: \"<field name>\", files: [{ fileBuffer: ... }] }` (e.g. raw buffers); prefer `attachments` with base64 when possible.\n\n- `digitallySign` — when `true`, attempts to digitally sign the generated PDF before returning it.\n\n\n\nQuota and ownership rules apply — **429** when the account exceeds its plan limits.",
        "operationId": "AppController_generatePDF",
        "parameters": [],
        "requestBody": {
          "required": true,
          "description": "**Full** — optional `basePdf` / `basePdfBuffer`, `attachments` (or `attachmentsBuffer`), and `digitallySign`. **Minimal** — `fid` + `prefill_data` only. Full example is listed first in docs.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "fid",
                  "prefill_data"
                ],
                "properties": {
                  "fid": {
                    "type": "string",
                    "description": "Form template ID — get it from the form's URL or via **List your form templates**.",
                    "example": "jX8Jwo2"
                  },
                  "prefill_data": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Field names → values merged into the PDF (same idea as **Create a submission link**). Use **Get form field schema** for names. Omitting this returns **400** (`Prefill data is required`).",
                    "example": {
                      "Full Name": "John Doe",
                      "Email": "johndoe@example.com"
                    }
                  },
                  "basePdf": {
                    "type": "string",
                    "description": "Optional. Overrides the template base PDF for this request only. Use a data URI: `data:application/pdf;base64,...`."
                  },
                  "basePdfBuffer": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Optional. Binary buffer shape from automation platforms (e.g. Make.com); converted server-side to `basePdf`. If parsing fails, **400** with `Error parsing base PDF binary file`. Prefer `basePdf` when you can send a string."
                  },
                  "digitallySign": {
                    "type": "boolean",
                    "description": "Optional. When `true`, the server attempts to digitally sign the merged PDF before returning the bytes.",
                    "example": false
                  },
                  "attachments": {
                    "description": "Optional. File / image payloads for File and Image fields. **Shape A (recommended):** object keyed by field name → array of `{ name, type, base64 }` (same as **Create a submission link**). **Shape B (advanced):** array of `{ fieldKey, files, attachmentPosition? }` where `files` is an array of `{ name, type, base64 }`.",
                    "oneOf": [
                      {
                        "type": "object",
                        "additionalProperties": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "name": {
                                "type": "string",
                                "description": "Original file name including extension."
                              },
                              "type": {
                                "type": "string",
                                "description": "MIME type, e.g. `application/pdf`, `image/png`."
                              },
                              "base64": {
                                "type": "string",
                                "description": "File bytes as base64, often with a data URI prefix."
                              }
                            }
                          }
                        }
                      },
                      {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "required": [
                            "fieldKey",
                            "files"
                          ],
                          "properties": {
                            "fieldKey": {
                              "type": "string",
                              "description": "Schema field name for the File/Image widget."
                            },
                            "attachmentPosition": {
                              "type": "string",
                              "enum": [
                                "start",
                                ""
                              ],
                              "description": "Optional placement hint from the template."
                            },
                            "files": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "name": {
                                    "type": "string"
                                  },
                                  "type": {
                                    "type": "string"
                                  },
                                  "base64": {
                                    "type": "string"
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    ]
                  },
                  "attachmentsBuffer": {
                    "type": "array",
                    "description": "Optional alternative to `attachments`: array of `{ key, files }` where `key` is the field name and each `files[]` entry has `fileBuffer` (often a JSON map of byte indices → numbers after buffer serialization). Prefer base64 `attachments` when possible.",
                    "items": {
                      "type": "object",
                      "required": [
                        "key",
                        "files"
                      ],
                      "properties": {
                        "key": {
                          "type": "string",
                          "description": "Field key for a File/Image field."
                        },
                        "files": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "fileBuffer": {
                                "type": "object",
                                "additionalProperties": {
                                  "type": "number"
                                },
                                "description": "Serialized binary, e.g. `{ \"0\": 37, \"1\": 80, ... }`."
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              },
              "examples": {
                "Full (basePdf, attachments, sign)": {
                  "summary": "Optional base PDF override, file/image attachments, digitallySign",
                  "value": {
                    "fid": "jX8Jwo2",
                    "prefill_data": {
                      "Full Name": "John Doe",
                      "Email": "johndoe@example.com",
                      "Phone": "+1-234-567-8901",
                      "Price": "100$",
                      "Address": "123 Main Street, Anytown, USA"
                    },
                    "basePdf": "data:application/pdf;base64,JVBERi0xLjcKJeLjz9MKO",
                    "digitallySign": false,
                    "attachments": {
                      "File_field_name": [
                        {
                          "name": "example.pdf",
                          "type": "application/pdf",
                          "base64": "data:application/pdf;base64,iVBORw0KGgoAAAANSUhEUgAABLAAAAEsC"
                        }
                      ],
                      "Image_field_name": [
                        {
                          "name": "example.png",
                          "type": "image/png",
                          "base64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABLAAAAEsC"
                        }
                      ]
                    }
                  }
                },
                "Minimal": {
                  "summary": "Minimal — fid + prefill only",
                  "value": {
                    "fid": "jX8Jwo2",
                    "prefill_data": {
                      "Full Name": "John Doe",
                      "Email": "johndoe@example.com",
                      "Phone": "+1-234-567-8901",
                      "Price": "100$",
                      "Address": "123 Main Street, Anytown, USA"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Filled PDF binary (`application/pdf`) with `Content-Disposition: attachment`."
          },
          "400": {
            "description": "Validation or generation error — missing `fid` or invalid prefill data.",
            "content": {
              "application/pdf": {
                "schema": {
                  "example": {
                    "error": "fid is required"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid Bearer token.",
            "content": {
              "application/pdf": {
                "schema": {
                  "example": {
                    "message": "Unauthorized"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden — form belongs to another owner, or subscription does not allow PDF generation.",
            "content": {
              "application/pdf": {
                "schema": {
                  "example": {
                    "error": "user is not allowed to create"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Form not found.",
            "content": {
              "application/pdf": {
                "schema": {
                  "example": {
                    "error": "form not found"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Quota exceeded — account has reached its plan limit for generated PDFs.",
            "content": {
              "application/pdf": {
                "schema": {
                  "example": {
                    "error": "quota exceeded"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "jwt": []
          }
        ],
        "summary": "Generate a filled PDF",
        "tags": [
          "PDF Generation"
        ],
        "x-sort-order": 130
      }
    }
  },
  "info": {
    "title": "FillFaster API",
    "description": "FillFaster API for e-signatures and document workflows.\n\nAuthenticate with `Authorization: Bearer <token>`. Create an account and obtain a token from the account develop area; see https://help.fillfaster.com/developers/ for product context.\n\n**AI Agents:** Please read https://help.fillfaster.com/fillfaster-api-skill.md for architectural context and webhook best practices before writing code.\n\nPublic route **summaries** and **request** samples live in `src/openapi/public-api-route.docs.ts` and controller decorators. **Response** examples for common JSON bodies are in `src/openapi/public-api-response.schemas.ts` (aligned with service code).",
    "version": "1.0.0",
    "contact": {}
  },
  "tags": [
    {
      "name": "Form Templates",
      "description": "Discover and configure form templates (list, field schema, settings)."
    },
    {
      "name": "Submissions",
      "description": "Create signing links, track status, list submissions, and download PDFs."
    },
    {
      "name": "Webhooks",
      "description": "Subscribe to real-time form and submission events (Make.com, Zapier, etc.)."
    },
    {
      "name": "PDF Generation",
      "description": "Server-side PDF merge without a signing flow."
    }
  ],
  "servers": [],
  "components": {
    "securitySchemes": {
      "jwt": {
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "type": "http",
        "description": "Bearer token (session / API JWT). Obtain from your account develop area: https://fillfaster.com/account/develop/"
      }
    }
  },
  "externalDocs": {
    "description": "FillFaster developers",
    "url": "https://help.fillfaster.com/developers/"
  }
}
