SpotDraft Public API

The SpotDraft Public API is a unified OpenAPI 3.0.3 surface for managing contracts, templates, counterparties, approvals, metadata, obligations, versions, recipients, clickwrap agreements, webhooks, analytics, users, organizations, and workspaces. Endpoints are versioned (v1, v2, v2.1) and are served from four regional clusters (api.in.spotdraft.com, api.us.spotdraft.com, api.eu.spotdraft.com, api.me.spotdraft.com). Authentication uses Client ID + Client Secret or OAuth Bearer tokens generated from Developer Settings. The API exposes 148 paths across 48 tag groups and 211 component schemas. Webhooks deliver real-time notifications for contract lifecycle events.

SpotDraft Public API is published by SpotDraft on the APIs.io network, described by a machine-readable OpenAPI specification.

This API exposes 29 machine-runnable capabilities that can be deployed as REST, MCP, or Agent Skill surfaces via Naftiko and 6 JSON Schema definitions.

Tagged areas include Contracts, Templates, Counterparties, Approvals, and Workflows. The published artifact set on APIs.io includes API documentation, an OpenAPI specification, a JSON-LD context, rate-limit docs, sample payloads, 29 Naftiko capability specs, and 6 JSON Schemas.

Documentation

Specifications

Examples

Schemas & Data

Other Resources

🔗
JSONLD
https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/json-ld/spotdraft-context.jsonld
🔗
SpectralRuleset
https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/rules/spotdraft-rules.yml
🔗
Vocabulary
https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/vocabulary/spotdraft-vocabulary.yml
🔗
Plans
https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/plans/spotdraft-plans-pricing.yml
🔗
FinOps
https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/finops/spotdraft-finops.yml
🔗
NaftikoCapability
https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/capabilities/spotdraft-contract-apis.yaml
🔗
NaftikoCapability
https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/capabilities/spotdraft-templates.yaml
🔗
NaftikoCapability
https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/capabilities/spotdraft-counterparties.yaml
🔗
NaftikoCapability
https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/capabilities/spotdraft-contract-approvals.yaml
🔗
NaftikoCapability
https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/capabilities/spotdraft-contract-types.yaml
🔗
NaftikoCapability
https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/capabilities/spotdraft-contract-versions.yaml
🔗
NaftikoCapability
https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/capabilities/spotdraft-contract-metadata-definitions.yaml
🔗
NaftikoCapability
https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/capabilities/spotdraft-contract-metadata-values.yaml
🔗
NaftikoCapability
https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/capabilities/spotdraft-contract-external-metadata.yaml
🔗
NaftikoCapability
https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/capabilities/spotdraft-contract-notes.yaml
🔗
NaftikoCapability
https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/capabilities/spotdraft-contract-activity.yaml
🔗
NaftikoCapability
https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/capabilities/spotdraft-contract-invitations.yaml
🔗
NaftikoCapability
https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/capabilities/spotdraft-contract-obligations.yaml
🔗
NaftikoCapability
https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/capabilities/spotdraft-contract-facets.yaml
🔗
NaftikoCapability
https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/capabilities/spotdraft-recipients.yaml
🔗
NaftikoCapability
https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/capabilities/spotdraft-clickwrap.yaml
🔗
NaftikoCapability
https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/capabilities/spotdraft-webhooks.yaml
🔗
NaftikoCapability
https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/capabilities/spotdraft-analytics-query.yaml
🔗
NaftikoCapability
https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/capabilities/spotdraft-users.yaml
🔗
NaftikoCapability
https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/capabilities/spotdraft-organizations.yaml
🔗
NaftikoCapability
https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/capabilities/spotdraft-workspaces.yaml
🔗
NaftikoCapability
https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/capabilities/spotdraft-workspace-tags.yaml
🔗
NaftikoCapability
https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/capabilities/spotdraft-workspace-files.yaml
🔗
NaftikoCapability
https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/capabilities/spotdraft-tasks-and-reminders.yaml
🔗
NaftikoCapability
https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/capabilities/spotdraft-obligation-types.yaml
🔗
NaftikoCapability
https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/capabilities/spotdraft-legal-intake.yaml
🔗
NaftikoCapability
https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/capabilities/spotdraft-native-integrations.yaml
🔗
NaftikoCapability
https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/capabilities/spotdraft-emails.yaml
🔗
NaftikoCapability
https://raw.githubusercontent.com/api-evangelist/spotdraft/refs/heads/main/capabilities/spotdraft-sidebar.yaml
🔗
Webhooks
https://help.spotdraft.com/hc/en-us/articles/19587223206429-Developer-Settings

OpenAPI Specification

spotdraft-openapi.yml Raw ↑
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