{
    "openapi": "3.0.3",
    "info": {
        "title": "Wthaiq API",
        "description": "The e-signature API from Wthaiq.\n\nAuthentication with a Bearer key:\n- The secret key `sk_` is for server-side use (full permissions); its format is `sk_` followed by 40 hexadecimal characters.\n- The publishable key `pk_` is for use in the browser (limited permissions).\n- Test keys `sk_test_` and `pk_test_`: they charge no balance, send no invitation, reminder or copy to anyone, go no further than a simple signature, get no sealed evidence record for their requests, and their objects and events carry `livemode: false`. The signer’s email or number must belong to your account or to one of your team members.\n\n**Publishable key (pk_) restrictions** — any violation returns `403 forbidden`:\n- Only these paths are available: `/`, `/templates`, `/signature_requests`, `/signers`, `/flows`. Any other path → 403.\n- `/templates`, `/signers` and `/flows` are read-only (GET). Any write → 403.\n- `GET /signature_requests` (listing) is forbidden; fetch a specific request by its ID.\n- The key is locked to the domains set in the dashboard; a request from another domain or without an Origin header → 403.\n- A tighter quota for operations that charge the balance: 5 `POST /signature_requests…` operations per hour per visitor (key + IP address) → 429.\n- A daily cap per publishable key on the same operations, regardless of how many IP addresses are used: once reached, `429 daily_cap_reached` is returned with `Retry-After` until the start of the next day (UTC), and the account owner is notified at 80% of the cap and when it is reached.\n\n**Field masking for the publishable key:** in every response except the creation response itself, `Signer.signing_url` is set to `null`, the email is masked (`a****@example.com`), and the `ip` and `user_agent` fields in events and the completion certificate are emptied. Use a secret key (sk_) to read these values.\n\n**Rate limits:** 100 requests per 10 seconds per **account** (not per key), a single limit shared by test and live mode, plus an extra per-IP limit before authentication. When exceeded: `429 too_many_requests` with `Retry-After`, and the headers `X-RateLimit-Limit`/`X-RateLimit-Remaining`/`X-RateLimit-Reset`.\n\n**Restricting a secret key to IP addresses:** in the developer console you can restrict each secret key (sk_) to a list of IPv4 or IPv6 addresses or CIDR ranges, up to 50 entries per key. A request from an address outside the list is answered with `403 ip_not_allowed` before any operation runs, does not count against the rate limit, and appears in the request log. A key with no list is accepted from any address, and publishable keys (pk_) are not subject to this list.\n\n**Key rotation:** rotating a key in the console issues a new key with the same name, permissions and address list, and the previous key stays valid for 24 hours before it is answered with `401 invalid_api_key`. You can stop the previous key before that time, or choose to stop it as soon as you rotate.\n\n**Live mode and company verification:** test keys are free within a daily limit on every plan, and their requests carry no legal weight. A live request that is sent requires an active paid plan and a verified company: without a paid plan the response is `402 plan_required`, after the subscription year ends without renewal `402 plan_expired`, and before company verification is approved `403 kyb_required`. Companies are verified from the “Company verification” page in the developer console: an identity check of the representative, then a review of the company documents.\n\n**Plan and wallet:** every signer on a live signature request counts as one send from your annual plan balance, with a maximum of five signers per request (`too_many_signers`). Once the balance runs out, each extra send is charged to the wallet at your plan's overage rate, and identity verification is always charged to the wallet for every signer who requires it. The wallet holds a single currency for your account. If the balance isn't enough, the response is `402 insufficient_balance` and nothing is sent. `GET /usage` returns the plan, the balance and the prices.\n\n**Plan features:** some features start at a specific plan for live requests: ordered signing (`ordered`), return URLs (`return_url`, `success_url` and `cancel_url`) and custom workflows from the Business plan; bulk send (`/signature_requests/bulk`), token signing (`legal_level: qes` or `method: token`), signer attachments and access codes from the Enterprise plan. A live request that uses a feature outside your plan gets `403 plan_feature_unavailable` with the fields `feature` and `required_plan`, and nothing is created or charged. Test keys unlock all of these features on every plan except the custom domain, and the default workflow (`workflow_id: default`) is available on every plan.\n\n**Test mode:** every feature except the custom domain is available with a test key, and everything it produces is marked as a test: invitations arrive by email with “[TEST]” in the subject and a notice banner in the body; WhatsApp messages are not sent, the request events record `audit.whatsapp_simulated` (“Would have been sent via WhatsApp to …” with a masked number), so every signer needs an email address. Identity verification is a simulation with no provider session: the signer opens a page and chooses “Approve” or “Decline”, and the result arrives as `signer.identity_verified` or `signer.identity_declined`. The final file carries the watermark “TEST — no legal effect”, the evidence record is not sealed and no timestamp is requested for it, and the public verification page states that the document is a test. Limits per account: 20 requests and 50 emails a day, 5 signers per request and 10 recipients per bulk batch; anything beyond is refused with `429 test_daily_limit`, `429 test_email_limit`, `400 test_signer_limit` or `400 test_bulk_limit`, and a signer without an email with `400 test_email_required`.\n\n**Idempotency:** send an `Idempotency-Key` header with any `POST` (up to 200 characters, valid for 24 hours). Repeating the request with the same key on the same path returns the saved response with `Idempotent-Replayed: true`; if the repeat arrives while the first request is still running it is answered with `409 idempotency_in_progress` and `Retry-After`; using the same key on a different path returns `409 idempotency_key_reused`.\n\nEvery request returns a `Wthaiq-Request-Id` header. Errors use a unified format.\n\n**Error message language:** the `error.message` field is in Arabic by default, and in English when the request's `Accept-Language` header starts with `en` (for example `en-US,en;q=0.9`), when the `?lang=en` parameter is added, or when the request is sent to the `/en/api/v1/…` path, which works exactly like `/api/v1/…`. The `?lang=ar` parameter keeps Arabic. Error codes (`error.code`) never change with the language, so build your logic on them, not on the message text.\n\n**Extra fields in errors:** `402 plan_required`, `402 plan_expired` and `403 plan_feature_unavailable` carry the `upgrade_url` field (the plans page in the developer portal); `403 kyb_required` carries the `verify_url` field (the Company verification page); and `400 too_many_signers` carries the `max_signers` field (the maximum number of signers in a live request, which is 5).",
        "version": "2026-07-01",
        "contact": {
            "name": "Wthaiq Support",
            "url": "https://developers.wthaiq.com/docs"
        }
    },
    "servers": [
        {
            "url": "https://wthaiq.com/api/v1",
            "description": "Production"
        }
    ],
    "security": [
        {
            "bearerAuth": []
        }
    ],
    "tags": [
        {
            "name": "signature_requests",
            "description": "Signature requests"
        },
        {
            "name": "sessions",
            "description": "Sessions — signature requests created from a workflow"
        },
        {
            "name": "templates",
            "description": "Contracts / templates"
        },
        {
            "name": "signers",
            "description": "Signers"
        },
        {
            "name": "documents",
            "description": "Upload PDF documents"
        },
        {
            "name": "webhooks",
            "description": "Webhook endpoints"
        },
        {
            "name": "flows",
            "description": "Ready-made console flows"
        },
        {
            "name": "account",
            "description": "Account and usage"
        },
        {
            "name": "events",
            "description": "Event log (the same webhook payload)"
        },
        {
            "name": "identity",
            "description": "Identity verification"
        },
        {
            "name": "verifications",
            "description": "Public verification of a signed contract"
        }
    ],
    "paths": {
        "/": {
            "get": {
                "tags": [
                    "account"
                ],
                "summary": "Service root and account info",
                "responses": {
                    "200": {
                        "description": "Service information, including the docs field with the link to the documentation in the developer portal."
                    }
                }
            }
        },
        "/usage": {
            "get": {
                "tags": [
                    "account"
                ],
                "summary": "Usage and balance",
                "responses": {
                    "200": {
                        "description": "Usage",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Usage"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/balance": {
            "get": {
                "tags": [
                    "account"
                ],
                "summary": "Account credit",
                "responses": {
                    "200": {
                        "description": "Balance",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Usage"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/templates": {
            "get": {
                "tags": [
                    "templates"
                ],
                "summary": "List templates",
                "parameters": [
                    {
                        "name": "scope",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "mine"
                            ]
                        },
                        "description": "mine = your custom contracts only"
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 20
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "List templates"
                    }
                }
            },
            "post": {
                "tags": [
                    "templates"
                ],
                "summary": "Create a template (custom contract)",
                "description": "Requires a secret key (sk_) — writes are forbidden with public keys (403).",
                "parameters": [
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "maxLength": 200
                        },
                        "description": "Safe-retry key for the request (POST only, valid for 24 hours). Re-sending with the same key on the same path returns the stored response with the header Idempotent-Replayed: true; if it arrives while the first request is still running it is answered with 409 and Retry-After; using it on another path returns 409."
                    }
                ],
                "responses": {
                    "201": {
                        "description": "Created",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Template"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "402": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Forbidden — usually a publishable key (pk_) restriction or an origin lock, or a secret-key request from an IP address outside its allowed list (ip_not_allowed).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Idempotency key used with another endpoint (idempotency_key_reused), or a request with the same key is still in progress (idempotency_in_progress, with Retry-After).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/TemplateCreate"
                            }
                        }
                    }
                }
            }
        },
        "/templates/{id}": {
            "get": {
                "tags": [
                    "templates"
                ],
                "summary": "Retrieve a template",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Resource ID"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Template",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Template"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/signature_requests": {
            "get": {
                "tags": [
                    "signature_requests"
                ],
                "summary": "List signature requests",
                "description": "Requires a secret key (sk_) — listing is forbidden with public keys (403).",
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "created_after",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        },
                        "description": "ISO or unix date"
                    },
                    {
                        "name": "created_before",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "starting_after",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        },
                        "description": "Page cursor"
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 20
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "List requests"
                    },
                    "403": {
                        "description": "Forbidden — usually a publishable key (pk_) restriction or an origin lock, or a secret-key request from an IP address outside its allowed list (ip_not_allowed).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded — see the Retry-After header.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "signature_requests"
                ],
                "summary": "Create and send a signature request",
                "description": "An operation that deducts from your balance. With a public key (pk_) it is subject to a quota of 5 operations/hour per visitor (429). A live request that is sent requires an active paid plan (`402 plan_required` or `402 plan_expired`) and a verified company (`403 kyb_required`).",
                "parameters": [
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "maxLength": 200
                        },
                        "description": "Safe-retry key for the request (POST only, valid for 24 hours). Re-sending with the same key on the same path returns the stored response with the header Idempotent-Replayed: true; if it arrives while the first request is still running it is answered with 409 and Retry-After; using it on another path returns 409."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/SignatureRequestCreate"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Created",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SignatureRequest"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "402": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Forbidden — a live request before company verification is approved (kyb_required), a feature not included in your plan (plan_feature_unavailable), a publishable key (pk_) restriction or domain lock, or a secret-key request from an IP address outside its allowlist (ip_not_allowed).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Idempotency key used with another endpoint (idempotency_key_reused), or a request with the same key is still in progress (idempotency_in_progress, with Retry-After).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded — see the Retry-After header.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/signature_requests/bulk": {
            "post": {
                "tags": [
                    "signature_requests"
                ],
                "summary": "Bulk send (the same contract to several signers)",
                "parameters": [
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "maxLength": 200
                        },
                        "description": "Safe-retry key for the request (POST only, valid for 24 hours). Re-sending with the same key on the same path returns the stored response with the header Idempotent-Replayed: true; if it arrives while the first request is still running it is answered with 409 and Retry-After; using it on another path returns 409."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/BulkSend"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Batch summary"
                    },
                    "400": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "402": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Forbidden — a live request before company verification is approved (kyb_required), a feature not included in your plan (plan_feature_unavailable), a publishable key (pk_) restriction or domain lock, or a secret-key request from an IP address outside its allowlist (ip_not_allowed).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Idempotency key used with another endpoint (idempotency_key_reused), or a request with the same key is still in progress (idempotency_in_progress, with Retry-After).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded — see the Retry-After header.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/signature_requests/{id}": {
            "get": {
                "tags": [
                    "signature_requests"
                ],
                "summary": "Retrieve a signature request",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Resource ID"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Request",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SignatureRequest"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/signature_requests/{id}/send": {
            "post": {
                "tags": [
                    "signature_requests"
                ],
                "summary": "Send a draft request",
                "description": "Charges the sending cost once. Resending a request that has already been charged is treated as a reminder: at least one hour between two messages to the same signer, and a cap of 10 reminders per request (429).",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Resource ID"
                    },
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "maxLength": 200
                        },
                        "description": "Safe-retry key for the request (POST only, valid for 24 hours). Re-sending with the same key on the same path returns the stored response with the header Idempotent-Replayed: true; if it arrives while the first request is still running it is answered with 409 and Retry-After; using it on another path returns 409."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sent"
                    },
                    "402": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Forbidden — a live request before company verification is approved (kyb_required), a feature not included in your plan (plan_feature_unavailable), a publishable key (pk_) restriction or domain lock, or a secret-key request from an IP address outside its allowlist (ip_not_allowed).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Idempotency key used with another endpoint (idempotency_key_reused), or a request with the same key is still in progress (idempotency_in_progress, with Retry-After).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded — see the Retry-After header.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/signature_requests/{id}/cancel": {
            "post": {
                "tags": [
                    "signature_requests"
                ],
                "summary": "Cancel a request",
                "description": "Rejected with 409 (request_not_cancelable) if the request is already completed or canceled. Once a request has been sent, its cost is not refunded, even if it is canceled before anyone signs it.",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Resource ID"
                    },
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "maxLength": 200
                        },
                        "description": "Safe-retry key for the request (POST only, valid for 24 hours). Re-sending with the same key on the same path returns the stored response with the header Idempotent-Replayed: true; if it arrives while the first request is still running it is answered with 409 and Retry-After; using it on another path returns 409."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Canceled"
                    },
                    "409": {
                        "description": "Idempotency key used with another endpoint (idempotency_key_reused), or a request with the same key is still in progress (idempotency_in_progress, with Retry-After).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded — see the Retry-After header.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/signature_requests/{id}/reminders": {
            "post": {
                "tags": [
                    "signature_requests"
                ],
                "summary": "Send a reminder to signers",
                "description": "At most one reminder per signer per hour, and a cap of 10 reminders per request. Violations return 429 (reminder_too_soon / reminder_limit_reached). A draft or canceled request returns 400.",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Resource ID"
                    },
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "maxLength": 200
                        },
                        "description": "Safe-retry key for the request (POST only, valid for 24 hours). Re-sending with the same key on the same path returns the stored response with the header Idempotent-Replayed: true; if it arrives while the first request is still running it is answered with 409 and Retry-After; using it on another path returns 409."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Reminder sent"
                    },
                    "400": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Idempotency key used with another endpoint (idempotency_key_reused), or a request with the same key is still in progress (idempotency_in_progress, with Retry-After).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded — see the Retry-After header.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/signature_requests/{id}/download": {
            "get": {
                "tags": [
                    "signature_requests"
                ],
                "summary": "Signed contract download link",
                "description": "Returns the signed contract data as JSON once the request is complete: `pdf_url` is the link to the final PDF (the frozen contract text with the same verification certificate used on the platform, with its reference and QR code), `pdf_status` is its state (`ready`, `pending` while it is being prepared, or `unavailable` when it could not be generated on the server, in which case use `final_document_url`), `pdf_sha256` is its fingerprint, `final_document_url` is the final document page, and `reference` is the verification reference. In live mode the link to the same file is sent to every signer and to the sender on completion. The file carries no embedded PAdES signature; the independent cryptographic proof is the sealed evidence record via GET /signature_requests/{id}/evidence. An incomplete request returns 400.",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Resource ID"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "File links"
                    },
                    "400": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/signature_requests/{id}/download/pdf": {
            "get": {
                "tags": [
                    "signature_requests"
                ],
                "summary": "Download the final PDF",
                "description": "Returns the final PDF itself (application/pdf) once the request is complete; the `X-File-Sha256` header carries its fingerprint, matching `pdf_sha256`. Requires a secret key (sk_). Returns 409 with code `pdf_not_ready` while the file is being prepared, or `pdf_unavailable` if it could not be generated on the server.",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Resource ID"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Final PDF",
                        "content": {
                            "application/pdf": {
                                "schema": {
                                    "type": "string",
                                    "format": "binary"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/signature_requests/{id}/evidence": {
            "get": {
                "tags": [
                    "signature_requests"
                ],
                "summary": "the sealed evidence record",
                "description": "Returns the sealed evidence record of a completed request (record_raw, the Ed25519 signature, the public key and the RFC3161 timestamp) for independent verification. Requires a secret key (sk_), and returns 404 until the record is sealed; test requests are never sealed.",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Resource ID"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Evidence record"
                    },
                    "403": {
                        "description": "Forbidden — usually a publishable key (pk_) restriction or an origin lock, or a secret-key request from an IP address outside its allowed list (ip_not_allowed).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/signature_requests/{id}/certificate": {
            "get": {
                "tags": [
                    "signature_requests"
                ],
                "summary": "Completion certificate and audit trail",
                "description": "The `ip` fields in the audit trail are emptied to null for public keys (pk_).",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Resource ID"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Certificate"
                    }
                }
            }
        },
        "/signature_requests/{id}/events": {
            "get": {
                "tags": [
                    "signature_requests"
                ],
                "summary": "Request events / audit log",
                "description": "The `ip` field is emptied to null for public keys (pk_).",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Resource ID"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Events"
                    }
                }
            }
        },
        "/sessions": {
            "get": {
                "tags": [
                    "sessions"
                ],
                "summary": "Sessions list",
                "description": "Returns the signature requests created from workflows, newest first, in the mode of the key itself (live or test). Requires a secret key (sk_).",
                "parameters": [
                    {
                        "name": "workflow_id",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        },
                        "example": "wf_8f3a1c9e2b",
                        "description": "Sessions of one workflow"
                    },
                    {
                        "name": "vendor_data",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        },
                        "description": "Your reference as sent at creation (exact match)"
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "draft",
                                "sent",
                                "partially_signed",
                                "completed",
                                "declined",
                                "expired",
                                "canceled"
                            ]
                        }
                    },
                    {
                        "name": "starting_after",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        },
                        "description": "Page cursor"
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 20,
                            "minimum": 1,
                            "maximum": 100
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sessions list",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SessionList"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Forbidden — usually a publishable key (pk_) restriction or an origin lock, or a secret-key request from an IP address outside its allowed list (ip_not_allowed).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded — see the Retry-After header.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "sessions"
                ],
                "summary": "Create a session from a workflow",
                "description": "Creates a signature request with the settings of a published workflow and sends it at once. The session ID is the signature request ID itself (`sr_…`), so all `/signature_requests/{id}` endpoints work with it. Requires a secret key (sk_); a publishable key (pk_) and a read-only key are refused with 403. On every plan, a request can use the default workflow with the ID `default`: its document is set with each request (`template_id`), the channel is email, the method is verified signing and links last 7 days; the usual overrides apply.\n\n**What a request may change:** `signature_method`, `channel`, `cc`, `require_id_attachment`, `expires_in`, `language` and `return_url`, plus the document (`template_id` or `document_id`) when the workflow's document is “set per request”. `ordered`, `reminders` and `require_access_code` are set in the workflow only; they are refused, together with `send`, `legal_level`, `require_identity`, `source`, `document`, `signers[].method` and `signers[].require_identity`, with `400 invalid_override`, and `param` names the field.\n\n**Channels:** `email` needs an e-mail address for every signer; `whatsapp` needs a number for every signer and has no extra cost; `link` sends no invitation and no reminders, and all links come back in the response.\n\n**Verification code:** it goes through the request's channel only: by e-mail with `email`, and by WhatsApp with `whatsapp`; it goes by e-mail if the signer has no number or WhatsApp codes are not enabled on the platform. With `link` it goes to the signer's e-mail if there is one, otherwise to their number.\n\n**Signing in order:** on a workflow whose parties sign in order, each party is invited after the previous one signs, and the `signer.sent` event arrives when their turn comes. With the `link` channel, all links come back in the creation response, and the signing page does not accept a party before the one ahead of them has signed.\n\n**Return URL:** set it in the workflow or send it in `return_url`: an `https` URL on a domain accepted on your account (up to 500 characters, no user name and no `#`), otherwise the answer is `400 invalid_override` or `400 domain_not_accepted`. After the signer signs or declines, they are redirected to the URL with `session_id`, `signer_id` and `status` (`completed` or `declined`). Rely on the signed webhook or on `GET /sessions/{id}` for the result, not on the return.\n\n**Live mode:** a live session requires an active paid plan and a verified company; otherwise the response is `402 plan_required`, `402 plan_expired` or `403 kyb_required`.\n\n**Cost:** charged once at sending: the request cost, plus the identity verification cost per signer when the method is `identity` (prices are in `GET /`). The balance is checked before creation, and the amount charged comes back in `cost`. With a test key nothing is charged, the invitation arrives by email marked “Test”, no WhatsApp messages are sent and identity verification is simulated. Once a request has been sent, its cost is not refunded, even if it is canceled before anyone signs it.\n\n**Errors:** `parameter_missing`, `workflow_not_found` (404), `workflow_not_live` (409), `invalid_override`, `invalid_signer`, `invalid_request`, `channel_unavailable`, `domain_not_accepted`, `insufficient_balance` (402), `plan_required` (402), `plan_expired` (402), `kyb_required` (403), `plan_feature_unavailable` (403), `test_daily_limit` (429), `test_email_limit` (429), `test_signer_limit`, `test_email_required`, `delivery_failed` (502), `feature_unavailable` (503).\n\n**Webhooks:** event names are unchanged. `signature_request.*` events carry `workflow_id`, `workflow_version`, `vendor_data` and `channel` inside the request object, and `signer.*` events carry `signature_request`, `workflow_id`, `workflow_version` and `vendor_data`.",
                "parameters": [
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "maxLength": 200
                        },
                        "description": "Safe-retry key for the request (POST only, valid for 24 hours). Re-sending with the same key on the same path returns the stored response with the header Idempotent-Replayed: true; if it arrives while the first request is still running it is answered with 409 and Retry-After; using it on another path returns 409."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/SessionCreate"
                            },
                            "example": {
                                "workflow_id": "wf_8f3a1c9e2b",
                                "vendor_data": "ORD-1001",
                                "signers": [
                                    {
                                        "name": "Ahmed Mohamed",
                                        "email": "ahmed@example.com"
                                    }
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Session created",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Session"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "402": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Forbidden — a live request before company verification is approved (kyb_required), a feature not included in your plan (plan_feature_unavailable), a publishable key (pk_) restriction or domain lock, or a secret-key request from an IP address outside its allowlist (ip_not_allowed).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "The workflow is not published yet or is archived (workflow_not_live), or an Idempotency key conflict (idempotency_key_reused / idempotency_in_progress).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded — see the Retry-After header.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "502": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "503": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/sessions/{id}": {
            "get": {
                "tags": [
                    "sessions"
                ],
                "summary": "Retrieve a session",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Resource ID"
                    }
                ],
                "description": "Returns the session object in its current state. Returns 404 for a signature request that was not created from a workflow. Requires a secret key (sk_).",
                "responses": {
                    "200": {
                        "description": "The session",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Session"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Forbidden — usually a publishable key (pk_) restriction or an origin lock, or a secret-key request from an IP address outside its allowed list (ip_not_allowed).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/signers/{id}": {
            "get": {
                "tags": [
                    "signers"
                ],
                "summary": "Retrieve a signer",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Resource ID"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Signer",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Signer"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/signers/{id}/signing_session": {
            "post": {
                "tags": [
                    "signers"
                ],
                "summary": "A short-lived embedded signing session (30 minutes)",
                "description": "Creates a short-lived signing link that can be embedded in an iframe. sk_ keys only (pk_ is read-only on /signers ⇒ 403). `return_url` is optional and must be https on a domain accepted in your account, otherwise 400 (domain_not_accepted for a domain that is not accepted). With `redirect` mode, the browser goes from `signing_url` to the signing page, then to `success_url` after signing or to `cancel_url` after declining, with `session_id`, `signer_id` and `status`.",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Resource ID"
                    },
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "maxLength": 200
                        },
                        "description": "Safe-retry key for the request (POST only, valid for 24 hours). Re-sending with the same key on the same path returns the stored response with the header Idempotent-Replayed: true; if it arrives while the first request is still running it is answered with 409 and Retry-After; using it on another path returns 409."
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "return_url": {
                                        "type": "string",
                                        "format": "uri",
                                        "example": "https://example.com/thanks",
                                        "description": "An https URL on a domain accepted in your account. The signer is sent there after signing; available on the Business plan and above."
                                    },
                                    "mode": {
                                        "type": "string",
                                        "enum": [
                                            "iframe",
                                            "redirect"
                                        ],
                                        "default": "iframe",
                                        "description": "iframe to embed in a frame on a page under a domain accepted in your account, or redirect to send the browser away and back. Do not send return_url with redirect."
                                    },
                                    "success_url": {
                                        "type": "string",
                                        "format": "uri",
                                        "maxLength": 500,
                                        "example": "https://app.example.com/done?sr={signature_request}",
                                        "description": "Required with redirect: an https URL on a domain accepted on your account; the signer is redirected to it after signing (status=completed). {signature_request} and {signer} are replaced with their IDs."
                                    },
                                    "cancel_url": {
                                        "type": "string",
                                        "format": "uri",
                                        "maxLength": 500,
                                        "example": "https://app.example.com/canceled",
                                        "description": "Optional with redirect: the signer is redirected to it after declining (status=declined). Without it, the signer stays on the signing page."
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "The session",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/SigningSession"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Forbidden — a feature not included in your plan (plan_feature_unavailable), a publishable key (pk_) restriction or domain lock, or a secret-key request from an IP address outside its allowlist (ip_not_allowed).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/signers/{id}/identity_match": {
            "post": {
                "tags": [
                    "signers"
                ],
                "summary": "Decide on a signer's name difference",
                "description": "When the name on a signer's identity document differs from the name sent in the request, and your account setting is “Hold signing until a decision” (the default), you receive the `signer.identity_match_hold` event and signing is not completed until you send the decision here or from the “Identity review” page in the developer console. approve continues signing, and reject stops this party's signing. Allowed for sk_ keys only. If there is no pending decision: 409 identity_match_not_pending.",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Resource ID"
                    },
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "maxLength": 200
                        },
                        "description": "Safe-retry key for the request (POST only, valid for 24 hours). Re-sending with the same key on the same path returns the stored response with the header Idempotent-Replayed: true; if it arrives while the first request is still running it is answered with 409 and Retry-After; using it on another path returns 409."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "decision"
                                ],
                                "properties": {
                                    "decision": {
                                        "type": "string",
                                        "enum": [
                                            "approve",
                                            "reject"
                                        ]
                                    },
                                    "note": {
                                        "type": "string",
                                        "maxLength": 200,
                                        "description": "Optional internal note saved with the decision."
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The signer after the decision, with the new state in identity.name_match",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Signer"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/events": {
            "get": {
                "tags": [
                    "events"
                ],
                "summary": "List the account events",
                "description": "Exactly the same payload as the webhook — useful for catching up after your endpoint has been down. Requires a secret key (sk_).",
                "parameters": [
                    {
                        "name": "type",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        },
                        "description": "Filter by event type, for example signature_request.completed"
                    },
                    {
                        "name": "starting_after",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        },
                        "description": "Page cursor (evt_…)"
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 20
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The list of events"
                    },
                    "403": {
                        "description": "Forbidden — usually a publishable key (pk_) restriction or an origin lock, or a secret-key request from an IP address outside its allowed list (ip_not_allowed).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/events/{id}": {
            "get": {
                "tags": [
                    "events"
                ],
                "summary": "Fetch a specific event",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Resource ID"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Event",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Event"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Forbidden — usually a publishable key (pk_) restriction or an origin lock, or a secret-key request from an IP address outside its allowed list (ip_not_allowed).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/events/{id}/redeliver": {
            "post": {
                "tags": [
                    "events"
                ],
                "summary": "Redeliver an event notification",
                "description": "Redelivers the webhook of a past event with the same payload and the same ID, signed with the endpoint's current secret. A new delivery is created and attempted immediately, and follows the usual retry schedule if your server does not respond with 2xx. Limit: five per event and thirty per account every ten minutes, then 429.",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Resource ID"
                    },
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "maxLength": 200
                        },
                        "description": "Safe-retry key for the request (POST only, valid for 24 hours). Re-sending with the same key on the same path returns the stored response with the header Idempotent-Replayed: true; if it arrives while the first request is still running it is answered with 409 and Retry-After; using it on another path returns 409."
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "endpoint": {
                                        "type": "string",
                                        "example": "we_123",
                                        "description": "ID of an enabled endpoint (we_) to redeliver to it only. Without it, the event is redelivered to every enabled endpoint subscribed to its type."
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Redelivery result",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "object": {
                                            "type": "string",
                                            "example": "event_redelivery"
                                        },
                                        "event": {
                                            "type": "string",
                                            "example": "evt_123"
                                        },
                                        "deliveries": {
                                            "type": "array",
                                            "items": {
                                                "type": "object",
                                                "properties": {
                                                    "endpoint": {
                                                        "type": "string",
                                                        "example": "we_123"
                                                    },
                                                    "status": {
                                                        "type": "string",
                                                        "enum": [
                                                            "succeeded",
                                                            "pending",
                                                            "failed"
                                                        ]
                                                    },
                                                    "response_code": {
                                                        "type": "integer",
                                                        "nullable": true
                                                    },
                                                    "error": {
                                                        "type": "string",
                                                        "nullable": true
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Forbidden — usually a publishable key (pk_) restriction or an origin lock, or a secret-key request from an IP address outside its allowed list (ip_not_allowed).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit exceeded — see the Retry-After header.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/identity_verifications/{id}": {
            "get": {
                "tags": [
                    "identity"
                ],
                "summary": "Identity verification status (idv_…)",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Resource ID"
                    }
                ],
                "description": "Requires a secret key (sk_). Returns 403 if the verification does not belong to your account.",
                "responses": {
                    "200": {
                        "description": "The identity verification",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/IdentityVerification"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Forbidden — usually a publishable key (pk_) restriction or an origin lock, or a secret-key request from an IP address outside its allowed list (ip_not_allowed).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/verifications/{reference}": {
            "get": {
                "tags": [
                    "verifications"
                ],
                "summary": "Verify a signed contract by its verification reference",
                "description": "Returns the contract status, content integrity (intact/modified/recorded/unknown), structural commitment (structure) and its parties with masked names and emails. Requires a secret key (sk_).",
                "parameters": [
                    {
                        "name": "reference",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "example": "WTQ-1A2B3C4D5E6F",
                        "description": "The verification reference as shown on the completion certificate or in the QR code, without inner dashes, e.g. WTQ-1A2B3C4D5E6F or WTH-1A2B3C4D5E6F. The document number is not accepted."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The verification result",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Verification"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Forbidden — usually a publishable key (pk_) restriction or an origin lock, or a secret-key request from an IP address outside its allowed list (ip_not_allowed).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No document has this reference: an error with the code not_found, together with the param and reference fields.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/documents": {
            "post": {
                "tags": [
                    "documents"
                ],
                "summary": "Upload a PDF document (optionally with a coordinate field map)",
                "description": "Send the file via multipart/form-data in the `file` field; it is saved in your account with its fingerprint and page count, and counts toward your plan’s contract limit.\n\nYou may send `field_map` as a JSON string that is saved with the document (coordinates are relative 0..1 from the page’s top-left corner).\n\nAn uploaded document cannot yet be used as a signature-request source through the API (coming soon); a request that references it returns 400, and field_map values are not printed on the file.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "file"
                                ],
                                "properties": {
                                    "file": {
                                        "type": "string",
                                        "format": "binary",
                                        "description": "PDF file (up to 10 MB)"
                                    },
                                    "kind": {
                                        "type": "string",
                                        "enum": [
                                            "pdf",
                                            "contract"
                                        ],
                                        "default": "pdf"
                                    },
                                    "field_map": {
                                        "type": "string",
                                        "description": "JSON: [{\"key\":\"signer_name\",\"label\":\"Name\",\"type\":\"text\",\"page\":1,\"x\":0.12,\"y\":0.34,\"w\":0.3,\"h\":0.04,\"required\":true}]"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Uploaded",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Document"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "402": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/documents/{id}": {
            "get": {
                "tags": [
                    "documents"
                ],
                "summary": "Retrieve an uploaded document",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Resource ID"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Document",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Document"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/flows": {
            "get": {
                "tags": [
                    "flows"
                ],
                "summary": "List ready-made flows",
                "description": "Flows are a legacy format that can be read here; no new flows are created. To configure the signing pipeline, use workflows in the developer console. Use them with the console: `<wthaiq-console flow=\"flow_…\">`.",
                "responses": {
                    "200": {
                        "description": "List flows"
                    }
                }
            }
        },
        "/flows/{id}": {
            "get": {
                "tags": [
                    "flows"
                ],
                "summary": "Retrieve a flow",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Resource ID"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Flow",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Flow"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/webhook_endpoints": {
            "get": {
                "tags": [
                    "webhooks"
                ],
                "summary": "List webhook endpoints",
                "parameters": [
                    {
                        "name": "limit",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "default": 20,
                            "minimum": 1,
                            "maximum": 100
                        }
                    },
                    {
                        "name": "starting_after",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        },
                        "description": "Page cursor (we_…)"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The list from newest to oldest, with has_more and next_cursor.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "object": {
                                            "type": "string",
                                            "example": "list"
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/WebhookEndpoint"
                                            }
                                        },
                                        "has_more": {
                                            "type": "boolean"
                                        },
                                        "next_cursor": {
                                            "type": "string",
                                            "nullable": true,
                                            "description": "Send it in starting_after to fetch the next page."
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "webhooks"
                ],
                "summary": "Create webhook endpoint",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/WebhookCreate"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Created",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/WebhookEndpoint"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/webhook_endpoints/event_types": {
            "get": {
                "tags": [
                    "webhooks"
                ],
                "summary": "Supported event types",
                "responses": {
                    "200": {
                        "description": "List types"
                    }
                }
            }
        },
        "/webhook_endpoints/{id}": {
            "get": {
                "tags": [
                    "webhooks"
                ],
                "summary": "Retrieve an endpoint",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Resource ID"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Endpoint"
                    },
                    "404": {
                        "description": "Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "webhooks"
                ],
                "summary": "Update an endpoint (events / status)",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Resource ID"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Updated"
                    }
                }
            },
            "delete": {
                "tags": [
                    "webhooks"
                ],
                "summary": "Delete an endpoint",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Resource ID"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Deleted"
                    }
                }
            }
        },
        "/webhook_endpoints/{id}/deliveries": {
            "get": {
                "tags": [
                    "webhooks"
                ],
                "summary": "Recent deliveries",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Resource ID"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Deliveries"
                    }
                }
            }
        },
        "/webhook_endpoints/{id}/test": {
            "post": {
                "tags": [
                    "webhooks"
                ],
                "summary": "Send a test event",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Resource ID"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Test result"
                    }
                }
            }
        }
    },
    "components": {
        "securitySchemes": {
            "bearerAuth": {
                "type": "http",
                "scheme": "bearer",
                "description": "API key: `Authorization: Bearer sk_...` or `pk_...`"
            }
        },
        "schemas": {
            "Error": {
                "type": "object",
                "properties": {
                    "error": {
                        "type": "object",
                        "properties": {
                            "type": {
                                "type": "string"
                            },
                            "code": {
                                "type": "string"
                            },
                            "message": {
                                "type": "string"
                            },
                            "param": {
                                "type": "string",
                                "nullable": true
                            },
                            "request_id": {
                                "type": "string"
                            },
                            "feature": {
                                "type": "string",
                                "nullable": true,
                                "description": "With plan_feature_unavailable: the feature requested."
                            },
                            "required_plan": {
                                "type": "string",
                                "nullable": true,
                                "description": "With plan_feature_unavailable: the lowest plan that includes the feature."
                            },
                            "upgrade_url": {
                                "type": "string",
                                "format": "uri",
                                "nullable": true,
                                "description": "With plan_required, plan_expired and plan_feature_unavailable: the plans page in the developer portal."
                            },
                            "verify_url": {
                                "type": "string",
                                "format": "uri",
                                "nullable": true,
                                "description": "With kyb_required: the Company verification page in the developer portal."
                            },
                            "max_signers": {
                                "type": "integer",
                                "nullable": true,
                                "example": 5,
                                "description": "With too_many_signers: the maximum number of signers in a single live request."
                            },
                            "reference": {
                                "type": "string",
                                "nullable": true,
                                "description": "With not_found on GET /verifications/{reference}: the reference that was looked up."
                            }
                        }
                    }
                }
            },
            "Field": {
                "type": "object",
                "properties": {
                    "key": {
                        "type": "string"
                    },
                    "label": {
                        "type": "string"
                    },
                    "type": {
                        "type": "string",
                        "enum": [
                            "text",
                            "number",
                            "date",
                            "email",
                            "tel",
                            "signature"
                        ]
                    },
                    "required": {
                        "type": "boolean"
                    }
                }
            },
            "Template": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "example": "tpl_123"
                    },
                    "object": {
                        "type": "string"
                    },
                    "name": {
                        "type": "string"
                    },
                    "fields": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Field"
                        }
                    },
                    "created_at": {
                        "type": "integer"
                    }
                }
            },
            "TemplateCreate": {
                "type": "object",
                "required": [
                    "name",
                    "content"
                ],
                "properties": {
                    "name": {
                        "type": "string",
                        "example": "Services contract"
                    },
                    "content": {
                        "type": "string",
                        "description": "HTML content with fields {{key}}",
                        "example": "<p>I, the undersigned, {{signer_name}} ...</p>"
                    },
                    "fields": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Field"
                        }
                    }
                }
            },
            "SignerInput": {
                "type": "object",
                "required": [
                    "name"
                ],
                "properties": {
                    "name": {
                        "type": "string"
                    },
                    "email": {
                        "type": "string",
                        "format": "email",
                        "description": "Optional when `phone` is present. At least one of the two is required."
                    },
                    "phone": {
                        "type": "string",
                        "example": "201012345678",
                        "description": "The signer’s WhatsApp number. When both a number and an email are given, the invitation is sent through both channels. A number **on its own** is accepted only while verification codes can be delivered over WhatsApp; otherwise the request is rejected with 400 and an email is required for that signer — so that nobody is left facing a code that cannot reach them. The number is normalised to international format automatically."
                    },
                    "require_identity": {
                        "type": "boolean"
                    },
                    "fields": {
                        "type": "object",
                        "additionalProperties": {
                            "type": "string"
                        }
                    },
                    "type": {
                        "type": "string",
                        "enum": [
                            "individual",
                            "company"
                        ],
                        "default": "individual"
                    },
                    "method": {
                        "type": "string",
                        "enum": [
                            "draw",
                            "token"
                        ],
                        "default": "draw",
                        "description": "token signs with the token certificate and is forced when legal_level is qes. The default is draw."
                    }
                }
            },
            "SignatureRequestCreate": {
                "type": "object",
                "required": [
                    "source",
                    "signers"
                ],
                "properties": {
                    "title": {
                        "type": "string",
                        "maxLength": 250
                    },
                    "require_identity": {
                        "type": "boolean",
                        "description": "Identity confirmation for every signer; forced with aes and qes. Test keys skip it."
                    },
                    "source": {
                        "type": "object",
                        "properties": {
                            "type": {
                                "type": "string",
                                "enum": [
                                    "template",
                                    "document"
                                ]
                            },
                            "template_id": {
                                "type": "string"
                            },
                            "document_id": {
                                "type": "string"
                            }
                        }
                    },
                    "signers": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/SignerInput"
                        }
                    },
                    "cc": {
                        "type": "array",
                        "description": "CC recipients — they receive the signed contract without signing it (up to 20).",
                        "items": {
                            "type": "object",
                            "properties": {
                                "name": {
                                    "type": "string"
                                },
                                "email": {
                                    "type": "string",
                                    "format": "email"
                                }
                            }
                        }
                    },
                    "fields": {
                        "type": "object",
                        "additionalProperties": {
                            "type": "string"
                        }
                    },
                    "legal_level": {
                        "type": "string",
                        "enum": [
                            "ses",
                            "aes",
                            "qes"
                        ],
                        "default": "ses"
                    },
                    "format": {
                        "type": "string",
                        "enum": [
                            "pades-b",
                            "pades-t",
                            "pades-lt",
                            "pades-lta"
                        ],
                        "default": "pades-lt",
                        "description": "The requested assurance level. It is recorded on the request and returned as-is for backward compatibility, but the API path does not currently produce a PAdES signature embedded in the PDF. The independent cryptographic proof is the sealed evidence record (Ed25519 signature + RFC3161 timestamp), fetched via GET /signature_requests/{id}/evidence; the public verification key is published at /trust."
                    },
                    "ordered": {
                        "type": "boolean",
                        "description": "Sequential signing in the order of the signers array: each party is invited after the previous one signs, and the signing page does not accept a party before their turn."
                    },
                    "send": {
                        "type": "boolean",
                        "default": true,
                        "description": "false creates a draft that is not sent and whose signing link does not work until POST /signature_requests/{id}/send."
                    },
                    "reminders": {
                        "type": "object",
                        "description": "{\"enabled\": true} sends up to three automatic reminders to the signer whose turn has come, five days, then three days, then one day before the deadline (sent live requests only). interval_hours and max are stored and returned as sent, without being used."
                    },
                    "metadata": {
                        "type": "object"
                    }
                }
            },
            "BulkSend": {
                "type": "object",
                "required": [
                    "source",
                    "recipients"
                ],
                "properties": {
                    "source": {
                        "type": "object"
                    },
                    "recipients": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/SignerInput"
                        }
                    },
                    "legal_level": {
                        "type": "string",
                        "enum": [
                            "ses",
                            "aes",
                            "qes"
                        ]
                    },
                    "fields": {
                        "type": "object"
                    }
                }
            },
            "Signer": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "example": "sgr_123"
                    },
                    "object": {
                        "type": "string"
                    },
                    "name": {
                        "type": "string"
                    },
                    "email": {
                        "type": "string",
                        "description": "Masked for public keys (pk_): a****@example.com"
                    },
                    "phone": {
                        "type": "string",
                        "nullable": true,
                        "description": "The signer’s WhatsApp number, if any. Masked for public keys (pk_): ********5678"
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "pending",
                            "sent",
                            "viewed",
                            "otp_verified",
                            "identity_verified",
                            "signed",
                            "declined"
                        ]
                    },
                    "require_identity": {
                        "type": "boolean"
                    },
                    "identity": {
                        "type": "object",
                        "description": "Present when identity confirmation is enabled for the signer; its status changes with the signer.identity_* events.",
                        "properties": {
                            "status": {
                                "type": "string",
                                "enum": [
                                    "none",
                                    "required",
                                    "in_review",
                                    "resubmission_requested",
                                    "declined",
                                    "approved"
                                ]
                            },
                            "provider": {
                                "type": "string",
                                "example": "external"
                            },
                            "level": {
                                "type": "string",
                                "example": "aes"
                            },
                            "verification_id": {
                                "type": "string",
                                "nullable": true,
                                "example": "idv_123"
                            },
                            "reason_code": {
                                "type": "string",
                                "nullable": true,
                                "enum": [
                                    "reviewer_decision",
                                    "face_mismatch",
                                    "face_unclear",
                                    "document_expired",
                                    "document_unreadable",
                                    "document_not_original",
                                    "document_not_supported",
                                    "not_accepted",
                                    null
                                ]
                            },
                            "resubmit_steps": {
                                "type": "array",
                                "items": {
                                    "type": "string",
                                    "enum": [
                                        "document",
                                        "liveness"
                                    ]
                                }
                            },
                            "updated_at": {
                                "type": "integer",
                                "nullable": true
                            }
                        }
                    },
                    "signing_url": {
                        "type": "string",
                        "nullable": true,
                        "description": "Always emptied to null with public keys (pk_) — the only exception is the response that creates the request itself (POST /signature_requests and /bulk). To read it later, use a secret key (sk_), or create a signing session via /signers/{id}/signing_session."
                    },
                    "signed_at": {
                        "type": "integer",
                        "nullable": true
                    }
                }
            },
            "SigningSession": {
                "type": "object",
                "properties": {
                    "object": {
                        "type": "string",
                        "example": "signing_session"
                    },
                    "signer": {
                        "type": "string",
                        "example": "sgr_123"
                    },
                    "mode": {
                        "type": "string",
                        "enum": [
                            "iframe",
                            "redirect"
                        ]
                    },
                    "signing_url": {
                        "type": "string",
                        "example": "https://wthaiq.com/embed/sign/…"
                    },
                    "success_url": {
                        "type": "string",
                        "description": "Present in redirect mode only, after {signature_request} and {signer} are replaced."
                    },
                    "cancel_url": {
                        "type": "string",
                        "nullable": true,
                        "description": "Present in redirect mode only."
                    },
                    "expires_at": {
                        "type": "integer",
                        "description": "unix — 30 minutes after creation"
                    }
                }
            },
            "Event": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "example": "evt_123"
                    },
                    "object": {
                        "type": "string",
                        "example": "event"
                    },
                    "type": {
                        "type": "string",
                        "example": "signature_request.completed"
                    },
                    "created_at": {
                        "type": "integer"
                    },
                    "livemode": {
                        "type": "boolean"
                    },
                    "data": {
                        "type": "object",
                        "properties": {
                            "object": {
                                "type": "object",
                                "description": "The object affected by the event. A request object created from a workflow carries workflow_id, workflow_version, vendor_data and channel, and the signer object in signer.* events carries the first three together with signature_request (the request ID)."
                            }
                        }
                    }
                }
            },
            "IdentityVerification": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "example": "idv_123"
                    },
                    "object": {
                        "type": "string"
                    },
                    "provider": {
                        "type": "string",
                        "example": "external"
                    },
                    "signer": {
                        "type": "string",
                        "nullable": true,
                        "example": "sgr_123"
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "pending",
                            "in_review",
                            "resubmission_requested",
                            "approved",
                            "declined",
                            "expired"
                        ]
                    },
                    "level": {
                        "type": "string",
                        "example": "aes"
                    },
                    "verification_url": {
                        "type": "string",
                        "nullable": true
                    },
                    "created_at": {
                        "type": "integer",
                        "nullable": true
                    }
                }
            },
            "Verification": {
                "type": "object",
                "properties": {
                    "object": {
                        "type": "string",
                        "example": "verification"
                    },
                    "reference": {
                        "type": "string",
                        "example": "WTQ-1A2B3C4D5E6F"
                    },
                    "found": {
                        "type": "boolean"
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "completed",
                            "in_progress"
                        ]
                    },
                    "integrity": {
                        "type": "string",
                        "enum": [
                            "intact",
                            "modified",
                            "recorded",
                            "unknown"
                        ]
                    },
                    "structure": {
                        "type": "string",
                        "enum": [
                            "match",
                            "changed",
                            "absent"
                        ]
                    },
                    "document": {
                        "type": "object",
                        "properties": {
                            "title": {
                                "type": "string"
                            },
                            "sha256": {
                                "type": "string",
                                "nullable": true,
                                "description": "The recorded fingerprint. Its algorithm is given in hash_alg."
                            },
                            "hash_alg": {
                                "type": "string",
                                "enum": [
                                    "hmac-sha256",
                                    "sha256"
                                ],
                                "description": "hmac-sha256: a fingerprint of the document text keyed with a secret held by the platform (WTQ- references), matched through the verification page and not recomputable by a third party. sha256: a hash of the final file (WTH- references) that anyone can recompute."
                            },
                            "format": {
                                "type": "string",
                                "enum": [
                                    "pades-b",
                                    "pades-t",
                                    "pades-lt",
                                    "pades-lta",
                                    "platform-evidence"
                                ],
                                "description": "The PAdES signature level actually embedded in the file (when the party signs with a token); otherwise platform-evidence: a time-stamped evidence record with no signature embedded in the file."
                            },
                            "legal_level": {
                                "type": "string",
                                "enum": [
                                    "ses",
                                    "aes"
                                ]
                            }
                        }
                    },
                    "signed_at": {
                        "type": "integer",
                        "nullable": true
                    },
                    "parties": {
                        "type": "array",
                        "items": {
                            "type": "object"
                        },
                        "description": "Names and emails are always masked"
                    },
                    "events": {
                        "type": "array",
                        "items": {
                            "type": "object"
                        }
                    },
                    "qr": {
                        "type": "string"
                    }
                }
            },
            "SessionSignerInput": {
                "type": "object",
                "required": [
                    "name"
                ],
                "properties": {
                    "name": {
                        "type": "string"
                    },
                    "email": {
                        "type": "string",
                        "format": "email",
                        "description": "Required with the `email` channel. Every signer needs at least an email or a number."
                    },
                    "phone": {
                        "type": "string",
                        "example": "201012345678",
                        "description": "The signer's WhatsApp number in international format. Required with the `whatsapp` channel."
                    },
                    "type": {
                        "type": "string",
                        "enum": [
                            "individual",
                            "company"
                        ],
                        "default": "individual"
                    },
                    "fields": {
                        "type": "object",
                        "additionalProperties": {
                            "type": "string"
                        },
                        "description": "Template field values specific to this signer."
                    },
                    "access_code": {
                        "type": "string",
                        "minLength": 4,
                        "maxLength": 32,
                        "description": "An access code the signer enters before the document opens. Required when the workflow demands it; it is stored hashed and is not written in the invitation."
                    }
                }
            },
            "SessionCreate": {
                "type": "object",
                "required": [
                    "workflow_id",
                    "signers"
                ],
                "properties": {
                    "workflow_id": {
                        "type": "string",
                        "example": "wf_8f3a1c9e2b",
                        "description": "The ID of a published workflow in your account."
                    },
                    "signers": {
                        "type": "array",
                        "minItems": 1,
                        "maxItems": 20,
                        "items": {
                            "$ref": "#/components/schemas/SessionSignerInput"
                        }
                    },
                    "vendor_data": {
                        "type": "string",
                        "maxLength": 190,
                        "example": "ORD-1001",
                        "description": "Your reference in your own system. It is stored with the session, returned in its object and in webhooks, and can filter the sessions list."
                    },
                    "template_id": {
                        "type": "string",
                        "example": "tpl_123",
                        "description": "The template for the request (`tpl_` followed by the template number). Accepted when the workflow document is “Set with each request”, and required if the workflow has no default template. Refused with a fixed-template workflow."
                    },
                    "document_id": {
                        "type": "string",
                        "example": "doc_123",
                        "description": "An alternative to `template_id` for a text document in your account. Do not send both, and an uploaded PDF file is not accepted."
                    },
                    "title": {
                        "type": "string"
                    },
                    "fields": {
                        "type": "object",
                        "additionalProperties": {
                            "type": "string"
                        }
                    },
                    "metadata": {
                        "type": "object"
                    },
                    "signature_method": {
                        "type": "string",
                        "enum": [
                            "simple",
                            "identity",
                            "token"
                        ],
                        "description": "Changes the signature method for this request: `simple` an authenticated signature by drawing plus a verification code, `identity` a signature after identity verification, `token` a seal with the token certificate."
                    },
                    "channel": {
                        "type": "string",
                        "enum": [
                            "email",
                            "whatsapp",
                            "link"
                        ],
                        "description": "Changes the delivery channel of the link for this request; the verification code goes through the same channel. `whatsapp` has no extra cost, and `link` sends nothing and returns the link in the response."
                    },
                    "cc": {
                        "type": "array",
                        "maxItems": 20,
                        "items": {
                            "type": "string",
                            "format": "email"
                        },
                        "description": "Addresses that receive a copy of the contract once signing is complete. Replaces the workflow list."
                    },
                    "require_id_attachment": {
                        "type": "boolean",
                        "description": "Requires the signer to attach a photo of their ID before the signature can be completed."
                    },
                    "expires_in": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 30,
                        "description": "Link validity in days."
                    },
                    "language": {
                        "type": "string",
                        "enum": [
                            "ar",
                            "en"
                        ],
                        "description": "The language of the signing page and the invitation."
                    },
                    "return_url": {
                        "type": "string",
                        "format": "uri",
                        "maxLength": 500,
                        "nullable": true,
                        "example": "https://app.example.com/signed",
                        "description": "An `https` URL on a domain accepted on your account that the signer returns to after signing or declining. It replaces the workflow's URL for this request; an empty value or null removes it for this request."
                    }
                }
            },
            "SessionSigner": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "example": "sgr_123"
                    },
                    "name": {
                        "type": "string"
                    },
                    "email": {
                        "type": "string",
                        "nullable": true
                    },
                    "phone": {
                        "type": "string",
                        "nullable": true
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "pending",
                            "sent",
                            "viewed",
                            "otp_verified",
                            "identity_verified",
                            "signed",
                            "declined"
                        ],
                        "example": "sent"
                    },
                    "sign_url": {
                        "type": "string",
                        "nullable": true,
                        "description": "This signer's signing link. It is null while the request is a draft."
                    }
                }
            },
            "Session": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "example": "sr_123",
                        "description": "The session ID, which is the signature request ID itself."
                    },
                    "object": {
                        "type": "string",
                        "example": "session"
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "draft",
                            "sent",
                            "partially_signed",
                            "completed",
                            "declined",
                            "canceled",
                            "expired"
                        ],
                        "example": "sent"
                    },
                    "workflow_id": {
                        "type": "string",
                        "example": "wf_8f3a1c9e2b"
                    },
                    "workflow_version": {
                        "type": "integer",
                        "nullable": true,
                        "description": "The published version number the session was created with."
                    },
                    "vendor_data": {
                        "type": "string",
                        "nullable": true
                    },
                    "channel": {
                        "type": "string",
                        "enum": [
                            "email",
                            "whatsapp",
                            "link"
                        ]
                    },
                    "signers": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/SessionSigner"
                        }
                    },
                    "sign_url": {
                        "type": "string",
                        "nullable": true,
                        "description": "The signing link when there is a single signer, and null when there are several."
                    },
                    "created_at": {
                        "type": "integer"
                    },
                    "expires_at": {
                        "type": "integer",
                        "nullable": true
                    },
                    "livemode": {
                        "type": "boolean"
                    },
                    "cost": {
                        "type": "object",
                        "description": "What was charged to the wallet for this request, in its currency. 0 with a test key, and when the request counts against the plan allowance without identity checks.",
                        "properties": {
                            "amount": {
                                "type": "number"
                            },
                            "currency": {
                                "type": "string",
                                "enum": [
                                    "EGP",
                                    "USD"
                                ]
                            },
                            "source": {
                                "type": "string",
                                "nullable": true,
                                "enum": [
                                    "plan",
                                    "overage"
                                ],
                                "description": "plan = from the plan's yearly allowance; overage = from the wallet at the overage price after the allowance is used up."
                            }
                        }
                    },
                    "return_url": {
                        "type": "string",
                        "format": "uri",
                        "description": "The return URL after signing. Present only when the request has a return URL."
                    },
                    "trial": {
                        "type": "boolean",
                        "description": "true for an older live request sent as one of the free requests that were available before account verification; the field is absent otherwise."
                    }
                }
            },
            "SessionList": {
                "type": "object",
                "properties": {
                    "object": {
                        "type": "string",
                        "example": "list"
                    },
                    "data": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Session"
                        }
                    },
                    "has_more": {
                        "type": "boolean"
                    },
                    "next_cursor": {
                        "type": "string",
                        "nullable": true,
                        "description": "Send it in starting_after to fetch the next page."
                    }
                }
            },
            "SignatureRequest": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "example": "sr_123"
                    },
                    "object": {
                        "type": "string"
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "draft",
                            "sent",
                            "partially_signed",
                            "completed",
                            "declined",
                            "canceled",
                            "expired"
                        ]
                    },
                    "title": {
                        "type": "string"
                    },
                    "legal_level": {
                        "type": "string"
                    },
                    "format": {
                        "type": "string",
                        "enum": [
                            "pades-b",
                            "pades-t",
                            "pades-lt",
                            "pades-lta"
                        ],
                        "description": "The requested assurance level recorded on the object. It is not an embedded PAdES signature; the proof is the sealed evidence record (Ed25519 + RFC3161) — the public key is on /trust."
                    },
                    "signers": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Signer"
                        }
                    },
                    "reference": {
                        "type": "string",
                        "nullable": true
                    },
                    "download_url": {
                        "type": "string",
                        "nullable": true
                    },
                    "created_at": {
                        "type": "integer"
                    },
                    "completed_at": {
                        "type": "integer",
                        "nullable": true
                    },
                    "workflow_id": {
                        "type": "string",
                        "example": "wf_8f3a1c9e2b",
                        "description": "Present only on a request created from a workflow, together with workflow_version, vendor_data and channel when they have a value."
                    },
                    "workflow_version": {
                        "type": "integer",
                        "nullable": true
                    },
                    "vendor_data": {
                        "type": "string"
                    },
                    "channel": {
                        "type": "string",
                        "enum": [
                            "email",
                            "whatsapp",
                            "link"
                        ]
                    },
                    "return_url": {
                        "type": "string",
                        "format": "uri",
                        "description": "The return URL after signing. Present only when the request has a return URL."
                    },
                    "trial": {
                        "type": "boolean",
                        "description": "true for an older live request sent as one of the free requests that were available before account verification; the field is absent otherwise."
                    }
                }
            },
            "WebhookCreate": {
                "type": "object",
                "required": [
                    "url"
                ],
                "properties": {
                    "url": {
                        "type": "string",
                        "format": "uri",
                        "example": "https://api.example.com/hooks/wthaiq"
                    },
                    "enabled_events": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        },
                        "example": [
                            "*"
                        ]
                    }
                }
            },
            "WebhookEndpoint": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "example": "we_123"
                    },
                    "object": {
                        "type": "string"
                    },
                    "url": {
                        "type": "string"
                    },
                    "enabled_events": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    },
                    "secret": {
                        "type": "string",
                        "description": "Shown once at creation"
                    },
                    "status": {
                        "type": "string"
                    }
                }
            },
            "Flow": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "example": "flow_a1b2c3"
                    },
                    "object": {
                        "type": "string"
                    },
                    "name": {
                        "type": "string"
                    },
                    "template_id": {
                        "type": "string",
                        "nullable": true
                    },
                    "legal_level": {
                        "type": "string",
                        "enum": [
                            "ses",
                            "aes",
                            "qes"
                        ]
                    },
                    "reminders": {
                        "type": "boolean"
                    },
                    "lock_contract": {
                        "type": "boolean"
                    },
                    "cc": {
                        "type": "array",
                        "items": {
                            "type": "object"
                        }
                    },
                    "created_at": {
                        "type": "integer"
                    }
                }
            },
            "PdfField": {
                "type": "object",
                "required": [
                    "key",
                    "page",
                    "x",
                    "y",
                    "w",
                    "h"
                ],
                "properties": {
                    "key": {
                        "type": "string"
                    },
                    "label": {
                        "type": "string"
                    },
                    "type": {
                        "type": "string",
                        "enum": [
                            "text",
                            "number",
                            "date",
                            "email",
                            "tel",
                            "signature"
                        ]
                    },
                    "page": {
                        "type": "integer",
                        "example": 1
                    },
                    "x": {
                        "type": "number",
                        "example": 0.12
                    },
                    "y": {
                        "type": "number",
                        "example": 0.34
                    },
                    "w": {
                        "type": "number",
                        "example": 0.3
                    },
                    "h": {
                        "type": "number",
                        "example": 0.04
                    },
                    "required": {
                        "type": "boolean"
                    },
                    "signer": {
                        "type": "string"
                    }
                }
            },
            "Document": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "example": "doc_123"
                    },
                    "object": {
                        "type": "string"
                    },
                    "kind": {
                        "type": "string",
                        "enum": [
                            "pdf",
                            "contract"
                        ]
                    },
                    "filename": {
                        "type": "string"
                    },
                    "pages": {
                        "type": "integer",
                        "nullable": true
                    },
                    "bytes": {
                        "type": "integer",
                        "nullable": true
                    },
                    "sha256": {
                        "type": "string",
                        "nullable": true
                    },
                    "fields": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/PdfField"
                        }
                    },
                    "created_at": {
                        "type": "integer"
                    }
                }
            },
            "Money": {
                "type": "object",
                "properties": {
                    "amount": {
                        "type": "number"
                    },
                    "amount_minor": {
                        "type": "integer"
                    },
                    "currency": {
                        "type": "string",
                        "enum": [
                            "EGP",
                            "USD"
                        ]
                    }
                }
            },
            "Usage": {
                "type": "object",
                "properties": {
                    "object": {
                        "type": "string"
                    },
                    "balance": {
                        "$ref": "#/components/schemas/Money"
                    },
                    "month_spent": {
                        "$ref": "#/components/schemas/Money"
                    },
                    "plan": {
                        "type": "object",
                        "description": "The active plan and its yearly send allowance.",
                        "properties": {
                            "id": {
                                "type": "string",
                                "enum": [
                                    "ap_trial",
                                    "ap_dev",
                                    "ap_biz",
                                    "ap_ent",
                                    "ap_custom"
                                ]
                            },
                            "name": {
                                "type": "string"
                            },
                            "paid": {
                                "type": "boolean"
                            },
                            "period_start": {
                                "type": "integer",
                                "nullable": true
                            },
                            "period_end": {
                                "type": "integer",
                                "nullable": true
                            },
                            "sends_quota": {
                                "type": "integer"
                            },
                            "sends_used": {
                                "type": "integer"
                            },
                            "sends_left": {
                                "type": "integer"
                            },
                            "auto_renew": {
                                "type": "boolean"
                            }
                        }
                    },
                    "pricing": {
                        "type": "object",
                        "properties": {
                            "overage_per_request": {
                                "$ref": "#/components/schemas/Money"
                            },
                            "identity_per_signer": {
                                "$ref": "#/components/schemas/Money"
                            },
                            "min_topup": {
                                "$ref": "#/components/schemas/Money"
                            },
                            "currency": {
                                "type": "string"
                            }
                        }
                    },
                    "signature_requests": {
                        "type": "object"
                    }
                }
            }
        }
    }
}