{
  "openapi": "3.1.0",
  "info": {
    "title": "Validature API",
    "version": "1.0",
    "description": "API access, including OAuth, is part of the Business Pro plan. On other plans, every call returns `409` with the message `commercial_feature_unavailable`.",
    "contact": {
      "email": "contact@validature.com"
    }
  },
  "servers": [
    {
      "url": "https://validature.app/api/v1"
    }
  ],
  "tags": [
    {
      "name": "OAuth 2.0",
      "description": "Validature uses the OAuth 2.0 authorization code grant. Clients are registered by Validature: contact us to receive a client ID and secret for your integration."
    },
    {
      "name": "Account",
      "description": ""
    },
    {
      "name": "Contacts",
      "description": "The address book of the connected user. Owners and administrators see the whole organization's contacts; other members see their own."
    },
    {
      "name": "Templates",
      "description": "Reusable documents with signature fields and recipient roles. A role is either fixed (its recipient is stored in the template, and can be overridden) or variable (you provide the recipient when sending)."
    },
    {
      "name": "Signature requests",
      "description": "A signature request sends documents to recipients (signers, approvers, observers). Its `status` is one of: `draft`, `prepared`, `sent`, `ongoing`, `completed`, `declined`, `expired`, `canceled`. A request past its deadline is reported `expired`, and one a recipient declined is reported `declined`. Owners and administrators access every request of the organization; other members access the requests they created. Zero-access (Vault) requests are created in the Validature app only, because their documents are encrypted in the sender's browser: the API reports their status and recipients, with the title `Document sécurisé` and no documents."
    },
    {
      "name": "Signed files",
      "description": "Downloads of a completed request. Zero-access (Vault) documents stay encrypted and cannot be downloaded through the API."
    },
    {
      "name": "Webhooks",
      "description": "Subscribe a URL to receive events as they happen. Subscriptions belong to the connected user: they receive the events of the contacts and requests this user can access, and stop when the user loses access."
    }
  ],
  "paths": {
    "/oauth/authorize": {
      "get": {
        "operationId": "authorize",
        "tags": [
          "OAuth 2.0"
        ],
        "summary": "Ask the user for access",
        "description": "Redirect the user's browser here. Validature signs the user in if needed, shows a consent screen listing the requested permissions, then redirects to `redirect_uri` with `code` and `state` (or `error=access_denied`).",
        "parameters": [
          {
            "name": "response_type",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "code"
              ],
              "description": "Must be `code`."
            }
          },
          {
            "name": "client_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Your client ID."
            }
          },
          {
            "name": "redirect_uri",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "One of the redirect URIs registered for your client."
            }
          },
          {
            "name": "state",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Opaque value returned unchanged; use it to prevent CSRF."
            }
          },
          {
            "name": "scope",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Space-separated scopes. Defaults to the scopes allowed for your client."
            }
          },
          {
            "name": "code_challenge",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "PKCE challenge (optional for confidential clients)."
            }
          },
          {
            "name": "code_challenge_method",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "S256"
              ],
              "description": "`S256` when `code_challenge` is sent."
            }
          }
        ],
        "security": [],
        "responses": {
          "302": {
            "description": "Redirect to `redirect_uri?code=…&state=…`. The code expires after a few minutes and can be used once."
          }
        }
      }
    },
    "/oauth/token": {
      "post": {
        "operationId": "token",
        "tags": [
          "OAuth 2.0"
        ],
        "summary": "Get or refresh an access token",
        "description": "Exchange an authorization code, or a refresh token, for an access token. Authenticate the client with HTTP Basic (`client_secret_basic`) or with `client_id` and `client_secret` in the body (`client_secret_post`). Access tokens are short-lived: read `expires_in` and refresh before it runs out, or when a call returns 401. Refresh tokens are long-lived and rotate: each refresh returns a new refresh token and invalidates the previous one; reusing an old one revokes the whole chain.",
        "parameters": [],
        "security": [
          {
            "clientBasic": []
          },
          {}
        ],
        "responses": {
          "200": {
            "description": "Tokens issued.",
            "content": {
              "application/json": {
                "example": {
                  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…",
                  "token_type": "Bearer",
                  "expires_in": 3600,
                  "refresh_token": "vrt_2b9c…",
                  "scope": "contacts:read contacts:write requests:read requests:write documents:read webhooks:manage"
                }
              }
            }
          },
          "400": {
            "description": "`invalid_grant` (expired, used or revoked code or refresh token) or `invalid_request`.",
            "content": {
              "application/json": {
                "example": {
                  "error": "invalid_grant",
                  "error_description": "Refresh token revoked"
                }
              }
            }
          },
          "401": {
            "description": "`invalid_client`: unknown client or wrong secret.",
            "content": {
              "application/json": {
                "example": {
                  "error": "invalid_client"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "grant_type"
                ],
                "properties": {
                  "grant_type": {
                    "type": "string",
                    "enum": [
                      "authorization_code",
                      "refresh_token"
                    ],
                    "description": "`authorization_code` or `refresh_token`."
                  },
                  "code": {
                    "type": "string",
                    "description": "The authorization code (authorization_code grant)."
                  },
                  "redirect_uri": {
                    "type": "string",
                    "description": "The same `redirect_uri` as in the authorization request (authorization_code grant)."
                  },
                  "refresh_token": {
                    "type": "string",
                    "description": "The refresh token (refresh_token grant)."
                  },
                  "client_id": {
                    "type": "string",
                    "description": "Your client ID, unless sent with HTTP Basic."
                  },
                  "client_secret": {
                    "type": "string",
                    "description": "Your client secret, unless sent with HTTP Basic."
                  },
                  "code_verifier": {
                    "type": "string",
                    "description": "PKCE verifier, when a `code_challenge` was sent."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/oauth/revoke": {
      "post": {
        "operationId": "revoke",
        "tags": [
          "OAuth 2.0"
        ],
        "summary": "Revoke a token",
        "description": "Revoke a refresh token (and the access it grants). Authenticate the client as for `/oauth/token`.",
        "parameters": [],
        "security": [
          {
            "clientBasic": []
          },
          {}
        ],
        "responses": {
          "200": {
            "description": "Revoked (also returned for unknown tokens).",
            "content": {
              "application/json": {
                "example": {
                  "revoked": true
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "token"
                ],
                "properties": {
                  "token": {
                    "type": "string",
                    "description": "The token to revoke."
                  },
                  "token_type_hint": {
                    "type": "string",
                    "description": "`refresh_token` or `access_token`."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/oauth/.well-known/oauth-authorization-server": {
      "get": {
        "operationId": "metadata",
        "tags": [
          "OAuth 2.0"
        ],
        "summary": "Authorization server metadata",
        "description": "RFC 8414 metadata: endpoints, supported grants, scopes and client authentication methods.",
        "parameters": [],
        "security": [],
        "responses": {
          "200": {
            "description": "Metadata document."
          }
        }
      }
    },
    "/auth/me": {
      "get": {
        "operationId": "me",
        "tags": [
          "Account"
        ],
        "summary": "Get the connected user",
        "description": "Returns the user the access token acts for. Use it to test a connection and to label it.",
        "parameters": [],
        "security": [
          {
            "oauth2": []
          }
        ],
        "responses": {
          "200": {
            "description": "The user.",
            "content": {
              "application/json": {
                "example": {
                  "id": "daa9e01b-c7ef-4dde-b72e-b001c3646f32",
                  "email": "olivia.owner@example.com",
                  "firstName": "Olivia",
                  "lastName": "Owner",
                  "phone": null,
                  "language": "en",
                  "role": "owner",
                  "organizationId": "b7e1d2c3-4a5b-4c6d-8e9f-0a1b2c3d4e5f"
                }
              }
            }
          }
        }
      }
    },
    "/contacts": {
      "get": {
        "operationId": "list-contacts",
        "tags": [
          "Contacts"
        ],
        "summary": "List or search contacts",
        "description": "Returns contacts matching `search` (name or email), 100 at most per page. Entries whose `id` starts with `user:` are members of the organization and cannot be edited.",
        "parameters": [
          {
            "name": "search",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Text to find in the name or email (100 characters max)."
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Page size, 1 to 100 (default 100)."
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Number of contacts to skip, 0 to 10,000 (default 0)."
            }
          }
        ],
        "security": [
          {
            "oauth2": [
              "contacts:read"
            ]
          }
        ],
        "responses": {
          "200": {
            "description": "A page of contacts.",
            "content": {
              "application/json": {
                "example": {
                  "data": [
                    {
                      "id": "4c6e8a0b-2d4f-4e6a-8c0e-2a4c6e8a0c2e",
                      "firstName": "Camille",
                      "lastName": "Martin",
                      "email": "camille.martin@example.com",
                      "phone": "+33 6 12 34 56 78",
                      "language": "fr",
                      "createdAt": "2026-09-24T10:30:00.000Z",
                      "updatedAt": "2026-09-24T10:30:00.000Z"
                    }
                  ],
                  "total": 1,
                  "limit": 100,
                  "offset": 0,
                  "hasMore": false
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "create-contact",
        "tags": [
          "Contacts"
        ],
        "summary": "Create or update a contact",
        "description": "Creates a contact, or updates the contact that already uses this email address. Fields you omit are left unchanged.",
        "parameters": [],
        "security": [
          {
            "oauth2": [
              "contacts:write"
            ]
          }
        ],
        "responses": {
          "201": {
            "description": "The contact, created or updated.",
            "content": {
              "application/json": {
                "example": {
                  "id": "4c6e8a0b-2d4f-4e6a-8c0e-2a4c6e8a0c2e",
                  "firstName": "Camille",
                  "lastName": "Martin",
                  "email": "camille.martin@example.com",
                  "phone": null,
                  "language": "fr",
                  "createdAt": "2026-09-24T10:30:00.000Z",
                  "updatedAt": "2026-09-24T10:30:00.000Z"
                }
              }
            }
          },
          "409": {
            "description": "`contact_email_unavailable`: the email belongs to a contact you cannot access."
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "email"
                ],
                "properties": {
                  "email": {
                    "type": "string",
                    "description": "Email address (254 characters max)."
                  },
                  "firstName": {
                    "type": "string",
                    "description": "First name (100 characters max)."
                  },
                  "lastName": {
                    "type": "string",
                    "description": "Last name (100 characters max)."
                  },
                  "phone": {
                    "type": "string",
                    "description": "Phone number in international format, for example `+33 6 12 34 56 78`."
                  },
                  "language": {
                    "type": "string",
                    "description": "Preferred language for emails, for example `fr` or `en`."
                  }
                }
              },
              "example": {
                "email": "camille.martin@example.com",
                "firstName": "Camille",
                "lastName": "Martin",
                "language": "fr"
              }
            }
          }
        }
      }
    },
    "/zapier/templates": {
      "get": {
        "operationId": "list-templates",
        "tags": [
          "Templates"
        ],
        "summary": "List templates",
        "description": "Returns the templates the connected user can use, optionally filtered by name.",
        "parameters": [
          {
            "name": "search",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Text to find in the template name."
            }
          }
        ],
        "security": [
          {
            "oauth2": [
              "requests:read"
            ]
          }
        ],
        "responses": {
          "200": {
            "description": "Templates.",
            "content": {
              "application/json": {
                "example": [
                  {
                    "id": "3f8a2c1d-7e6b-4d5c-9a8b-1c2d3e4f5a6b",
                    "name": "Employment contract",
                    "description": "Standard employment contract",
                    "signingOrder": "sequential",
                    "createdAt": "2026-09-01T08:00:00.000Z",
                    "updatedAt": "2026-09-20T08:00:00.000Z",
                    "recipients": [
                      {
                        "roleKey": "hr",
                        "label": "HR manager",
                        "role": "signer",
                        "fixed": true,
                        "email": "hr@example.com",
                        "firstName": "Hana",
                        "lastName": "Rossi",
                        "phone": null,
                        "language": "en"
                      },
                      {
                        "roleKey": "employee",
                        "label": "Employee",
                        "role": "signer",
                        "fixed": false,
                        "email": null,
                        "firstName": null,
                        "lastName": null,
                        "phone": null,
                        "language": null
                      }
                    ]
                  }
                ]
              }
            }
          }
        }
      }
    },
    "/zapier/templates/{templateId}": {
      "get": {
        "operationId": "get-template",
        "tags": [
          "Templates"
        ],
        "summary": "Get a template and its recipient roles",
        "parameters": [
          {
            "name": "templateId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Template identifier."
            }
          }
        ],
        "security": [
          {
            "oauth2": [
              "requests:read"
            ]
          }
        ],
        "responses": {
          "200": {
            "description": "The template.",
            "content": {
              "application/json": {
                "example": {
                  "id": "3f8a2c1d-7e6b-4d5c-9a8b-1c2d3e4f5a6b",
                  "name": "Employment contract",
                  "description": "Standard employment contract",
                  "signingOrder": "sequential",
                  "createdAt": "2026-09-01T08:00:00.000Z",
                  "updatedAt": "2026-09-20T08:00:00.000Z",
                  "recipients": [
                    {
                      "roleKey": "hr",
                      "label": "HR manager",
                      "role": "signer",
                      "fixed": true,
                      "email": "hr@example.com",
                      "firstName": "Hana",
                      "lastName": "Rossi",
                      "phone": null,
                      "language": "en"
                    },
                    {
                      "roleKey": "employee",
                      "label": "Employee",
                      "role": "signer",
                      "fixed": false,
                      "email": null,
                      "firstName": null,
                      "lastName": null,
                      "phone": null,
                      "language": null
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/zapier/signature-requests/from-template": {
      "post": {
        "operationId": "create-from-template",
        "tags": [
          "Signature requests"
        ],
        "summary": "Create a signature request from a template",
        "description": "Creates a request from a template, fills its recipient roles and sends it (or keeps it as a draft with `send: false`). Each role needs an email address; variable roles also need a first and last name. Two recipients cannot share an email address.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Optional. Repeat the same key to retry safely: the request is performed once."
            }
          }
        ],
        "security": [
          {
            "oauth2": [
              "requests:write"
            ]
          }
        ],
        "responses": {
          "201": {
            "description": "The signature request. `dispatch` is `queued` when sending has started, `draft` otherwise.",
            "content": {
              "application/json": {
                "example": {
                  "id": "5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d",
                  "title": "Service agreement - Acme",
                  "status": "sent",
                  "externalId": "deal-1042",
                  "signatureLevel": "SES",
                  "signingOrder": "parallel",
                  "createdAt": "2026-09-23T16:20:00.000Z",
                  "sentAt": "2026-09-23T16:25:00.000Z",
                  "completedAt": null,
                  "expiresAt": "2026-10-23T21:59:59.999Z",
                  "url": "https://validature.app/requests/5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d",
                  "senderEmail": "olivia.owner@example.com",
                  "senderName": "Olivia Owner",
                  "recipients": [
                    {
                      "id": "9d2f4b6a-1c3e-4a5b-8d7f-2e4c6a8b0d1f",
                      "email": "camille.martin@example.com",
                      "firstName": "Camille",
                      "lastName": "Martin",
                      "role": "signer",
                      "status": "signed",
                      "order": 1,
                      "notifiedAt": "2026-09-23T16:25:00.000Z",
                      "viewedAt": "2026-09-24T09:12:00.000Z",
                      "signedAt": "2026-09-24T09:15:00.000Z",
                      "declinedAt": null,
                      "declineReason": null
                    },
                    {
                      "id": "1e3a5c7d-9b2f-4d6e-8a1c-3e5f7a9b1d2c",
                      "email": "lea.dubois@example.com",
                      "firstName": "Léa",
                      "lastName": "Dubois",
                      "role": "signer",
                      "status": "notified",
                      "order": 2,
                      "notifiedAt": "2026-09-23T16:25:00.000Z",
                      "viewedAt": null,
                      "signedAt": null,
                      "declinedAt": null,
                      "declineReason": null
                    }
                  ],
                  "documents": [
                    {
                      "id": "8c1d2e3f-4a5b-4c6d-9e8f-7a6b5c4d3e2f",
                      "name": "service-agreement.pdf",
                      "version": "original"
                    }
                  ],
                  "dispatch": "queued"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input, for example `zapier_template_recipient_incomplete` or `zapier_template_recipient_duplicate_email`.",
            "content": {
              "application/json": {
                "example": {
                  "statusCode": 400,
                  "error": "Bad Request",
                  "code": "zapier_template_recipient_incomplete",
                  "message": "Add the email address, first name and last name of \"Employee\"."
                }
              }
            }
          },
          "409": {
            "description": "The `externalId` is already used by another request (`zapier_external_reference_taken`). Nothing was created or sent.",
            "content": {
              "application/json": {
                "example": {
                  "statusCode": 409,
                  "error": "Conflict",
                  "code": "zapier_external_reference_taken",
                  "message": "This external reference is already used by another signature request. Use a unique reference, or leave it empty.",
                  "timestamp": "2026-09-24T10:30:00.000Z",
                  "requestId": "6fd4f8a7-cebe-48c8-a726-c3ce89cae49a"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "templateId",
                  "recipients"
                ],
                "properties": {
                  "templateId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Template to use."
                  },
                  "recipients": {
                    "type": "array",
                    "items": {
                      "type": "object"
                    },
                    "description": "One entry per role you fill: `roleKey` (required), `email`, `firstName`, `lastName`, `phone`, `language`. Fixed roles you omit keep the recipient stored in the template."
                  },
                  "title": {
                    "type": "string",
                    "description": "Request title (255 characters max). Defaults to the template name."
                  },
                  "message": {
                    "type": "string",
                    "description": "Message shown to recipients (5,000 characters max)."
                  },
                  "emailSubject": {
                    "type": "string",
                    "description": "Subject of the invitation email."
                  },
                  "signatureLevel": {
                    "type": "string",
                    "enum": [
                      "SES",
                      "AES"
                    ],
                    "description": "`SES` (simple) or `AES` (advanced, with identity verification)."
                  },
                  "signingOrder": {
                    "type": "string",
                    "enum": [
                      "parallel",
                      "sequential"
                    ],
                    "description": "`parallel` or `sequential`."
                  },
                  "expirationDays": {
                    "type": "integer",
                    "description": "Days before the request expires, 1 to 365."
                  },
                  "reminderFrequency": {
                    "type": "string",
                    "enum": [
                      "daily",
                      "weekly",
                      "monthly"
                    ],
                    "description": "Automatic reminders: `daily`, `weekly` or `monthly`."
                  },
                  "reminderMaxCount": {
                    "type": "integer",
                    "description": "Maximum number of automatic reminders, 0 to 12."
                  },
                  "securityCodeType": {
                    "type": "string",
                    "enum": [
                      "none",
                      "email",
                      "sms"
                    ],
                    "description": "One-time code before signing: `none`, `email` or `sms`."
                  },
                  "ccEmails": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Email addresses that receive a copy of the signed documents (50 max)."
                  },
                  "externalId": {
                    "type": "string",
                    "description": "Your own reference for the request, for example a CRM deal ID (255 characters max). It must be unique: it also becomes the request reference shown in Validature."
                  },
                  "send": {
                    "type": "boolean",
                    "description": "`true` (default) sends the request now; `false` keeps it as a draft."
                  }
                }
              },
              "example": {
                "templateId": "3f8a2c1d-7e6b-4d5c-9a8b-1c2d3e4f5a6b",
                "recipients": [
                  {
                    "roleKey": "employee",
                    "email": "camille.martin@example.com",
                    "firstName": "Camille",
                    "lastName": "Martin"
                  }
                ],
                "title": "Employment contract - Camille Martin",
                "externalId": "hire-208",
                "send": true
              }
            }
          }
        }
      }
    },
    "/zapier/signature-requests": {
      "get": {
        "operationId": "search-requests",
        "tags": [
          "Signature requests"
        ],
        "summary": "Find signature requests",
        "description": "Returns the most recent requests matching every criterion given, newest first.",
        "parameters": [
          {
            "name": "externalId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Your reference, exact match."
            }
          },
          {
            "name": "recipientEmail",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "A recipient's email address (case-insensitive)."
            }
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Text to find in the title."
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "draft",
                "prepared",
                "sent",
                "ongoing",
                "completed",
                "declined",
                "expired",
                "canceled"
              ],
              "description": "Only requests in this status."
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "1 to 100 (default 10)."
            }
          }
        ],
        "security": [
          {
            "oauth2": [
              "requests:read"
            ]
          }
        ],
        "responses": {
          "200": {
            "description": "Signature requests.",
            "content": {
              "application/json": {
                "example": [
                  {
                    "id": "5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d",
                    "title": "Service agreement - Acme",
                    "status": "ongoing",
                    "externalId": "deal-1042",
                    "signatureLevel": "SES",
                    "signingOrder": "parallel",
                    "createdAt": "2026-09-23T16:20:00.000Z",
                    "sentAt": "2026-09-23T16:25:00.000Z",
                    "completedAt": null,
                    "expiresAt": "2026-10-23T21:59:59.999Z",
                    "url": "https://validature.app/requests/5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d",
                    "senderEmail": "olivia.owner@example.com",
                    "senderName": "Olivia Owner",
                    "recipients": [
                      {
                        "id": "9d2f4b6a-1c3e-4a5b-8d7f-2e4c6a8b0d1f",
                        "email": "camille.martin@example.com",
                        "firstName": "Camille",
                        "lastName": "Martin",
                        "role": "signer",
                        "status": "signed",
                        "order": 1,
                        "notifiedAt": "2026-09-23T16:25:00.000Z",
                        "viewedAt": "2026-09-24T09:12:00.000Z",
                        "signedAt": "2026-09-24T09:15:00.000Z",
                        "declinedAt": null,
                        "declineReason": null
                      },
                      {
                        "id": "1e3a5c7d-9b2f-4d6e-8a1c-3e5f7a9b1d2c",
                        "email": "lea.dubois@example.com",
                        "firstName": "Léa",
                        "lastName": "Dubois",
                        "role": "signer",
                        "status": "notified",
                        "order": 2,
                        "notifiedAt": "2026-09-23T16:25:00.000Z",
                        "viewedAt": null,
                        "signedAt": null,
                        "declinedAt": null,
                        "declineReason": null
                      }
                    ],
                    "documents": [
                      {
                        "id": "8c1d2e3f-4a5b-4c6d-9e8f-7a6b5c4d3e2f",
                        "name": "service-agreement.pdf",
                        "version": "original"
                      }
                    ]
                  }
                ]
              }
            }
          }
        }
      }
    },
    "/zapier/signature-requests/{requestId}": {
      "get": {
        "operationId": "get-request",
        "tags": [
          "Signature requests"
        ],
        "summary": "Get a signature request",
        "parameters": [
          {
            "name": "requestId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Signature request identifier."
            }
          }
        ],
        "security": [
          {
            "oauth2": [
              "requests:read"
            ]
          }
        ],
        "responses": {
          "200": {
            "description": "The signature request.",
            "content": {
              "application/json": {
                "example": {
                  "id": "5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d",
                  "title": "Service agreement - Acme",
                  "status": "ongoing",
                  "externalId": "deal-1042",
                  "signatureLevel": "SES",
                  "signingOrder": "parallel",
                  "createdAt": "2026-09-23T16:20:00.000Z",
                  "sentAt": "2026-09-23T16:25:00.000Z",
                  "completedAt": null,
                  "expiresAt": "2026-10-23T21:59:59.999Z",
                  "url": "https://validature.app/requests/5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d",
                  "senderEmail": "olivia.owner@example.com",
                  "senderName": "Olivia Owner",
                  "recipients": [
                    {
                      "id": "9d2f4b6a-1c3e-4a5b-8d7f-2e4c6a8b0d1f",
                      "email": "camille.martin@example.com",
                      "firstName": "Camille",
                      "lastName": "Martin",
                      "role": "signer",
                      "status": "signed",
                      "order": 1,
                      "notifiedAt": "2026-09-23T16:25:00.000Z",
                      "viewedAt": "2026-09-24T09:12:00.000Z",
                      "signedAt": "2026-09-24T09:15:00.000Z",
                      "declinedAt": null,
                      "declineReason": null
                    },
                    {
                      "id": "1e3a5c7d-9b2f-4d6e-8a1c-3e5f7a9b1d2c",
                      "email": "lea.dubois@example.com",
                      "firstName": "Léa",
                      "lastName": "Dubois",
                      "role": "signer",
                      "status": "notified",
                      "order": 2,
                      "notifiedAt": "2026-09-23T16:25:00.000Z",
                      "viewedAt": null,
                      "signedAt": null,
                      "declinedAt": null,
                      "declineReason": null
                    }
                  ],
                  "documents": [
                    {
                      "id": "8c1d2e3f-4a5b-4c6d-9e8f-7a6b5c4d3e2f",
                      "name": "service-agreement.pdf",
                      "version": "original"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/zapier/signature-requests/{requestId}/send": {
      "post": {
        "operationId": "send-draft",
        "tags": [
          "Signature requests"
        ],
        "summary": "Send a draft",
        "description": "Sends a request created as a draft. Fails with 409 if the request is no longer a draft.",
        "parameters": [
          {
            "name": "requestId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Signature request identifier."
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Optional. Repeat the same key to retry safely: the request is performed once."
            }
          }
        ],
        "security": [
          {
            "oauth2": [
              "requests:write"
            ]
          }
        ],
        "responses": {
          "201": {
            "description": "The signature request, now sent.",
            "content": {
              "application/json": {
                "example": {
                  "id": "5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d",
                  "title": "Service agreement - Acme",
                  "status": "sent",
                  "externalId": "deal-1042",
                  "signatureLevel": "SES",
                  "signingOrder": "parallel",
                  "createdAt": "2026-09-23T16:20:00.000Z",
                  "sentAt": "2026-09-23T16:25:00.000Z",
                  "completedAt": null,
                  "expiresAt": "2026-10-23T21:59:59.999Z",
                  "url": "https://validature.app/requests/5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d",
                  "senderEmail": "olivia.owner@example.com",
                  "senderName": "Olivia Owner",
                  "recipients": [
                    {
                      "id": "9d2f4b6a-1c3e-4a5b-8d7f-2e4c6a8b0d1f",
                      "email": "camille.martin@example.com",
                      "firstName": "Camille",
                      "lastName": "Martin",
                      "role": "signer",
                      "status": "signed",
                      "order": 1,
                      "notifiedAt": "2026-09-23T16:25:00.000Z",
                      "viewedAt": "2026-09-24T09:12:00.000Z",
                      "signedAt": "2026-09-24T09:15:00.000Z",
                      "declinedAt": null,
                      "declineReason": null
                    },
                    {
                      "id": "1e3a5c7d-9b2f-4d6e-8a1c-3e5f7a9b1d2c",
                      "email": "lea.dubois@example.com",
                      "firstName": "Léa",
                      "lastName": "Dubois",
                      "role": "signer",
                      "status": "notified",
                      "order": 2,
                      "notifiedAt": "2026-09-23T16:25:00.000Z",
                      "viewedAt": null,
                      "signedAt": null,
                      "declinedAt": null,
                      "declineReason": null
                    }
                  ],
                  "documents": [
                    {
                      "id": "8c1d2e3f-4a5b-4c6d-9e8f-7a6b5c4d3e2f",
                      "name": "service-agreement.pdf",
                      "version": "original"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/zapier/signature-requests/{requestId}/remind": {
      "post": {
        "operationId": "remind",
        "tags": [
          "Signature requests"
        ],
        "summary": "Remind recipients",
        "description": "Sends a reminder to every recipient who still has to sign or approve. Recipients who could not be reminded are listed in `skipped` with a reason. Fails with 409 when nobody is waiting (`zapier_reminder_nobody_waiting`) or when no reminder could be sent (`zapier_reminder_not_sent`).",
        "parameters": [
          {
            "name": "requestId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Signature request identifier."
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Optional. Repeat the same key to retry safely: the request is performed once."
            }
          }
        ],
        "security": [
          {
            "oauth2": [
              "requests:write"
            ]
          }
        ],
        "responses": {
          "201": {
            "description": "Who was reminded.",
            "content": {
              "application/json": {
                "example": {
                  "requestId": "5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d",
                  "reminded": [
                    {
                      "recipientId": "1e3a5c7d-9b2f-4d6e-8a1c-3e5f7a9b1d2c",
                      "email": "lea.dubois@example.com",
                      "status": "queued"
                    }
                  ],
                  "skipped": []
                }
              }
            }
          }
        }
      }
    },
    "/zapier/signature-requests/{requestId}/cancel": {
      "post": {
        "operationId": "cancel",
        "tags": [
          "Signature requests"
        ],
        "summary": "Cancel a signature request",
        "description": "Cancels the request; recipients can no longer sign it.",
        "parameters": [
          {
            "name": "requestId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Signature request identifier."
            }
          }
        ],
        "security": [
          {
            "oauth2": [
              "requests:write"
            ]
          }
        ],
        "responses": {
          "201": {
            "description": "The signature request, canceled.",
            "content": {
              "application/json": {
                "example": {
                  "id": "5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d",
                  "title": "Service agreement - Acme",
                  "status": "canceled",
                  "externalId": "deal-1042",
                  "signatureLevel": "SES",
                  "signingOrder": "parallel",
                  "createdAt": "2026-09-23T16:20:00.000Z",
                  "sentAt": "2026-09-23T16:25:00.000Z",
                  "completedAt": null,
                  "expiresAt": "2026-10-23T21:59:59.999Z",
                  "url": "https://validature.app/requests/5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d",
                  "senderEmail": "olivia.owner@example.com",
                  "senderName": "Olivia Owner",
                  "recipients": [
                    {
                      "id": "9d2f4b6a-1c3e-4a5b-8d7f-2e4c6a8b0d1f",
                      "email": "camille.martin@example.com",
                      "firstName": "Camille",
                      "lastName": "Martin",
                      "role": "signer",
                      "status": "signed",
                      "order": 1,
                      "notifiedAt": "2026-09-23T16:25:00.000Z",
                      "viewedAt": "2026-09-24T09:12:00.000Z",
                      "signedAt": "2026-09-24T09:15:00.000Z",
                      "declinedAt": null,
                      "declineReason": null
                    },
                    {
                      "id": "1e3a5c7d-9b2f-4d6e-8a1c-3e5f7a9b1d2c",
                      "email": "lea.dubois@example.com",
                      "firstName": "Léa",
                      "lastName": "Dubois",
                      "role": "signer",
                      "status": "notified",
                      "order": 2,
                      "notifiedAt": "2026-09-23T16:25:00.000Z",
                      "viewedAt": null,
                      "signedAt": null,
                      "declinedAt": null,
                      "declineReason": null
                    }
                  ],
                  "documents": [
                    {
                      "id": "8c1d2e3f-4a5b-4c6d-9e8f-7a6b5c4d3e2f",
                      "name": "service-agreement.pdf",
                      "version": "original"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/requests/{requestId}/download-bundle": {
      "get": {
        "operationId": "download-bundle",
        "tags": [
          "Signed files"
        ],
        "summary": "Download the signed package",
        "description": "A ZIP archive with the signed documents and the signature certificate. Available once the request is completed.",
        "parameters": [
          {
            "name": "requestId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Signature request identifier."
            }
          }
        ],
        "security": [
          {
            "oauth2": [
              "requests:read"
            ]
          }
        ],
        "responses": {
          "200": {
            "description": "`application/zip` file."
          },
          "400": {
            "description": "The request is not completed."
          }
        }
      }
    },
    "/requests/{requestId}/documents/{documentId}/download": {
      "get": {
        "operationId": "download-document",
        "tags": [
          "Signed files"
        ],
        "summary": "Download one document",
        "description": "The signed version once the request is completed (see `documents[].version`).",
        "parameters": [
          {
            "name": "requestId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Signature request identifier."
            }
          },
          {
            "name": "documentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Document identifier, from `documents[].id`."
            }
          }
        ],
        "security": [
          {
            "oauth2": [
              "requests:read"
            ]
          }
        ],
        "responses": {
          "200": {
            "description": "The file, usually `application/pdf`."
          }
        }
      }
    },
    "/requests/{requestId}/certificate": {
      "get": {
        "operationId": "download-certificate",
        "tags": [
          "Signed files"
        ],
        "summary": "Download the signature certificate",
        "description": "The PDF audit trail: recipients, authentication, timestamps and events.",
        "parameters": [
          {
            "name": "requestId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Signature request identifier."
            }
          },
          {
            "name": "download",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Set to `1` to receive the file as an attachment."
            }
          }
        ],
        "security": [
          {
            "oauth2": [
              "requests:read"
            ]
          }
        ],
        "responses": {
          "200": {
            "description": "`application/pdf` file."
          }
        }
      }
    },
    "/zapier/hooks/{hook}/subscribe": {
      "post": {
        "operationId": "subscribe",
        "tags": [
          "Webhooks"
        ],
        "summary": "Subscribe to an event",
        "description": "Validature will POST each new event to `targetUrl`. Subscribing the same URL again reactivates it.\n\nScopes: Plus the scopes of the event (see Events).",
        "parameters": [
          {
            "name": "hook",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "contact-created",
                "signer-done",
                "request-done",
                "request-sent",
                "request-status-changed",
                "signer-viewed",
                "signer-declined",
                "request-canceled",
                "request-expired"
              ],
              "description": "The event to subscribe to (see Events)."
            }
          }
        ],
        "security": [
          {
            "oauth2": [
              "webhooks:manage"
            ]
          }
        ],
        "responses": {
          "201": {
            "description": "The subscription.",
            "content": {
              "application/json": {
                "example": {
                  "id": "0b6e1c2d-3f4a-4b5c-8d9e-0f1a2b3c4d5e",
                  "event": "request.sent",
                  "targetUrl": "https://hooks.example.com/validature/7d1f…",
                  "active": true
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "targetUrl"
                ],
                "properties": {
                  "targetUrl": {
                    "type": "string",
                    "description": "Public HTTPS URL that receives the events."
                  }
                }
              },
              "example": {
                "targetUrl": "https://hooks.example.com/validature/7d1f…"
              }
            }
          }
        }
      }
    },
    "/zapier/hooks/{hook}/unsubscribe": {
      "post": {
        "operationId": "unsubscribe",
        "tags": [
          "Webhooks"
        ],
        "summary": "Unsubscribe",
        "description": "Scopes: Plus the scopes of the event (see Events).",
        "parameters": [
          {
            "name": "hook",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "contact-created",
                "signer-done",
                "request-done",
                "request-sent",
                "request-status-changed",
                "signer-viewed",
                "signer-declined",
                "request-canceled",
                "request-expired"
              ],
              "description": "The event to subscribe to (see Events)."
            }
          }
        ],
        "security": [
          {
            "oauth2": [
              "webhooks:manage"
            ]
          }
        ],
        "responses": {
          "201": {
            "description": "Done (also returned when no such subscription exists).",
            "content": {
              "application/json": {
                "example": {
                  "unsubscribed": true
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "targetUrl"
                ],
                "properties": {
                  "targetUrl": {
                    "type": "string",
                    "description": "The URL given when subscribing."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/zapier/hooks/{hook}/poll": {
      "get": {
        "operationId": "poll",
        "tags": [
          "Webhooks"
        ],
        "summary": "List recent events",
        "description": "Returns the most recent events of this type, newest first, in the same shape as the webhook payloads. Use it to backfill or to test an integration.\n\nScopes: The scopes of the event (see Events).",
        "parameters": [
          {
            "name": "hook",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "contact-created",
                "signer-done",
                "request-done",
                "request-sent",
                "request-status-changed",
                "signer-viewed",
                "signer-declined",
                "request-canceled",
                "request-expired"
              ],
              "description": "The event to subscribe to (see Events)."
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "1 to 100 (default 20)."
            }
          },
          {
            "name": "createdAfter",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only events after this time. The parameter depends on the event: `createdAfter` for `contact-created`, `signedAfter` for `signer-done`, `completedAfter` for `request-done`, `occurredAfter` for the others."
            }
          },
          {
            "name": "signedAfter",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only events after this time. The parameter depends on the event: `createdAfter` for `contact-created`, `signedAfter` for `signer-done`, `completedAfter` for `request-done`, `occurredAfter` for the others."
            }
          },
          {
            "name": "completedAfter",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only events after this time. The parameter depends on the event: `createdAfter` for `contact-created`, `signedAfter` for `signer-done`, `completedAfter` for `request-done`, `occurredAfter` for the others."
            }
          },
          {
            "name": "occurredAfter",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only events after this time. The parameter depends on the event: `createdAfter` for `contact-created`, `signedAfter` for `signer-done`, `completedAfter` for `request-done`, `occurredAfter` for the others."
            }
          },
          {
            "name": "statuses",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "`request-status-changed` only: comma-separated transitions to keep (`sent`, `completed`, `declined`, `canceled`, `expired`)."
            }
          }
        ],
        "security": [
          {
            "oauth2": []
          }
        ],
        "responses": {
          "200": {
            "description": "Events.",
            "content": {
              "application/json": {
                "example": [
                  {
                    "id": "5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d",
                    "eventType": "request.sent",
                    "occurredAt": "2026-09-24T10:30:00.000Z",
                    "eventStatus": "sent",
                    "requestId": "5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d",
                    "organizationId": "b7e1d2c3-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
                    "title": "Service agreement - Acme",
                    "status": "sent",
                    "externalId": "deal-1042",
                    "signatureLevel": "SES",
                    "signingOrder": "parallel",
                    "createdAt": "2026-09-23T16:20:00.000Z",
                    "sentAt": "2026-09-23T16:25:00.000Z",
                    "completedAt": null,
                    "expiresAt": "2026-10-23T21:59:59.999Z",
                    "url": "https://validature.app/requests/5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d",
                    "senderEmail": "olivia.owner@example.com",
                    "senderName": "Olivia Owner",
                    "recipients": [
                      {
                        "id": "9d2f4b6a-1c3e-4a5b-8d7f-2e4c6a8b0d1f",
                        "email": "camille.martin@example.com",
                        "firstName": "Camille",
                        "lastName": "Martin",
                        "role": "signer",
                        "status": "signed",
                        "order": 1,
                        "notifiedAt": "2026-09-23T16:25:00.000Z",
                        "viewedAt": "2026-09-24T09:12:00.000Z",
                        "signedAt": "2026-09-24T09:15:00.000Z",
                        "declinedAt": null,
                        "declineReason": null
                      },
                      {
                        "id": "1e3a5c7d-9b2f-4d6e-8a1c-3e5f7a9b1d2c",
                        "email": "lea.dubois@example.com",
                        "firstName": "Léa",
                        "lastName": "Dubois",
                        "role": "signer",
                        "status": "notified",
                        "order": 2,
                        "notifiedAt": "2026-09-23T16:25:00.000Z",
                        "viewedAt": null,
                        "signedAt": null,
                        "declinedAt": null,
                        "declineReason": null
                      }
                    ]
                  }
                ]
              }
            }
          }
        }
      }
    }
  },
  "webhooks": {
    "contact.created": {
      "post": {
        "summary": "A contact is added to the address book of the connected user.",
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "id": "4c6e8a0b-2d4f-4e6a-8c0e-2a4c6e8a0c2e",
                "eventType": "contact.created",
                "occurredAt": "2026-09-24T10:30:00.000Z",
                "contactId": "4c6e8a0b-2d4f-4e6a-8c0e-2a4c6e8a0c2e",
                "organizationId": "b7e1d2c3-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
                "firstName": "Camille",
                "lastName": "Martin",
                "email": "camille.martin@example.com",
                "phone": "+33 6 12 34 56 78",
                "language": "fr",
                "createdAt": "2026-09-24T10:30:00.000Z",
                "updatedAt": "2026-09-24T10:30:00.000Z"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Any 2xx acknowledges the event."
          }
        }
      }
    },
    "participant.signed": {
      "post": {
        "summary": "A recipient signs a signature request. Not sent for zero-access (Vault) requests.",
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "id": "9d2f4b6a-1c3e-4a5b-8d7f-2e4c6a8b0d1f",
                "eventType": "participant.signed",
                "occurredAt": "2026-09-24T09:15:00.000Z",
                "participantId": "9d2f4b6a-1c3e-4a5b-8d7f-2e4c6a8b0d1f",
                "requestId": "5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d",
                "requestTitle": "Service agreement - Acme",
                "organizationId": "b7e1d2c3-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
                "role": "signer",
                "email": "camille.martin@example.com",
                "firstName": "Camille",
                "lastName": "Martin",
                "signedAt": "2026-09-24T09:15:00.000Z",
                "requestStatus": "ongoing",
                "requestCompletedAt": null,
                "requestExternalId": "deal-1042",
                "requestUrl": "https://validature.app/requests/5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Any 2xx acknowledges the event."
          }
        }
      }
    },
    "request.completed": {
      "post": {
        "summary": "Every recipient has signed or approved: the signed documents are ready. `downloadUrl` links are valid for 24 hours. Not sent for zero-access (Vault) requests.",
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "id": "5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d",
                "eventType": "request.completed",
                "occurredAt": "2026-09-24T11:00:00.000Z",
                "requestId": "5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d",
                "organizationId": "b7e1d2c3-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
                "title": "Service agreement - Acme",
                "status": "completed",
                "createdAt": "2026-09-23T16:20:00.000Z",
                "sentAt": "2026-09-23T16:25:00.000Z",
                "completedAt": "2026-09-24T11:00:00.000Z",
                "externalId": "deal-1042",
                "url": "https://validature.app/requests/5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d",
                "recipients": [
                  {
                    "id": "9d2f4b6a-1c3e-4a5b-8d7f-2e4c6a8b0d1f",
                    "email": "camille.martin@example.com",
                    "firstName": "Camille",
                    "lastName": "Martin",
                    "role": "signer",
                    "status": "signed",
                    "order": 1,
                    "notifiedAt": "2026-09-23T16:25:00.000Z",
                    "viewedAt": "2026-09-24T09:12:00.000Z",
                    "signedAt": "2026-09-24T09:15:00.000Z",
                    "declinedAt": null,
                    "declineReason": null
                  },
                  {
                    "id": "1e3a5c7d-9b2f-4d6e-8a1c-3e5f7a9b1d2c",
                    "email": "lea.dubois@example.com",
                    "firstName": "Léa",
                    "lastName": "Dubois",
                    "role": "signer",
                    "status": "signed",
                    "order": 2,
                    "notifiedAt": "2026-09-23T16:25:00.000Z",
                    "viewedAt": "2026-09-24T10:55:00.000Z",
                    "signedAt": "2026-09-24T11:00:00.000Z",
                    "declinedAt": null,
                    "declineReason": null
                  }
                ],
                "signedDocuments": [
                  {
                    "id": "8c1d2e3f-4a5b-4c6d-9e8f-7a6b5c4d3e2f",
                    "name": "service-agreement.pdf",
                    "mimeType": "application/pdf",
                    "downloadUrl": "https://storage.example/signed/service-agreement.pdf?signature=…"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Any 2xx acknowledges the event."
          }
        }
      }
    },
    "request.sent": {
      "post": {
        "summary": "A signature request is sent to its recipients.",
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "id": "5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d",
                "eventType": "request.sent",
                "occurredAt": "2026-09-24T10:30:00.000Z",
                "eventStatus": "sent",
                "requestId": "5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d",
                "organizationId": "b7e1d2c3-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
                "title": "Service agreement - Acme",
                "status": "sent",
                "externalId": "deal-1042",
                "signatureLevel": "SES",
                "signingOrder": "parallel",
                "createdAt": "2026-09-23T16:20:00.000Z",
                "sentAt": "2026-09-23T16:25:00.000Z",
                "completedAt": null,
                "expiresAt": "2026-10-23T21:59:59.999Z",
                "url": "https://validature.app/requests/5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d",
                "senderEmail": "olivia.owner@example.com",
                "senderName": "Olivia Owner",
                "recipients": [
                  {
                    "id": "9d2f4b6a-1c3e-4a5b-8d7f-2e4c6a8b0d1f",
                    "email": "camille.martin@example.com",
                    "firstName": "Camille",
                    "lastName": "Martin",
                    "role": "signer",
                    "status": "signed",
                    "order": 1,
                    "notifiedAt": "2026-09-23T16:25:00.000Z",
                    "viewedAt": "2026-09-24T09:12:00.000Z",
                    "signedAt": "2026-09-24T09:15:00.000Z",
                    "declinedAt": null,
                    "declineReason": null
                  },
                  {
                    "id": "1e3a5c7d-9b2f-4d6e-8a1c-3e5f7a9b1d2c",
                    "email": "lea.dubois@example.com",
                    "firstName": "Léa",
                    "lastName": "Dubois",
                    "role": "signer",
                    "status": "notified",
                    "order": 2,
                    "notifiedAt": "2026-09-23T16:25:00.000Z",
                    "viewedAt": null,
                    "signedAt": null,
                    "declinedAt": null,
                    "declineReason": null
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Any 2xx acknowledges the event."
          }
        }
      }
    },
    "request.status_changed": {
      "post": {
        "summary": "A signature request is sent, completed, declined, canceled or expires. `eventStatus` names the transition; filter it with the `statuses` query parameter when polling. The `completed` transition is not reported for zero-access (Vault) requests.",
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "id": "5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d",
                "eventType": "request.status_changed",
                "occurredAt": "2026-09-24T10:30:00.000Z",
                "eventStatus": "completed",
                "requestId": "5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d",
                "organizationId": "b7e1d2c3-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
                "title": "Service agreement - Acme",
                "status": "completed",
                "externalId": "deal-1042",
                "signatureLevel": "SES",
                "signingOrder": "parallel",
                "createdAt": "2026-09-23T16:20:00.000Z",
                "sentAt": "2026-09-23T16:25:00.000Z",
                "completedAt": "2026-09-24T11:00:00.000Z",
                "expiresAt": "2026-10-23T21:59:59.999Z",
                "url": "https://validature.app/requests/5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d",
                "senderEmail": "olivia.owner@example.com",
                "senderName": "Olivia Owner",
                "recipients": [
                  {
                    "id": "9d2f4b6a-1c3e-4a5b-8d7f-2e4c6a8b0d1f",
                    "email": "camille.martin@example.com",
                    "firstName": "Camille",
                    "lastName": "Martin",
                    "role": "signer",
                    "status": "signed",
                    "order": 1,
                    "notifiedAt": "2026-09-23T16:25:00.000Z",
                    "viewedAt": "2026-09-24T09:12:00.000Z",
                    "signedAt": "2026-09-24T09:15:00.000Z",
                    "declinedAt": null,
                    "declineReason": null
                  },
                  {
                    "id": "1e3a5c7d-9b2f-4d6e-8a1c-3e5f7a9b1d2c",
                    "email": "lea.dubois@example.com",
                    "firstName": "Léa",
                    "lastName": "Dubois",
                    "role": "signer",
                    "status": "notified",
                    "order": 2,
                    "notifiedAt": "2026-09-23T16:25:00.000Z",
                    "viewedAt": null,
                    "signedAt": null,
                    "declinedAt": null,
                    "declineReason": null
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Any 2xx acknowledges the event."
          }
        }
      }
    },
    "participant.viewed": {
      "post": {
        "summary": "A recipient opens a signature request for the first time.",
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "id": "participant.viewed:1e3a5c7d-9b2f-4d6e-8a1c-3e5f7a9b1d2c",
                "email": "lea.dubois@example.com",
                "firstName": "Léa",
                "lastName": "Dubois",
                "role": "signer",
                "status": "viewed",
                "order": 2,
                "notifiedAt": "2026-09-23T16:25:00.000Z",
                "viewedAt": "2026-09-24T10:30:00.000Z",
                "signedAt": null,
                "declinedAt": null,
                "declineReason": null,
                "eventType": "participant.viewed",
                "occurredAt": "2026-09-24T10:30:00.000Z",
                "participantId": "1e3a5c7d-9b2f-4d6e-8a1c-3e5f7a9b1d2c",
                "requestId": "5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d",
                "requestTitle": "Service agreement - Acme",
                "requestStatus": "ongoing",
                "requestExternalId": "deal-1042",
                "requestUrl": "https://validature.app/requests/5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d",
                "organizationId": "b7e1d2c3-4a5b-4c6d-8e9f-0a1b2c3d4e5f"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Any 2xx acknowledges the event."
          }
        }
      }
    },
    "participant.declined": {
      "post": {
        "summary": "A recipient declines to sign; the request stops there. `declineReason` is always null for zero-access (Vault) requests.",
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "id": "participant.declined:1e3a5c7d-9b2f-4d6e-8a1c-3e5f7a9b1d2c",
                "email": "lea.dubois@example.com",
                "firstName": "Léa",
                "lastName": "Dubois",
                "role": "signer",
                "status": "declined",
                "order": 2,
                "notifiedAt": "2026-09-23T16:25:00.000Z",
                "viewedAt": "2026-09-24T10:25:00.000Z",
                "signedAt": null,
                "declinedAt": "2026-09-24T10:30:00.000Z",
                "declineReason": "Wrong price",
                "eventType": "participant.declined",
                "occurredAt": "2026-09-24T10:30:00.000Z",
                "participantId": "1e3a5c7d-9b2f-4d6e-8a1c-3e5f7a9b1d2c",
                "requestId": "5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d",
                "requestTitle": "Service agreement - Acme",
                "requestStatus": "declined",
                "requestExternalId": "deal-1042",
                "requestUrl": "https://validature.app/requests/5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d",
                "organizationId": "b7e1d2c3-4a5b-4c6d-8e9f-0a1b2c3d4e5f"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Any 2xx acknowledges the event."
          }
        }
      }
    },
    "request.canceled": {
      "post": {
        "summary": "The sender cancels a signature request.",
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "id": "5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d",
                "eventType": "request.canceled",
                "occurredAt": "2026-09-24T10:30:00.000Z",
                "eventStatus": "canceled",
                "requestId": "5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d",
                "organizationId": "b7e1d2c3-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
                "title": "Service agreement - Acme",
                "status": "canceled",
                "externalId": "deal-1042",
                "signatureLevel": "SES",
                "signingOrder": "parallel",
                "createdAt": "2026-09-23T16:20:00.000Z",
                "sentAt": "2026-09-23T16:25:00.000Z",
                "completedAt": null,
                "expiresAt": "2026-10-23T21:59:59.999Z",
                "url": "https://validature.app/requests/5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d",
                "senderEmail": "olivia.owner@example.com",
                "senderName": "Olivia Owner",
                "recipients": [
                  {
                    "id": "9d2f4b6a-1c3e-4a5b-8d7f-2e4c6a8b0d1f",
                    "email": "camille.martin@example.com",
                    "firstName": "Camille",
                    "lastName": "Martin",
                    "role": "signer",
                    "status": "signed",
                    "order": 1,
                    "notifiedAt": "2026-09-23T16:25:00.000Z",
                    "viewedAt": "2026-09-24T09:12:00.000Z",
                    "signedAt": "2026-09-24T09:15:00.000Z",
                    "declinedAt": null,
                    "declineReason": null
                  },
                  {
                    "id": "1e3a5c7d-9b2f-4d6e-8a1c-3e5f7a9b1d2c",
                    "email": "lea.dubois@example.com",
                    "firstName": "Léa",
                    "lastName": "Dubois",
                    "role": "signer",
                    "status": "notified",
                    "order": 2,
                    "notifiedAt": "2026-09-23T16:25:00.000Z",
                    "viewedAt": null,
                    "signedAt": null,
                    "declinedAt": null,
                    "declineReason": null
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Any 2xx acknowledges the event."
          }
        }
      }
    },
    "request.expired": {
      "post": {
        "summary": "A signature request reaches its deadline before every recipient has acted.",
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "id": "5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d",
                "eventType": "request.expired",
                "occurredAt": "2026-09-24T10:30:00.000Z",
                "eventStatus": "expired",
                "requestId": "5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d",
                "organizationId": "b7e1d2c3-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
                "title": "Service agreement - Acme",
                "status": "expired",
                "externalId": "deal-1042",
                "signatureLevel": "SES",
                "signingOrder": "parallel",
                "createdAt": "2026-09-23T16:20:00.000Z",
                "sentAt": "2026-09-23T16:25:00.000Z",
                "completedAt": null,
                "expiresAt": "2026-09-24T10:30:00.000Z",
                "url": "https://validature.app/requests/5a7c9e1b-3d5f-4b7a-9c1e-3f5a7c9e1b3d",
                "senderEmail": "olivia.owner@example.com",
                "senderName": "Olivia Owner",
                "recipients": [
                  {
                    "id": "9d2f4b6a-1c3e-4a5b-8d7f-2e4c6a8b0d1f",
                    "email": "camille.martin@example.com",
                    "firstName": "Camille",
                    "lastName": "Martin",
                    "role": "signer",
                    "status": "signed",
                    "order": 1,
                    "notifiedAt": "2026-09-23T16:25:00.000Z",
                    "viewedAt": "2026-09-24T09:12:00.000Z",
                    "signedAt": "2026-09-24T09:15:00.000Z",
                    "declinedAt": null,
                    "declineReason": null
                  },
                  {
                    "id": "1e3a5c7d-9b2f-4d6e-8a1c-3e5f7a9b1d2c",
                    "email": "lea.dubois@example.com",
                    "firstName": "Léa",
                    "lastName": "Dubois",
                    "role": "signer",
                    "status": "notified",
                    "order": 2,
                    "notifiedAt": "2026-09-23T16:25:00.000Z",
                    "viewedAt": null,
                    "signedAt": null,
                    "declinedAt": null,
                    "declineReason": null
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Any 2xx acknowledges the event."
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "oauth2": {
        "type": "oauth2",
        "flows": {
          "authorizationCode": {
            "authorizationUrl": "https://validature.app/api/v1/oauth/authorize",
            "tokenUrl": "https://validature.app/api/v1/oauth/token",
            "refreshUrl": "https://validature.app/api/v1/oauth/token",
            "scopes": {
              "contacts:read": "Read the address book.",
              "contacts:write": "Create and update contacts.",
              "requests:read": "Read templates and signature requests, and download completed files.",
              "requests:write": "Create, send, remind and cancel signature requests.",
              "documents:read": "Receive download links of signed documents in `request.completed` events.",
              "webhooks:manage": "Subscribe to and unsubscribe from events."
            }
          }
        }
      },
      "clientBasic": {
        "type": "http",
        "scheme": "basic",
        "description": "OAuth client ID and secret."
      }
    }
  }
}
