{
  "openapi": "3.1.0",
  "info": {
    "title": "blocksign.red API",
    "version": "0.1.0",
    "description": "Blockchain-anchored e-signatures. One API call to create, send, and verify contracts.\n\nFor a quick overview, see [/llms.txt](/llms.txt). For the full reference, see [/llms-full.txt](/llms-full.txt).",
    "contact": {
      "url": "https://blocksign.red"
    }
  },
  "servers": [
    { "url": "https://api.blocksign.red", "description": "Production" }
  ],
  "x-agent-hints": {
    "preferred_flow": "POST /v1/agent/agreements",
    "discovery": "/v1/agent/instructions",
    "supports_mcp": true,
    "llms_txt": "/llms.txt",
    "llms_full_txt": "/llms-full.txt"
  },
  "x-mcp-server": {
    "protocol_version": "2024-11-05",
    "transport": "http",
    "endpoint": "https://mcp.blocksign.red/mcp",
    "discovery": "https://mcp.blocksign.red/.well-known/mcp.json",
    "authentication": "Authorization: Bearer bsk_agent_*",
    "tools": [
      "create_agreement",
      "get_agreement_status",
      "list_agreements",
      "list_templates",
      "verify_agreement",
      "void_agreement",
      "preview_template",
      "upload_document",
      "detect_fields",
      "check_billing_status",
      "purchase_credits"
    ],
    "resources": [
      "agreement://{id}",
      "template://{slug}",
      "verification://{id}",
      "templates://catalog"
    ],
    "prompts": [
      "create_nda",
      "review_status",
      "explain_verification"
    ]
  },
  "security": [
    { "apiKey": [] },
    { "jwt": [] }
  ],
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "API key: `bsk_live_*` (full access) or `bsk_agent_*` (scoped). Pass as `Authorization: Bearer <key>`."
      },
      "jwt": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "JWT token from `POST /v1/auth/sign-in`."
      },
      "workflowToken": {
        "type": "apiKey",
        "in": "header",
        "name": "x-workflow-token",
        "description": "Scoped workflow token (`bsk_wft_*`) for agent-to-agent negotiation. 72h TTL, scoped to one envelope."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": ["error_code", "message"],
        "properties": {
          "error_code": { "type": "string", "enum": ["not_found", "unauthorized", "forbidden", "mfa_required", "email_unverified", "conflict", "validation_failed", "rate_limited", "payment_required", "internal_error"] },
          "message": { "type": "string" }
        }
      },
      "DocumentSummary": {
        "type": "object",
        "required": ["id", "title", "source_sha256_hex", "byte_length", "page_count", "mime_type"],
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "title": { "type": "string" },
          "filename": { "type": "string" },
          "source_sha256_hex": { "type": "string" },
          "byte_length": { "type": "integer" },
          "page_count": { "type": "integer" },
          "mime_type": { "type": "string" },
          "detected_fields": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/DetectedField" }
          }
        }
      },
      "DetectedField": {
        "type": "object",
        "required": ["field_type", "page", "x", "y", "w", "h", "signer_index", "confidence", "source"],
        "properties": {
          "field_type": { "type": "string", "enum": ["signature", "initials", "text", "date", "checkbox"] },
          "page": { "type": "integer" },
          "x": { "type": "number", "minimum": 0, "maximum": 1 },
          "y": { "type": "number", "minimum": 0, "maximum": 1 },
          "w": { "type": "number", "minimum": 0, "maximum": 1 },
          "h": { "type": "number", "minimum": 0, "maximum": 1 },
          "signer_index": { "type": "integer" },
          "confidence": { "type": "number" },
          "source": { "type": "string", "enum": ["ai", "heuristic", "default"] }
        }
      },
      "SignerInput": {
        "type": "object",
        "required": ["email", "name"],
        "properties": {
          "email": { "type": "string", "format": "email" },
          "name": { "type": "string" },
          "client_ref": { "type": "string" },
          "routing_order": { "type": "integer" },
          "locale": { "type": "string" },
          "auth_methods": { "type": "array", "items": { "type": "string" } },
          "fields": {
            "oneOf": [
              { "type": "string", "enum": ["auto"] },
              { "type": "array", "items": { "$ref": "#/components/schemas/FieldInput" } }
            ]
          },
          "agent_callback_url": { "type": "string", "format": "uri" },
          "agent_mcp_url": { "type": "string", "format": "uri" }
        }
      },
      "FieldInput": {
        "type": "object",
        "required": ["field_type", "page", "x", "y", "w", "h"],
        "properties": {
          "field_type": { "type": "string", "enum": ["signature", "initials", "text", "date", "checkbox"] },
          "page": { "type": "integer" },
          "x": { "type": "number" },
          "y": { "type": "number" },
          "w": { "type": "number" },
          "h": { "type": "number" },
          "signer_ref": { "type": "string" },
          "required": { "type": "boolean" },
          "label": { "type": "string" }
        }
      },
      "AgreementResponse": {
        "type": "object",
        "required": ["agreement_id", "envelope_id", "status", "verification_url", "signers"],
        "properties": {
          "agreement_id": { "type": "string", "format": "uuid" },
          "envelope_id": { "type": "string", "format": "uuid" },
          "status": { "type": "string" },
          "verification_url": { "type": "string", "format": "uri" },
          "signers": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": { "type": "string" },
                "email": { "type": "string" },
                "status": { "type": "string" },
                "signing_url": { "type": "string", "format": "uri" }
              }
            }
          }
        }
      },
      "EnvelopeResponse": {
        "type": "object",
        "properties": {
          "envelope": {
            "type": "object",
            "properties": {
              "id": { "type": "string", "format": "uuid" },
              "status": { "type": "string" }
            }
          },
          "signers": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "signer_id": { "type": "string", "format": "uuid" },
                "client_ref": { "type": "string" },
                "email": { "type": "string" },
                "signing_token": { "type": "string" },
                "signing_url": { "type": "string", "format": "uri" }
              }
            }
          }
        }
      },
      "VerifyResponse": {
        "type": "object",
        "required": ["envelope_id", "status", "event_count"],
        "properties": {
          "envelope_id": { "type": "string", "format": "uuid" },
          "status": { "type": "string" },
          "event_count": { "type": "integer" },
          "event_chain_tip_sha256_hex": { "type": "string" },
          "computed_tip_sha256_hex": { "type": "string" },
          "anchors": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "chain": { "type": "string" },
                "status": { "type": "string" },
                "tx_hash_hex": { "type": "string" },
                "block_number": { "type": "integer" }
              }
            }
          }
        }
      },
      "TemplateSummary": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "slug": { "type": "string" },
          "version": { "type": "integer" },
          "title": { "type": "string" },
          "category": { "type": "string" },
          "is_public": { "type": "boolean" },
          "org_id": { "type": "string", "format": "uuid", "nullable": true },
          "created_at": { "type": "string", "format": "date-time" }
        }
      },
      "PaymentRequiredError": {
        "type": "object",
        "properties": {
          "error": { "type": "string" },
          "message": { "type": "string" },
          "billing_status": {
            "type": "object",
            "properties": {
              "plan": { "type": "string" },
              "envelopes_used": { "type": "integer" },
              "envelopes_limit": { "type": "integer" },
              "credits_remaining": { "type": "integer" }
            }
          },
          "document_cost": {
            "type": "object",
            "description": "Present when per-document pricing applies",
            "properties": {
              "pages": { "type": "integer" },
              "amount_cents": { "type": "integer" },
              "breakdown": { "type": "string" }
            }
          },
          "actions": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "type": { "type": "string", "enum": ["pay_now", "buy_credits", "subscribe"] },
                "api": { "type": "string" },
                "body": { "type": "object" }
              }
            }
          }
        }
      }
    }
  },
  "paths": {
    "/v1/auth/sign-up": {
      "post": {
        "tags": ["Auth"],
        "summary": "Create account",
        "operationId": "signUp",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["email", "password", "name", "org_name"],
                "properties": {
                  "email": { "type": "string", "format": "email" },
                  "password": { "type": "string", "minLength": 12 },
                  "name": { "type": "string" },
                  "org_name": { "type": "string" }
                }
              }
            }
          }
        },
        "responses": {
          "201": { "description": "Account created" },
          "409": { "description": "Email already registered" }
        }
      }
    },
    "/v1/auth/sign-in": {
      "post": {
        "tags": ["Auth"],
        "summary": "Get JWT tokens",
        "operationId": "signIn",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["email", "password"],
                "properties": {
                  "email": { "type": "string", "format": "email" },
                  "password": { "type": "string" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Authentication successful",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "access_token": { "type": "string" },
                    "token_type": { "type": "string" },
                    "expires_in_secs": { "type": "integer" },
                    "org_id": { "type": "string", "format": "uuid" },
                    "user_id": { "type": "string", "format": "uuid" },
                    "region": { "type": "string" }
                  }
                }
              }
            }
          },
          "401": { "description": "Invalid credentials" }
        }
      }
    },
    "/v1/api-keys": {
      "post": {
        "tags": ["Auth"],
        "summary": "Create API key",
        "operationId": "createApiKey",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["name"],
                "properties": {
                  "name": { "type": "string" },
                  "is_agent_key": { "type": "boolean", "default": false },
                  "capabilities": {
                    "type": "array",
                    "items": { "type": "string", "enum": ["agreement.create", "agreement.read", "agreement.void", "template.use", "template.create", "document.upload", "billing.auto_purchase"] }
                  },
                  "auto_purchase_credits": { "type": "boolean", "default": false }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "API key created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": { "type": "string", "format": "uuid" },
                    "key": { "type": "string", "description": "The API key (shown only once)" },
                    "name": { "type": "string" },
                    "capabilities": { "type": "array", "items": { "type": "string" } },
                    "created_at": { "type": "string", "format": "date-time" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/documents": {
      "post": {
        "tags": ["Documents"],
        "summary": "Upload a document",
        "operationId": "uploadDocument",
        "description": "Upload a PDF, plain text, or Markdown document. Text/Markdown is converted to PDF automatically. Optionally run AI field detection.",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": ["file"],
                "properties": {
                  "file": { "type": "string", "format": "binary", "description": "PDF, text/plain, or text/markdown" },
                  "title": { "type": "string" },
                  "detect_fields": { "type": "string", "enum": ["true", "false"], "description": "Run AI field detection" },
                  "signers_count": { "type": "integer", "default": 1, "description": "Context for field detection" }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Document uploaded",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/DocumentSummary" }
              }
            }
          }
        }
      }
    },
    "/v1/documents/{id}": {
      "get": {
        "tags": ["Documents"],
        "summary": "Get document metadata",
        "operationId": "getDocument",
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
        ],
        "responses": {
          "200": {
            "description": "Document metadata",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/DocumentSummary" }
              }
            }
          }
        }
      }
    },
    "/v1/agent/agreements": {
      "post": {
        "tags": ["Agent Agreements"],
        "summary": "Create and send an agreement in one call",
        "operationId": "createAgreement",
        "description": "The recommended endpoint for agents. Four mutually exclusive input modes: template, document_text, document_base64, or document_id.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "template": { "type": "string", "description": "Template slug (e.g. 'nda'). Mutually exclusive with document_* fields." },
                  "variables": { "type": "object", "additionalProperties": { "type": "string" } },
                  "document_text": { "type": "string", "description": "Raw contract text. Mutually exclusive with template/document_base64/document_id." },
                  "document_text_format": { "type": "string", "enum": ["plain", "markdown"], "default": "plain" },
                  "document_base64": { "type": "string", "description": "Base64-encoded PDF. Mutually exclusive with other input modes." },
                  "document_id": { "type": "string", "format": "uuid", "description": "Pre-uploaded document ID." },
                  "document_title": { "type": "string" },
                  "signers": {
                    "type": "array",
                    "items": { "$ref": "#/components/schemas/SignerInput" }
                  },
                  "options": {
                    "type": "object",
                    "properties": {
                      "auto_send": { "type": "boolean", "default": true },
                      "routing_mode": { "type": "string", "enum": ["parallel", "sequential"] },
                      "expires_in_days": { "type": "integer" },
                      "webhook_url": { "type": "string", "format": "uri" }
                    }
                  }
                }
              },
              "examples": {
                "template_mode": {
                  "summary": "Create NDA from template",
                  "value": {
                    "template": "nda",
                    "variables": {
                      "party_a_name": "Acme Corp",
                      "party_a_email": "alice@acme.com",
                      "party_b_name": "Bob Smith",
                      "party_b_email": "bob@example.com",
                      "jurisdiction": "Delaware"
                    },
                    "options": { "auto_send": true }
                  }
                },
                "text_mode": {
                  "summary": "Create from Markdown text",
                  "value": {
                    "document_text": "# Services Agreement\n\nBetween {{party_a}} and {{party_b}}...\n\nSignature: _______",
                    "document_text_format": "markdown",
                    "document_title": "Services Agreement",
                    "signers": [
                      { "name": "Alice", "email": "alice@acme.com", "fields": "auto" },
                      { "name": "Bob", "email": "bob@example.com", "fields": "auto" }
                    ],
                    "options": { "auto_send": true }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Agreement created",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/AgreementResponse" }
              }
            }
          },
          "402": {
            "description": "Payment required — quota exhausted",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/PaymentRequiredError" }
              }
            }
          }
        }
      }
    },
    "/v1/agent/agreements/{id}": {
      "get": {
        "tags": ["Agent Agreements"],
        "summary": "Get agreement status",
        "operationId": "getAgreementStatus",
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
        ],
        "responses": {
          "200": {
            "description": "Agreement status",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/AgreementResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/agent/agreements/{id}/access": {
      "get": {
        "tags": ["Agent Agreements"],
        "summary": "Get presigned download URL for completed agreement",
        "operationId": "getAgreementAccess",
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
        ],
        "responses": {
          "200": {
            "description": "Access info with download URL (null if not yet completed)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "agreement_id": { "type": "string", "format": "uuid" },
                    "status": { "type": "string" },
                    "download_url": { "type": "string", "format": "uri", "nullable": true },
                    "download_expires_at": { "type": "string", "format": "date-time", "nullable": true }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/agent/agreements/{id}/counter": {
      "post": {
        "tags": ["Agent Negotiation"],
        "summary": "Submit counter-proposal",
        "operationId": "counterProposal",
        "security": [{ "apiKey": [] }, { "workflowToken": [] }],
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "body_markdown": { "type": "string" },
                  "variables": { "type": "object", "additionalProperties": true },
                  "message": { "type": "string" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Counter-proposal submitted" }
        }
      }
    },
    "/v1/agent/agreements/{id}/history": {
      "get": {
        "tags": ["Agent Negotiation"],
        "summary": "Get all proposal versions",
        "operationId": "getProposalHistory",
        "security": [{ "apiKey": [] }, { "workflowToken": [] }],
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
        ],
        "responses": {
          "200": { "description": "Proposal versions in reverse chronological order" }
        }
      }
    },
    "/v1/agent/agreements/{id}/accept": {
      "post": {
        "tags": ["Agent Negotiation"],
        "summary": "Accept current terms",
        "operationId": "acceptTerms",
        "security": [{ "apiKey": [] }, { "workflowToken": [] }],
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
        ],
        "responses": {
          "200": { "description": "Terms accepted" }
        }
      }
    },
    "/v1/agent/fields/detect": {
      "post": {
        "tags": ["AI Field Detection"],
        "summary": "Detect signature fields in a document",
        "operationId": "detectFields",
        "description": "Run AI field detection on a previously uploaded text document. 3-tier system: AI (claude-haiku) → regex heuristics → per-signer defaults.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["document_id"],
                "properties": {
                  "document_id": { "type": "string", "format": "uuid" },
                  "signers_count": { "type": "integer", "default": 1 }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Detected fields",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "document_id": { "type": "string", "format": "uuid" },
                    "fields": { "type": "array", "items": { "$ref": "#/components/schemas/DetectedField" } },
                    "detection_source": { "type": "string" },
                    "model_used": { "type": "string" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/envelopes": {
      "post": {
        "tags": ["Envelopes"],
        "summary": "Create envelope with signers and fields",
        "operationId": "createEnvelope",
        "description": "Traditional multi-step flow. Use POST /v1/agent/agreements for the simpler one-call approach.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["document_id", "title", "signers", "fields"],
                "properties": {
                  "document_id": { "type": "string", "format": "uuid" },
                  "title": { "type": "string" },
                  "routing_mode": { "type": "string", "enum": ["sequential", "parallel"] },
                  "auth_level_required": { "type": "string" },
                  "language": { "type": "string" },
                  "expires_in_days": { "type": "integer" },
                  "signers": { "type": "array", "items": { "$ref": "#/components/schemas/SignerInput" } },
                  "fields": { "type": "array", "items": { "$ref": "#/components/schemas/FieldInput" } }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Envelope created",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/EnvelopeResponse" }
              }
            }
          }
        }
      },
      "get": {
        "tags": ["Envelopes"],
        "summary": "List envelopes",
        "operationId": "listEnvelopes",
        "parameters": [
          { "name": "status", "in": "query", "schema": { "type": "string" } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 20 } },
          { "name": "offset", "in": "query", "schema": { "type": "integer", "default": 0 } }
        ],
        "responses": {
          "200": { "description": "List of envelopes" }
        }
      }
    },
    "/v1/envelopes/{id}": {
      "get": {
        "tags": ["Envelopes"],
        "summary": "Get envelope details",
        "operationId": "getEnvelope",
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
        ],
        "responses": {
          "200": { "description": "Envelope details" }
        }
      }
    },
    "/v1/envelopes/{id}/send": {
      "post": {
        "tags": ["Envelopes"],
        "summary": "Send envelope for signing",
        "operationId": "sendEnvelope",
        "description": "Dispatches signing invitations to all signers. Requires Idempotency-Key header.",
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } },
          { "name": "Idempotency-Key", "in": "header", "required": true, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": { "description": "Envelope sent" },
          "402": {
            "description": "Payment required",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/PaymentRequiredError" }
              }
            }
          }
        }
      }
    },
    "/v1/envelopes/{id}/void": {
      "post": {
        "tags": ["Envelopes"],
        "summary": "Void an envelope",
        "operationId": "voidEnvelope",
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
        ],
        "responses": {
          "200": { "description": "Envelope voided" }
        }
      }
    },
    "/v1/sign/{token}": {
      "get": {
        "tags": ["Signing Ceremony"],
        "summary": "Load signing session",
        "operationId": "getSigningSession",
        "security": [],
        "parameters": [
          { "name": "token", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": { "description": "Signing session data including document URL and fields" }
        }
      }
    },
    "/v1/sign/{token}/consent": {
      "post": {
        "tags": ["Signing Ceremony"],
        "summary": "Record signer consent",
        "operationId": "recordConsent",
        "security": [],
        "parameters": [
          { "name": "token", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["consent_text", "consent_version", "language"],
                "properties": {
                  "consent_text": { "type": "string" },
                  "consent_version": { "type": "string" },
                  "language": { "type": "string" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Consent recorded" }
        }
      }
    },
    "/v1/sign/{token}/fields": {
      "post": {
        "tags": ["Signing Ceremony"],
        "summary": "Submit filled field values",
        "operationId": "fillFields",
        "security": [],
        "parameters": [
          { "name": "token", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "fields": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": ["field_id", "value"],
                      "properties": {
                        "field_id": { "type": "string", "format": "uuid" },
                        "value": {}
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Fields filled" }
        }
      }
    },
    "/v1/sign/{token}/sign": {
      "post": {
        "tags": ["Signing Ceremony"],
        "summary": "Apply cryptographic signature",
        "operationId": "applySignature",
        "security": [],
        "parameters": [
          { "name": "token", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": { "description": "Signature applied" }
        }
      }
    },
    "/v1/verify/{envelope_id}": {
      "get": {
        "tags": ["Verification"],
        "summary": "Verify document integrity (no auth required)",
        "operationId": "verifyEnvelope",
        "security": [],
        "description": "Anyone can verify without an account. Returns the stored and recomputed audit chain tips — if they match, the document is untampered.",
        "parameters": [
          { "name": "envelope_id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
        ],
        "responses": {
          "200": {
            "description": "Verification result",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/VerifyResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/templates": {
      "get": {
        "tags": ["Templates"],
        "summary": "List available templates",
        "operationId": "listTemplates",
        "responses": {
          "200": {
            "description": "Template list",
            "content": {
              "application/json": {
                "schema": { "type": "array", "items": { "$ref": "#/components/schemas/TemplateSummary" } }
              }
            }
          }
        }
      },
      "post": {
        "tags": ["Templates"],
        "summary": "Create custom template",
        "operationId": "createTemplate",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["slug", "title", "body_markdown", "variables_schema"],
                "properties": {
                  "slug": { "type": "string" },
                  "title": { "type": "string" },
                  "category": { "type": "string" },
                  "body_markdown": { "type": "string" },
                  "variables_schema": { "type": "object" },
                  "is_public": { "type": "boolean", "default": false }
                }
              }
            }
          }
        },
        "responses": {
          "201": { "description": "Template created" }
        }
      }
    },
    "/v1/templates/{id_or_slug}": {
      "get": {
        "tags": ["Templates"],
        "summary": "Get template details",
        "operationId": "getTemplate",
        "parameters": [
          { "name": "id_or_slug", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": { "description": "Template details including body markdown and variables schema" }
        }
      }
    },
    "/v1/templates/{slug}/preview": {
      "post": {
        "tags": ["Templates"],
        "summary": "Preview template with interpolated variables",
        "operationId": "previewTemplate",
        "parameters": [
          { "name": "slug", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "variables": { "type": "object", "additionalProperties": { "type": "string" } }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Rendered preview",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "title": { "type": "string" },
                    "rendered_markdown": { "type": "string" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhook-endpoints": {
      "post": {
        "tags": ["Webhooks"],
        "summary": "Register webhook URL",
        "operationId": "createWebhookEndpoint",
        "description": "All webhook deliveries include an HMAC signature in the svix-signature header.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["url", "events"],
                "properties": {
                  "url": { "type": "string", "format": "uri" },
                  "events": {
                    "type": "array",
                    "items": { "type": "string", "enum": ["envelope.sent", "signer.opened", "signer.signed", "envelope.completed", "envelope.anchored", "envelope.voided"] }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": { "description": "Webhook endpoint registered" }
        }
      }
    },
    "/v1/billing/status": {
      "get": {
        "tags": ["Billing"],
        "summary": "Check plan, usage, and credit balance",
        "operationId": "getBillingStatus",
        "responses": {
          "200": {
            "description": "Current billing status",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "plan": { "type": "string" },
                    "envelopes_used": { "type": "integer" },
                    "envelopes_limit": { "type": "integer" },
                    "credits_remaining": { "type": "integer" },
                    "has_payment_method": { "type": "boolean" },
                    "per_document_pricing": {
                      "type": "object",
                      "properties": {
                        "base_cents": { "type": "integer", "example": 299 },
                        "per_page_over_10_cents": { "type": "integer", "example": 50 }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/billing/charge": {
      "post": {
        "tags": ["Billing"],
        "summary": "Charge per-document price for a draft envelope",
        "operationId": "chargeDocument",
        "description": "For agents with a card on file. Charges the per-document amount ($2.99 base + $0.50/page over 10) and sends the envelope in one step.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["envelope_id"],
                "properties": {
                  "envelope_id": { "type": "string", "format": "uuid" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Charge succeeded, envelope sent",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "charge_id": { "type": "string", "format": "uuid" },
                    "amount_cents": { "type": "integer" },
                    "page_count": { "type": "integer" },
                    "envelope_id": { "type": "string", "format": "uuid" },
                    "status": { "type": "string", "enum": ["sent"] }
                  }
                }
              }
            }
          },
          "402": {
            "description": "No payment method on file",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/PaymentRequiredError" }
              }
            }
          }
        }
      }
    },
    "/v1/billing/checkout": {
      "post": {
        "tags": ["Billing"],
        "summary": "Start Stripe Checkout for subscription upgrade",
        "operationId": "createCheckout",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["plan"],
                "properties": {
                  "plan": { "type": "string", "enum": ["pro", "business"] }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Checkout session",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "checkout_url": { "type": "string", "format": "uri" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/billing/credits/purchase": {
      "post": {
        "tags": ["Billing"],
        "summary": "Purchase envelope credits",
        "operationId": "purchaseCredits",
        "description": "Valid packs: 10 ($12), 50 ($50), 200 ($160). Credits never expire.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["credits"],
                "properties": {
                  "credits": { "type": "integer", "enum": [10, 50, 200] }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Credits purchased (if payment method on file) or checkout URL",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "credits_added": { "type": "integer" },
                    "balance": { "type": "integer" },
                    "checkout_url": { "type": "string", "format": "uri" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/billing/portal": {
      "post": {
        "tags": ["Billing"],
        "summary": "Get Stripe customer portal URL",
        "operationId": "getBillingPortal",
        "responses": {
          "200": {
            "description": "Portal URL",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "portal_url": { "type": "string", "format": "uri" }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "tags": [
    { "name": "Auth", "description": "Authentication and API key management" },
    { "name": "Documents", "description": "Document upload and metadata" },
    { "name": "Agent Agreements", "description": "One-call agreement creation (recommended for agents)" },
    { "name": "Agent Negotiation", "description": "Counter-proposals and multi-party negotiation" },
    { "name": "AI Field Detection", "description": "AI-powered signature field placement" },
    { "name": "Envelopes", "description": "Traditional multi-step envelope management" },
    { "name": "Signing Ceremony", "description": "Signer-facing endpoints (token-based, no API key needed)" },
    { "name": "Verification", "description": "Public document integrity verification (no auth required)" },
    { "name": "Templates", "description": "Contract templates with Markdown + variable interpolation" },
    { "name": "Webhooks", "description": "Real-time event notifications" },
    { "name": "Billing", "description": "Plans, credits, and payment management" }
  ]
}
