openapi: 3.0.3
info:
title: SpotDraft API
version: v1
x-version: v1
x-logo:
url: https://cdn.spotdraft.com/assets/logo-black-new.png
backgroundColor: transparent
altText: SpotDraft Logo
href: https://spotdraft.com
x-favicon: https://cdn.spotdraft.com/assets/favicon.png
x-footer: © SpotDraft Inc. All rights reserved.
description: "# SpotDraft Public API\n\nWelcome to the **SpotDraft Public API**. Use this documentation to authenticate\
\ requests, choose the right product workflow, and move from guide content into the endpoint-level API reference.\n\n\
## Start here\n\nIf you are new to the API, use this sequence:\n\n1. Confirm your **regional base URL / cluster** and\
\ authentication headers.\n2. Start with one workflow: Embedded signing, Clickthrough, contract operations, or webhook\
\ ingestion.\n3. Use the **API Reference** section for endpoint schemas, request examples, and version-specific details.\n\
4. Verify redirects, authentication, errors, and webhook validation before going live.\n\n## Quick navigation\n\n| I want\
\ to... | Start here \
\ |\n| --------------------------------------------------- | ------------------------------------------------------------------------------------\
\ |\n| Authenticate requests and choose the right hostname | [Authentication](/api/docs#description/authentication) \
\ |\n| Subscribe to lifecycle events | [Webhooks](/api/docs#description/webhooks)\
\ |\n| Understand error behavior and retry logic | [Errors](/api/docs#description/errors)\
\ |\n| Embed signing inside my product | [Embedded Contract\
\ API](/api/docs#description/embedded-contract-api) |\n| Add pre-acceptance flows with the SDK \
\ | [Clickthrough SDK](/api/docs#description/clickthrough-sdk) |\n| Explore the analytics\
\ SQL catalog | [Analytics Query Table Catalog](/api/docs#description/analytics-query-table-catalog)\
\ |\n| Explore endpoint-level details | [API Reference](/api/docs#tag/v21-contract-apis) \
\ |\n\n## Versioning and conventions\n\n- SpotDraft uses **versioning in the path**.\n- Versioning\
\ is **scoped to each API family**, not to the full public API surface.\n- Different families currently expose different\
\ path versions, including `v1`, `v2`, and `v2.1`.\n- The version in the request path is the contract for that endpoint.\
\ Do not infer version availability across unrelated API families.\n- A family can expose only one documented version,\
\ even if other families expose newer-looking path versions.\n- Documentation links, tags, and operation references should\
\ match the exact versioned path shown in the schema for that endpoint.\n- Composite ids such as `T-123` or `H-123` are\
\ identifiers, not plain integers. Send them exactly as documented.\n- Datetimes are returned in ISO 8601 UTC form such\
\ as `2025-06-07T00:00:00Z`.\n- Optional fields may be omitted or returned as `null`. Rely on field names and descriptions\
\ instead of assuming presence.\n- Pagination uses `page` and `limit`. Version-specific list endpoints document any additional\
\ filters or sorting options.\n\n## Base URL and regions\n\nPick the cluster that matches where your SpotDraft workspace\
\ is provisioned. The API reference server picker exposes the same four options.\n\n| Region | Domain \
\ |\n| ------------------- | ----------------------------------- |\n| IN (India) |\
\ `https://api.in.spotdraft.com/api/` |\n| US (United States) | `https://api.us.spotdraft.com/api/` |\n| ME (Middle East)\
\ | `https://api.me.spotdraft.com/api/` |\n| EU (European Union) | `https://api.eu.spotdraft.com/api/` |\n\nAlways\
\ use **`https://`**. Keep your API calls, webhook configuration, and embedded flows in the same regional cluster where\
\ the workspace is provisioned.\n\n## Redirects\n\nThe API commonly returns **`302 Found`** in two cases:\n\n1. **HTTP\
\ instead of HTTPS**\n2. **Trailing slash mismatch**\n\nSome HTTP clients do not preserve the original method on redirect.\
\ Disable automatic redirects while debugging so you can fix the real URL issue directly.\n\n---\n\n# Authentication\n\
\nAll API requests must include a **Client ID** in the HTTP headers.\n\n## Authentication quick reference\n\n| Scenario\
\ | Required headers |\n| -------- | ---------------- |\n| Server-to-server request | `client-id`, `client-secret` |\n\
| Act on behalf of a workspace user | `client-id`, `client-secret`, `user-email` |\n| OAuth JWT request | `Authorization:\
\ Bearer <token>` |\n| OAuth JWT request to a dual CLM bearer/OAuth endpoint | `Authorization: Bearer <token>`, `X-SD-Auth-Type:\
\ oauth-jwt` |\n| Debugging auth failures | Confirm the workspace region, credential pair, and whether the impersonated\
\ user is active |\n\n## Requests as the application\n\nFor server-to-server access, send both **Client ID** and **Client\
\ Secret** in headers. SpotDraft audits these calls as the integration, not as a browser user session.\n\n### User impersonation\n\
\nYou may pass **`user-email`** with the email of a user to act on their behalf. That user must be an active member of\
\ the workspace tied to the credentials.\n\nTypical uses:\n\n- respecting per-user permissions\n- user-scoped list endpoints\n\
- audit attribution\n\nIf you omit **`user-email`**, the integration runs as the user linked to the API credentials.\n\
\nUse impersonation only when you want permission checks and audit attribution to resolve to a specific workspace user.\
\ Keep the credential pair and the selected user in the same workspace and region.\n\n## Header reference\n\n| Type |\
\ Header | Value |\n| ---- | ------ | ----- |\n| HEADER | `client-id` | string |\n| HEADER | `client-secret` | string\
\ |\n| HEADER | `user-email` | string (optional) |\n| HEADER | `Authorization` | `Bearer <token>` for OAuth JWT access\
\ |\n| HEADER | `X-SD-Auth-Type` | `oauth-jwt` when an endpoint explicitly supports both standard CLM bearer tokens and\
\ OAuth JWT bearer tokens |\n\n## OAuth JWT access\n\nOAuth-enabled routes accept a user-scoped OAuth JWT in the standard\
\ `Authorization` header:\n\n```http\nAuthorization: Bearer <token>\n```\n\nSome internal routes support both standard\
\ CLM bearer tokens and OAuth JWT bearer tokens. For those dual-auth routes, callers must opt into OAuth JWT authentication\
\ explicitly:\n\n```http\nAuthorization: Bearer <token>\nX-SD-Auth-Type: oauth-jwt\n```\n\nThis opt-in header prevents\
\ Django from treating an OAuth JWT string as a CLM bearer token before OAuth JWT authentication runs. Routes that only\
\ declare OAuth JWT authentication continue to use the standard bearer header without the opt-in header. Guide and guideline\
\ CRUD endpoints use the dual-auth pattern so existing CLM bearer-token clients continue to work while Sidebar and agent\
\ clients can call them with user-scoped OAuth JWTs.\n\n## Interactive auth in the API reference\n\nThe API reference\
\ exposes the supported auth mechanisms per endpoint:\n\n- `client-id` + `client-secret` for public API integrations\n\
- `Bearer <token>` for OAuth-enabled routes\n- `Bearer <token>` plus `X-SD-Auth-Type: oauth-jwt` for routes that explicitly\
\ support both standard CLM bearer tokens and OAuth JWT bearer tokens\n- clickthrough-specific headers on clickthrough\
\ browser endpoints\n\n`user-email` remains an optional request header for impersonation when the endpoint supports client-header\
\ authentication.\n\n## Creating credentials\n\nIn SpotDraft, open **Settings → Developer settings**, then **Generate\
\ API credential**. Copy the **Client ID** and **Client Secret** at creation time and store them in a secrets manager\
\ or password vault.\n\nIf requests fail unexpectedly, first confirm:\n\n- you are calling the correct regional cluster\n\
- the credential pair belongs to the same workspace\n- any impersonated `user-email` is active in that workspace\n\nReference:\
\ [Developer settings](https://help.spotdraft.com/articles/8632014145-developer-settings)\n\n---\n\n# Webhooks\n\nWebhooks\
\ notify **your server** when contract lifecycle events happen in SpotDraft. Register one or more **HTTPS endpoints**\
\ in **Settings → Developer settings → Webhooks**, choose the event types, and SpotDraft delivers an HTTP `POST` with\
\ a JSON payload.\n\nReturn a **`2xx`** response quickly. Queue slow work so timeouts do not count as failed deliveries.\n\
\n## Delivery requirements\n\n- **HTTPS** with a publicly trusted certificate\n- reliable endpoint behavior\n- support\
\ for multiple webhook URLs per account\n- event-type filtering so you only receive what you need\n- fast acknowledgement\
\ with asynchronous downstream processing\n\n## Verifying webhooks\n\nUse **`X-SD-WEBHOOK-CONTENT-HASH`** for verification.\
\ Validate the raw request body with **HMAC-SHA512** using the `hmac_key` returned by the HMAC key API.\n\n```python\n\
import base64\nimport hashlib\nimport hmac\n\nsignature = hmac.new(\n base64.b64decode(sample_hmac_key),\n request.body,\n\
\ digestmod=hashlib.sha512,\n).hexdigest()\n\nassert signature == request.headers[\"X-SD-WEBHOOK-CONTENT-HASH\"]\n\
```\n\nCompare against the **raw** request body bytes before any JSON parsing or normalization.\n\n## Logs and troubleshooting\n\
\nDeveloper Settings also exposes webhook logs for operational debugging. Use them to:\n\n- search deliveries by contract\
\ id\n- inspect the request payload sent by SpotDraft\n- confirm delivery failures before retrying downstream processing\n\
\nWhen investigating failures, confirm that the destination URL belongs to the same cluster strategy you use for the rest\
\ of the integration and that your endpoint returns a `2xx` quickly.\n\n## Common activity types\n\n| `activity` value\
\ | When it fires |\n| ---------------- | ------------- |\n| `CONTRACT_CREATED` | A new contract is created |\n| `CONTRACT_SENT_TO_COUNTERPARTY`\
\ | Sent for counterparty review / redlining |\n| `CONTRACT_SIGNATURE_REQUESTED` | Marked for signature |\n| `CONTRACT_SIGNED`\
\ | Any required signatory completes signing |\n| `CONTRACT_EXECUTED` | All signatures are complete |\n| `CONTRACT_PROCESS_METRIC_UPDATED`\
\ | Workflow metrics change |\n\nUse the API reference for version-specific webhook endpoints and sample payload operations.\n\
\nReference: [Developer settings](https://help.spotdraft.com/articles/8632014145-developer-settings)\n\n---\n\n# Errors\n\
\nSpotDraft uses conventional HTTP status codes so clients can branch without parsing proprietary error enums first.\n\
\n## Error handling guidance\n\n- Treat the HTTP status code as the primary branch condition.\n- Parse the response body\
\ for fields such as `detail`, `message`, `code`, or field-level validation errors.\n- Preserve the original request URL\
\ and method in logs. Redirects and trailing-slash mismatches can otherwise look like unrelated auth or validation problems.\n\
\n## HTTP status summary\n\n| Code | Meaning |\n| ---- | ------- |\n| `200` | Success |\n| `400` | Invalid or incomplete\
\ input |\n| `401` | Credentials missing, expired, or not accepted |\n| `402` | Request failed due to business-rule or\
\ workflow state |\n| `403` | Authenticated, but not allowed |\n| `404` | Resource not found or not visible to the caller\
\ |\n| `409` | Conflict, duplicate, or version mismatch |\n| `429` | Rate limited |\n| `500`, `502`, `503`, `504` | SpotDraft\
\ or upstream infrastructure error |\n\n## Retry guidance\n\n- Retry `429` and `5xx` responses with exponential backoff.\n\
- Do **not** blindly retry `4xx` responses without fixing the request.\n- Disable automatic redirect following while debugging\
\ `302` responses so URL issues are visible.\n\n---\n\n# Embedded Contract API\n\nUse the Embedded Contract flow to create\
\ contracts through the Public API and render SpotDraft’s signing experience inside your product with an iframe.\n\n##\
\ High-level flow\n\n1. Create the contract with user-supplied data.\n2. Generate a short-lived embedded URL for the counterparty.\n\
3. Render the iframe.\n4. Listen for `postMessage` events to detect completion, decline, or error states.\n\n## Step 1\
\ — Create a contract\n\nAuthenticate with your application credentials and call the **Create Contract** API using the\
\ data you collect in your product.\n\nUse a credential pair linked to the SpotDraft user who should:\n\n- receive notifications\n\
- appear as the business user when relevant\n- own the integration-level audit trail\n\n## Step 2 — Generate the embed\
\ URL\n\nUse the contract id returned by Create Contract together with the counterparty email to call the embedded URL\
\ endpoint. Treat the returned URL like a capability token: load it only for the intended user session and avoid logging\
\ it without redaction.\n\n## Step 3 — Render the iframe\n\nListen for `postMessage` events from the iframe and validate\
\ `event.origin` before trusting them.\n\n| Event | Message name | Payload |\n| ----- | ------------ | ------- |\n| Success\
\ | `spotdraft.embedded.sign_successful` | `{ contract_id }` |\n| Declined | `spotdraft.embedded.sign_declined` | `{ contract_id\
\ }` |\n| Signing error | `spotdraft.embedded.sign_error` | `{ contract_id, error: { code, upstream_error } }` |\n\n##\
\ Integration notes\n\n- Large agreements can take several seconds to render. Show a loader or skeleton state.\n- Keep\
\ API calls and embed URLs in the same region as the tenant.\n- Handle iframe close / completion without polling where\
\ possible.\n\n---\n\n# Clickthrough SDK\n\nThe **Clickthrough** JavaScript SDK lets you capture recorded acceptance of\
\ one or more agreements before a user continues with signup, checkout, or access to a gated feature.\n\n## Prerequisites\n\
\nBefore integrating, confirm the following in the SpotDraft Clickthrough console:\n\n- Clickthrough is enabled for the\
\ workspace\n- the relevant agreements are attached and published\n- your supported domains are allowlisted\n- production\
\ pages are served over HTTPS\n- you are using the snippet values for the same regional cluster as your workspace\n\n\
## Installation\n\n### NPM\n\n```bash\nnpm install @spotdraft/clickwrap-client\n```\n\n### CDN\n\n```html\n<script\n \
\ type=\"module\"\n src=\"https://sdk.spotdraft.com/clickwrap/v1/sdk.js\"\n></script>\n```\n\n## Initialization\n\n```typescript\n\
import { SdClickthrough } from \"@spotdraft/clickwrap-client\";\n\nconst clickthrough = new SdClickthrough({\n clickwrapId:\
\ \"CLICKWRAP_ID_FROM_CONSOLE\",\n hostLocationDomId: \"HOST_ELEMENT_DOM_ID\",\n baseUrl: \"BASE_URL_FROM_CONSOLE\"\
,\n});\n\nawait clickthrough.init();\n```\n\nUse the `clickwrapId` and `baseUrl` exactly as provided by the SpotDraft\
\ console snippet for that clickthrough.\nFor the latest SDK package details, installation metadata, and published package\
\ versions, use the npm package page for `@spotdraft/clickwrap-client`.\n\n## Submit payload\n\n`user_identifier` is the\
\ only required payload field for `submit(payload)`. It should uniquely identify the user in your product, such as their\
\ email address or mobile number.\n\n```typescript\nconst payload = {\n user_identifier: \"[email protected]\",\n \
\ first_name: \"John\",\n last_name: \"Doe\",\n user_email: \"[email protected]\",\n};\n```\n\n## Common methods\n\
\n| Method | Description |\n| ------ | ----------- |\n| `init()` | Mount embedded UI |\n| `isAccepted()` | Check whether\
\ required agreements are accepted |\n| `submit(payload)` | Record acceptance |\n| `openConsentDialog()` | Open modal\
\ mode |\n| `closeConsentDialog()` | Close modal mode |\n| `isReacceptanceRequired(id)` | Check whether a user must accept\
\ again |\n\n## Common events\n\n| Event | When it fires |\n| ----- | ------------- |\n| `acceptanceToggled` | Aggregate\
\ acceptance changed |\n| `acceptanceComplete` | All mandatory agreements are accepted |\n| `cancelClicked` | User dismisses\
\ the flow |\n| `sdClickthroughLoaded` | CDN SDK is ready |\n| `sdClickthroughLoadFailed` | CDN SDK failed to load |\n\
\n## Common setup issue\n\nIf the SDK returns **`Request received from invalid domain`**, the request origin is not allowlisted\
\ in Clickthrough settings. Add the full domain, including protocol such as `https://app.example.com`. `localhost` is\
\ typically allowlisted for local testing.\n\nUse the API reference for clickthrough endpoints and keep the product console’s\
\ **View snippet** output as the source of truth for tenant-specific ids and base URLs.\n\nReferences:\n\n- [@spotdraft/clickwrap-client\
\ on npm](https://www.npmjs.com/package/@spotdraft/clickwrap-client)\n- [How to Implement Clickthrough in Your Application](https://help.spotdraft.com/articles/3574375021-how-to-implement-clickthrough-in-your-application)\n\
- [How to Implement SpotDraft Clickthrough in Mobile Application](https://help.spotdraft.com/articles/9120222930-how-to-implement-spotdraft-clickthrough-in-mobile-application)\n\
\n---\n\n# Analytics Query Table Catalog\n\n**Dialect:** GoogleSQL (Google Standard SQL).\n\n---\n\n## Using this catalog\n\
\n| Topic | Behaviour |\n| --- | --- |\n| **Enablement** | The flag `PUBLIC_ANALYTICS_QUERY_API` must be enabled; otherwise\
\ the endpoint returns **501**. Contact SpotDraft support. |\n| **Endpoint** | [POST /api/v2.1/public/analytics/query/](#tag/v21-analytics-query/POST/api/v2.1/public/analytics/query/)\
\ |\n| **Column names** | Use **snake_case public** names (e.g. `execution_time`, `workflow_id`). |\n| **SQL** | Single\
\ `SELECT` (optional `WITH`, `UNION`). |\n| **Contract-scoped rows** | By default limited to contracts the user may access\
\ (server `user_access`). Optional `user_scoped` or `X-Spotdraft-Analytics-User-Scoped`; workspace-wide mode requires\
\ the workspace Admin role (see API overview). |\n\n---\n\n## Table contents\n\nJump to a table definition:\n\n- [`contracts`](#table-contracts)\n\
- [`users`](#table-users)\n- [`workflows_setup`](#table-workflows_setup)\n- [`approvals_setup`](#table-approvals_setup)\n\
- [`contract_types_setup`](#table-contract_types_setup)\n- [`counterparties_setup`](#table-counterparties_setup)\n- [`entities_setup`](#table-entities_setup)\n\
- [`signatures_setups`](#table-signatures_setups)\n- [`contract_lifecycle`](#table-contract_lifecycle)\n- [`contract_tat_details`](#table-contract_tat_details)\n\
- [`contract_sign`](#table-contract_sign)\n- [`contract_approvals`](#table-contract_approvals)\n- [`contracts_review`](#table-contracts_review)\n\
- [`signatories`](#table-signatories)\n- [`contract_level_metrics`](#table-contract_level_metrics)\n- [`contract_level_metrics_lc`](#table-contract_level_metrics_lc)\n\
- [`legal_intake`](#table-legal_intake)\n\n---\n\n## Dataset overview\n\n| Public table id | Description |\n| --- | ---\
\ |\n| `contracts` | Core fact table — one row per contract. Lifecycle timing, negotiation metrics, workflow linkage,\
\ counterparty name, entity name, and expiry. |\n| `users` | One row per user — activity, teams, licensing, and account\
\ flags. |\n| `workflows_setup` | Frozen (versioned) workflow configuration per workspace. |\n| `approvals_setup` | Approval\
\ steps configured within workflow versions. |\n| `contract_types_setup` | Contract type directory per workspace. |\n\
| `counterparties_setup` | Registered counterparties per workspace. |\n| `entities_setup` | Legal entities (customer signing\
\ companies) per workspace. |\n| `signatures_setups` | Signatory slots per workflow version. |\n| `contract_lifecycle`\
\ | Core contract register — one row per contract. Volume, status, type, expiry, counterparty, entity, workflow. |\n|\
\ `contract_tat_details` | Turnaround time per contract — one row per contract. Lifecycle stage timing, negotiation rounds,\
\ ownership. Time columns are in hours (FLOAT64). |\n| `contract_sign` | Signing-stage summary per contract — one row\
\ per contract. Signature SLA and pending-signature analysis. Time columns in hours where applicable. |\n| `contract_approvals`\
\ | Approval-step detail — one row per approval step per contract. Approval SLA and bottleneck analysis. Time columns\
\ in hours. |\n| `contracts_review` | Review-request detail — one row per review instance per contract. Legal workload\
\ and review SLA. Time columns in hours (FLOAT64). |\n| `signatories` | Individual signatory records — one row per signatory\
\ per contract. Per-signatory analytics. time_to_sign_hours is in hours (FLOAT64). |\n| `contract_level_metrics` | Event-level\
\ lifecycle tracking — multiple rows per contract. time_spent_seconds is in seconds (INT64); divide by 3600 for hours.\
\ |\n| `contract_level_metrics_lc` | Lifecycle-focused variant of contract_level_metrics — same structure without review_filter,\
\ approval_filter, sign_filter. time_spent_seconds in seconds. |\n| `legal_intake` | Legal intake requests — one row per\
\ intake item. Legal ops workload and intake SLA. |\n\nPhysical table names and cloud project or dataset identifiers are\
\ resolved server-side and are not part of this reference.\n\n---\n\n## `contracts`\n\n<a id=\"table-contracts\"></a>\n\
\nCore fact table — one row per contract. Lifecycle timing, negotiation metrics, workflow linkage, counterparty name,\
\ entity name, and expiry.\n\n### Schema\n\n| Column | Type | Nullable | Description |\n| --- | --- | --- | --- |\n| `contract_id`\
\ | `INT64` | Yes | Primary key — unique contract identifier |\n| `workspace_id` | `INT64` | Yes | Workspace this contract\
\ belongs to |\n| `contract_kind` | `STRING` | Yes | How the contract entered the system |\n| `contract_status` | `STRING`\
\ | Yes | Current lifecycle stage |\n| `contract_type_id` | `INT64` | Yes | FK to contract_types_setup |\n| `contract_type`\
\ | `STRING` | Yes | Human-readable contract type name |\n| `created_date` | `DATE` | Yes | Date the contract was created\
\ |\n| `execution_date` | `DATE` | Yes | Date the contract was fully executed |\n| `expiry_date` | `DATE` | Yes | Expiry\
\ or renewal date |\n| `term_length` | `STRING` | Yes | Contract term as text |\n| `counterparty_name` | `STRING` | Yes\
\ | Counterparty label on the contract (free text) |\n| `entity_name` | `STRING` | Yes | Signing company / entity name\
\ on the contract |\n| `redlining_starts` | `TIMESTAMP` | Yes | When redlining began |\n| `sign_starts` | `TIMESTAMP`\
\ | Yes | When signing began |\n| `sign_email_sent` | `TIMESTAMP` | Yes | When the signature request email was sent |\n\
| `draft_time` | `FLOAT64` | Yes | Days spent in Draft |\n| `redlining_time` | `FLOAT64` | Yes | Total days in Redlining\
\ |\n| `client_redlining_time` | `FLOAT64` | Yes | Days redlining on client side |\n| `counterparty_redlining_time` |\
\ `FLOAT64` | Yes | Days redlining on counterparty side |\n| `on_hold_time` | `FLOAT64` | Yes | Days spent On Hold |\n\
| `sign_nego_time` | `FLOAT64` | Yes | Days in sign negotiation |\n| `sign_time` | `FLOAT64` | Yes | Total days in Sign\
\ |\n| `sign_approvals` | `FLOAT64` | Yes | Days on sign-stage approvals |\n| `signature_collection` | `FLOAT64` | Yes\
\ | Days to collect signatures |\n| `execution_time` | `FLOAT64` | Yes | Total days from created to executed (key metric)\
\ |\n| `time_for_reviews` | `FLOAT64` | Yes | Days in internal reviews |\n| `reviews_requested` | `INT64` | Yes | Review\
\ requests made |\n| `pending_reviews` | `INT64` | Yes | Reviews still pending |\n| `client_rounds` | `INT64` | Yes |\
\ Redline rounds from client |\n| `cp_rounds` | `INT64` | Yes | Redline rounds from counterparty |\n| `turns` | `INT64`\
\ | Yes | Total negotiation turns |\n| `on_hold_rounds` | `INT64` | Yes | Times placed on hold |\n| `sign_nego_rounds`\
\ | `INT64` | Yes | Rounds of sign negotiation |\n| `contract_ageing_days` | `INT64` | Yes | Days since creation (in-flight)\
\ |\n| `sign_pending_with` | `STRING` | Yes | Who signing is pending with |\n| `total_time_to_sign_counterparty_hours`\
\ | `FLOAT64` | Yes | Hours counterparty took to sign |\n| `total_time_to_sign_company_hours` | `FLOAT64` | Yes | Hours\
\ company took to sign |\n| `pending_counterparty_signatories` | `INT64` | Yes | CP signatories yet to sign |\n| `counterparties_signatory_signed`\
\ | `INT64` | Yes | CP signatories who have signed |\n| `company_signatory_signed` | `INT64` | Yes | Company signatories\
\ who have signed |\n| `pending_company_signatories` | `INT64` | Yes | Company signatories yet to sign |\n| `frozen_workflow_id`\
\ | `INT64` | Yes | Frozen workflow snapshot at creation |\n| `workflow_title_at_creation` | `STRING` | Yes | Frozen workflow\
\ title at creation |\n| `workflow_id` | `INT64` | Yes | Current workflow id |\n| `current_workflow_title` | `STRING`\
\ | Yes | Current workflow display name |\n\n### Enum values\n\n#### `contract_status`\n\n- `Executed`\n- `Redlining`\n\
- `Sign`\n- `Draft`\n- `Voided`\n- `On Hold`\n\n#### `contract_kind`\n\n- `Externally Executed Contracts`\n- `Upload Sign\
\ Contracts`\n- `Campaign Contracts`\n- `Uploaded for review`\n- `Template Contracts`\n- `Template Contracts (Redlined)`\n\
- `Clickwrap Contracts`\n- `Express Template Contracts`\n\n#### `sign_pending_with`\n\n- `Executed`\n- `Pending with Counterparty\
\ Signatory`\n- `Pending with Company Signatory`\n- `Pending with Counterparty and Company Signatories`\n\n---\n\n## `users`\n\
\n<a id=\"table-users\"></a>\n\nOne row per user — activity, teams, licensing, and account flags.\n\n### Schema\n\n| Column\
\ | Type | Nullable | Description |\n| --- | --- | --- | --- |\n| `id` | `INT64` | Yes | Primary key (org_user_id) |\n\
| `last_activity_date` | `TIMESTAMP` | Yes | Most recent platform activity |\n| `invite_accepted` | `BOOL` | Yes | Invite\
\ accepted |\n| `first_login_date` | `TIMESTAMP` | Yes | First login time |\n| `is_active` | `BOOL` | Yes | Account active\
\ |\n| `is_deleted` | `BOOL` | Yes | Soft-deleted |\n| `created` | `TIMESTAMP` | Yes | Account created at |\n| `designation`\
\ | `STRING` | Yes | Job title / designation |\n| `created_by_workspace_id` | `INT64` | Yes | Workspace the user belongs\
\ to |\n| `teams` | `STRING` | Yes | Comma-separated team names |\n| `seniority_level` | `STRING` | Yes | Seniority band\
\ |\n| `department` | `STRING` | Yes | Department name |\n| `app_usage_purposes` | `STRING` | Yes | Stated usage purposes\
\ |\n| `licensed_user` | `BOOL` | Yes | Consumes a paid seat |\n\n---\n\n## `workflows_setup`\n\n<a id=\"table-workflows_setup\"\
></a>\n\nFrozen (versioned) workflow configuration per workspace.\n\n### Schema\n\n| Column | Type | Nullable | Description\
\ |\n| --- | --- | --- | --- |\n| `workspace_id` | `INT64` | Yes | Workspace id |\n| `frozen_workflow_id` | `INT64` |\
\ Yes | Frozen workflow snapshot id (legacy spelling in dataset) |\n| `workflow_id` | `INT64` | Yes | Parent workflow\
\ id |\n| `title` | `STRING` | Yes | Workflow display name |\n| `status` | `STRING` | Yes | PUBLISHED / UNPUBLISHED /\
\ ARCHIVED |\n| `created` | `TIMESTAMP` | Yes | Version created at |\n| `last_published` | `TIMESTAMP` | Yes | Last published\
\ at |\n| `unpublished_changes_present` | `BOOL` | Yes | Draft changes not yet published |\n| `cp_contract_download_permission`\
\ | `STRING` | Yes | Counterparty download rights |\n\n### Enum values\n\n#### `status`\n\n- `PUBLISHED`\n- `UNPUBLISHED`\n\
- `ARCHIVED`\n\n#### `cp_contract_download_permission`\n\n- `ENABLE_PDF_OR_WORD`\n- `ENABLE_PDF_ONLY`\n- `DISABLE_UNTIL_SIGNING`\n\
- `NULL`\n\n---\n\n## `approvals_setup`\n\n<a id=\"table-approvals_setup\"></a>\n\nApproval steps configured within workflow\
\ versions.\n\n### Schema\n\n| Column | Type | Nullable | Description |\n| --- | --- | --- | --- |\n| `approval_id` |\
\ `STRING` | Yes | Approval step id |\n| `approval_ver` | `STRING` | Yes | Version string |\n| `id` | `INT64` | Yes |\
\ Internal numeric id |\n| `approval_name` | `STRING` | Yes | Step display name |\n| `approval_order` | `INT64` | Yes\
\ | Sequence order |\n| `frozen_workflow_id` | `INT64` | Yes | Frozen workflow id |\n| `workflow_id` | `INT64` | Yes |\
\ Parent workflow id |\n| `workflow_name` | `STRING` | Yes | Parent workflow name |\n| `status` | `STRING` | Yes | Publication\
\ status |\n| `type` | `STRING` | Yes | TEMPLATE_WORKFLOW or UPLOAD_WORKFLOW |\n| `conditional_approval` | `BOOL` | Yes\
\ | Conditional step |\n| `workspace_id` | `INT64` | Yes | Workspace id |\n| `role_id` | `INT64` | Yes | Approver role\
\ id |\n| `skip_approval_restriction` | `BOOL` | Yes | Skip approvers allowed |\n| `download_contract_restriction` | `BOOL`\
\ | Yes | Download blocked during step |\n| `send_to_cp_restriction` | `BOOL` | Yes | Send-to-CP blocked during step |\n\
\n### Enum values\n\n#### `type`\n\n- `TEMPLATE_WORKFLOW`\n- `UPLOAD_WORKFLOW`\n\n---\n\n## `contract_types_setup`\n\n\
<a id=\"table-contract_types_setup\"></a>\n\nContract type directory per workspace.\n\n### Schema\n\n| Column | Type |\
\ Nullable | Description |\n| --- | --- | --- | --- |\n| `workspace_id` | `INT64` | Yes | Workspace id |\n| `contract_type_id`\
\ | `INT64` | Yes | Primary key |\n| `contract_type` | `STRING` | Yes | Contract type name |\n\n---\n\n## `counterparties_setup`\n\
\n<a id=\"table-counterparties_setup\"></a>\n\nRegistered counterparties per workspace.\n\n### Schema\n\n| Column | Type\
\ | Nullable | Description |\n| --- | --- | --- | --- |\n| `workspace_id` | `INT64` | Yes | Workspace id |\n| `counterparty_name`\
\ | `STRING` | Yes | Registered counterparty name |\n| `status` | `STRING` | Yes | ACTIVE / other states |\n\n---\n\n\
## `entities_setup`\n\n<a id=\"table-entities_setup\"></a>\n\nLegal entities (customer signing companies) per workspace.\n\
\n### Schema\n\n| Column | Type | Nullable | Description |\n| --- | --- | --- | --- |\n| `workspace_id` | `INT64` | Yes\
\ | Workspace id |\n| `entity_name` | `STRING` | Yes | Display name |\n| `id` | `INT64` | Yes | Entity id |\n| `created`\
\ | `TIMESTAMP` | Yes | Created at |\n| `modified` | `TIMESTAMP` | Yes | Last modified at |\n| `is_primary` | `BOOL` |\
\ Yes | Primary entity flag |\n| `is_deleted` | `BOOL` | Yes | Soft delete |\n| `jurisdiction_id` | `INT64` | Yes | Jurisdiction\
\ id |\n| `organization_id` | `INT64` | Yes | Parent organization id |\n| `organization_type_id` | `INT64` | Yes | Organization\
\ type id |\n\n---\n\n## `signatures_setups`\n\n<a id=\"table-signatures_setups\"></a>\n\nSignatory slots per workflow\
\ version.\n\n### Schema\n\n| Column | Type | Nullable | Description |\n| --- | --- | --- | --- |\n| `default_signature_id`\
\ | `INT64` | Yes | Signatory slot id |\n| `type` | `STRING` | Yes | COUNTER_PARTY or CREATOR_PARTY |\n| `name` | `STRING`\
\ | Yes | Signatory label |\n| `sign_order` | `INT64` | Yes | Signing order |\n| `created` | `TIMESTAMP` | Yes | Created\
\ at |\n| `workspace_id` | `INT64` | Yes | Workspace id |\n| `workflow_id` | `INT64` | Yes | Workflow id |\n| `conditional_signatory`\
\ | `BOOL` | Yes | Conditional signatory |\n| `conditional_routing` | `BOOL` | Yes | Conditional routing |\n\n### Enum\
\ values\n\n#### `type`\n\n- `COUNTER_PARTY`\n- `CREATOR_PARTY`\n\n---\n\n## `contract_lifecycle`\n\n<a id=\"table-contract_lifecycle\"\
></a>\n\nCore contract register — one row per contract. Volume, status, type, expiry, counterparty,
# --- truncated at 32 KB (892 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/openapi/spotdraft-openapi.yml