{
  "openapi": "3.0.3",
  "info": {
    "title": "Agreement API",
    "version": "1.0.0",
    "description": "REST API for the Agreement e-signature and document workflow platform. Authenticate with an API key (create one in Admin → API Keys) or a JWT bearer token.",
    "contact": {
      "email": "support@agreement.dev"
    },
    "license": {
      "name": "Proprietary"
    }
  },
  "servers": [
    { "url": "/api", "description": "Current server" }
  ],
  "security": [
    { "ApiKeyAuth": [] },
    { "BearerAuth": [] }
  ],
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      },
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key"
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean", "example": false },
          "error":   { "type": "string",  "example": "Not found" }
        }
      },
      "Pagination": {
        "type": "object",
        "properties": {
          "total": { "type": "integer" },
          "page":  { "type": "integer" },
          "limit": { "type": "integer" },
          "pages": { "type": "integer" }
        }
      },
      "Agreement": {
        "type": "object",
        "properties": {
          "id":             { "type": "string", "format": "uuid" },
          "title":          { "type": "string" },
          "description":    { "type": "string", "nullable": true },
          "status":         { "type": "string", "enum": ["draft","pending","completed","voided","expired"] },
          "content":        { "type": "string", "description": "HTML content with optional <!-- PAGEBREAK --> markers" },
          "signing_order":  { "type": "string", "enum": ["parallel","sequential"] },
          "expiration_date":{ "type": "string", "format": "date", "nullable": true },
          "reminder_days":  { "type": "integer", "nullable": true },
          "created_at":     { "type": "string", "format": "date-time" },
          "updated_at":     { "type": "string", "format": "date-time" },
          "recipients":     { "type": "array", "items": { "$ref": "#/components/schemas/Recipient" } }
        }
      },
      "Recipient": {
        "type": "object",
        "properties": {
          "id":           { "type": "string", "format": "uuid" },
          "name":         { "type": "string" },
          "email":        { "type": "string", "format": "email" },
          "role":         { "type": "string", "enum": ["signer","approver","cc","viewer"] },
          "status":       { "type": "string", "enum": ["pending","viewed","signed","declined"] },
          "signing_order":{ "type": "integer" },
          "color":        { "type": "string" }
        }
      },
      "Field": {
        "type": "object",
        "properties": {
          "fieldId":     { "type": "string" },
          "type":        { "type": "string", "enum": ["signature","initials","date","text","checkbox","company","title","email","phone","dropdown","radio"] },
          "recipientId": { "type": "string", "format": "uuid" },
          "label":       { "type": "string" },
          "placeholder": { "type": "string", "nullable": true },
          "required":    { "type": "boolean" },
          "pageNumber":  { "type": "integer" },
          "x":           { "type": "number" },
          "y":           { "type": "number" },
          "width":       { "type": "number" },
          "height":      { "type": "number" }
        }
      },
      "Template": {
        "type": "object",
        "properties": {
          "id":          { "type": "string", "format": "uuid" },
          "name":        { "type": "string" },
          "description": { "type": "string", "nullable": true },
          "category":    { "type": "string" },
          "content":     { "type": "string" },
          "is_system":   { "type": "boolean" },
          "usage_count": { "type": "integer" },
          "created_at":  { "type": "string", "format": "date-time" }
        }
      },
      "Webhook": {
        "type": "object",
        "properties": {
          "id":      { "type": "string", "format": "uuid" },
          "name":    { "type": "string" },
          "url":     { "type": "string", "format": "uri" },
          "events":  { "type": "array", "items": { "type": "string" } },
          "active":  { "type": "boolean" },
          "created_at": { "type": "string", "format": "date-time" }
        }
      },
      "User": {
        "type": "object",
        "properties": {
          "id":           { "type": "string", "format": "uuid" },
          "email":        { "type": "string", "format": "email" },
          "first_name":   { "type": "string" },
          "last_name":    { "type": "string" },
          "role":         { "type": "string", "enum": ["super_admin","org_admin","manager","member"] },
          "totp_enabled": { "type": "boolean" },
          "created_at":   { "type": "string", "format": "date-time" }
        }
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Missing or invalid credentials",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      },
      "NotFound": {
        "description": "Resource not found",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      },
      "BadRequest": {
        "description": "Validation error",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      }
    }
  },
  "tags": [
    { "name": "Auth",         "description": "Authentication and session management" },
    { "name": "Agreements",   "description": "Create and manage agreements" },
    { "name": "Recipients",   "description": "Manage agreement recipients" },
    { "name": "Fields",       "description": "Signature and form fields" },
    { "name": "Templates",    "description": "Reusable document templates" },
    { "name": "AI",           "description": "AI-powered document tools" },
    { "name": "Webhooks",     "description": "Outbound webhook management" },
    { "name": "Users",        "description": "User profile and team management" },
    { "name": "Notifications","description": "In-app notifications" }
  ],
  "paths": {
    "/auth/login": {
      "post": {
        "tags": ["Auth"],
        "summary": "Sign in",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["email","password"],
                "properties": {
                  "email":    { "type": "string", "format": "email" },
                  "password": { "type": "string" },
                  "totpCode": { "type": "string", "description": "Required when MFA is enabled" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Authenticated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success":      { "type": "boolean" },
                    "accessToken":  { "type": "string" },
                    "refreshToken": { "type": "string" },
                    "requiresMfa":  { "type": "boolean" },
                    "user":         { "$ref": "#/components/schemas/User" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/auth/register": {
      "post": {
        "tags": ["Auth"],
        "summary": "Create an account",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["email","password","firstName","lastName"],
                "properties": {
                  "email":     { "type": "string", "format": "email" },
                  "password":  { "type": "string", "minLength": 8 },
                  "firstName": { "type": "string" },
                  "lastName":  { "type": "string" },
                  "orgName":   { "type": "string" }
                }
              }
            }
          }
        },
        "responses": {
          "201": { "description": "Account created — verification email sent" },
          "400": { "$ref": "#/components/responses/BadRequest" }
        }
      }
    },
    "/auth/refresh": {
      "post": {
        "tags": ["Auth"],
        "summary": "Refresh access token",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["refreshToken"],
                "properties": { "refreshToken": { "type": "string" } }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "New token pair issued" },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/auth/logout": {
      "post": {
        "tags": ["Auth"],
        "summary": "Sign out",
        "responses": { "200": { "description": "Signed out" } }
      }
    },
    "/agreements": {
      "get": {
        "tags": ["Agreements"],
        "summary": "List agreements",
        "parameters": [
          { "name": "page",   "in": "query", "schema": { "type": "integer", "default": 1 } },
          { "name": "limit",  "in": "query", "schema": { "type": "integer", "default": 20 } },
          { "name": "status", "in": "query", "schema": { "type": "string", "enum": ["draft","pending","completed","voided","expired"] } },
          { "name": "search", "in": "query", "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "Paginated agreement list",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    { "$ref": "#/components/schemas/Pagination" },
                    {
                      "type": "object",
                      "properties": {
                        "data": { "type": "array", "items": { "$ref": "#/components/schemas/Agreement" } }
                      }
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": ["Agreements"],
        "summary": "Create an agreement",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["title"],
                "properties": {
                  "title":          { "type": "string" },
                  "description":    { "type": "string" },
                  "content":        { "type": "string", "description": "HTML body" },
                  "signingOrder":   { "type": "string", "enum": ["parallel","sequential"] },
                  "expirationDate": { "type": "string", "format": "date" },
                  "reminderDays":   { "type": "integer" },
                  "message":        { "type": "string" }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Agreement created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success":   { "type": "boolean" },
                    "agreement": { "$ref": "#/components/schemas/Agreement" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/agreements/{id}": {
      "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
      "get": {
        "tags": ["Agreements"],
        "summary": "Get an agreement",
        "responses": {
          "200": {
            "description": "Agreement detail",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": { "success": { "type": "boolean" }, "agreement": { "$ref": "#/components/schemas/Agreement" } }
                }
              }
            }
          },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      },
      "put": {
        "tags": ["Agreements"],
        "summary": "Update a draft agreement",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title":          { "type": "string" },
                  "description":    { "type": "string" },
                  "content":        { "type": "string" },
                  "signingOrder":   { "type": "string" },
                  "expirationDate": { "type": "string", "format": "date" },
                  "reminderDays":   { "type": "integer" },
                  "message":        { "type": "string" }
                }
              }
            }
          }
        },
        "responses": { "200": { "description": "Updated" } }
      },
      "delete": {
        "tags": ["Agreements"],
        "summary": "Delete an agreement",
        "responses": { "200": { "description": "Deleted" } }
      }
    },
    "/agreements/{id}/send": {
      "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
      "post": {
        "tags": ["Agreements"],
        "summary": "Send agreement to recipients",
        "description": "Transitions the agreement from `draft` to `pending` and emails all signers.",
        "responses": {
          "200": { "description": "Sent" },
          "400": { "$ref": "#/components/responses/BadRequest" }
        }
      }
    },
    "/agreements/{id}/void": {
      "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
      "post": {
        "tags": ["Agreements"],
        "summary": "Void an agreement",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": { "reason": { "type": "string" } }
              }
            }
          }
        },
        "responses": { "200": { "description": "Voided" } }
      }
    },
    "/agreements/{id}/remind": {
      "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
      "post": {
        "tags": ["Agreements"],
        "summary": "Send reminder emails to pending signers",
        "responses": { "200": { "description": "Reminders sent" } }
      }
    },
    "/agreements/{id}/download": {
      "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
      "get": {
        "tags": ["Agreements"],
        "summary": "Download signed PDF",
        "responses": {
          "200": {
            "description": "PDF file",
            "content": { "application/pdf": {} }
          }
        }
      }
    },
    "/agreements/{id}/recipients": {
      "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
      "post": {
        "tags": ["Recipients"],
        "summary": "Add a recipient",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["name","email"],
                "properties": {
                  "name":         { "type": "string" },
                  "email":        { "type": "string", "format": "email" },
                  "role":         { "type": "string", "enum": ["signer","approver","cc","viewer"], "default": "signer" },
                  "signingOrder": { "type": "integer" },
                  "color":        { "type": "string" }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Recipient added",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": { "success": { "type": "boolean" }, "recipient": { "$ref": "#/components/schemas/Recipient" } }
                }
              }
            }
          }
        }
      }
    },
    "/agreements/{id}/recipients/{recipientId}": {
      "parameters": [
        { "name": "id", "in": "path", "required": true, "schema": { "type": "string" } },
        { "name": "recipientId", "in": "path", "required": true, "schema": { "type": "string" } }
      ],
      "delete": {
        "tags": ["Recipients"],
        "summary": "Remove a recipient",
        "responses": { "200": { "description": "Removed" } }
      }
    },
    "/agreements/{id}/fields": {
      "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
      "post": {
        "tags": ["Fields"],
        "summary": "Save signature fields",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "fields": { "type": "array", "items": { "$ref": "#/components/schemas/Field" } }
                }
              }
            }
          }
        },
        "responses": { "200": { "description": "Fields saved" } }
      }
    },
    "/templates": {
      "get": {
        "tags": ["Templates"],
        "summary": "List templates",
        "parameters": [
          { "name": "category", "in": "query", "schema": { "type": "string" } },
          { "name": "search",   "in": "query", "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "Template list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean" },
                    "data":    { "type": "array", "items": { "$ref": "#/components/schemas/Template" } }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": ["Templates"],
        "summary": "Create a template",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["name"],
                "properties": {
                  "name":        { "type": "string" },
                  "description": { "type": "string" },
                  "category":    { "type": "string" },
                  "content":     { "type": "string" }
                }
              }
            }
          }
        },
        "responses": { "201": { "description": "Created" } }
      }
    },
    "/templates/{id}": {
      "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
      "get": {
        "tags": ["Templates"],
        "summary": "Get a template",
        "responses": { "200": { "description": "Template" }, "404": { "$ref": "#/components/responses/NotFound" } }
      },
      "put": {
        "tags": ["Templates"],
        "summary": "Update a template",
        "requestBody": {
          "content": { "application/json": { "schema": { "type": "object" } } }
        },
        "responses": { "200": { "description": "Updated" } }
      },
      "delete": {
        "tags": ["Templates"],
        "summary": "Delete a template",
        "responses": { "200": { "description": "Deleted" } }
      }
    },
    "/templates/{id}/use": {
      "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
      "post": {
        "tags": ["Templates"],
        "summary": "Create agreement from template",
        "responses": {
          "201": {
            "description": "Draft agreement created from template",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": { "success": { "type": "boolean" }, "agreement": { "$ref": "#/components/schemas/Agreement" } }
                }
              }
            }
          }
        }
      }
    },
    "/ai/generate": {
      "post": {
        "tags": ["AI"],
        "summary": "Generate an agreement",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["prompt"],
                "properties": {
                  "prompt":      { "type": "string", "description": "Plain-English description of the agreement" },
                  "category":    { "type": "string", "enum": ["nda","employment","contractor","service","saas","real_estate","partnership","purchase","privacy","terms"] },
                  "agreementId": { "type": "string", "description": "Optional — attach result to this agreement" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Generated HTML content",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success":    { "type": "boolean" },
                    "content":    { "type": "string" },
                    "tokensUsed": { "type": "integer" },
                    "model":      { "type": "string" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/ai/rewrite": {
      "post": {
        "tags": ["AI"],
        "summary": "Rewrite a clause",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["clause","instruction"],
                "properties": {
                  "clause":      { "type": "string" },
                  "instruction": { "type": "string" }
                }
              }
            }
          }
        },
        "responses": { "200": { "description": "Rewritten clause HTML" } }
      }
    },
    "/ai/explain": {
      "post": {
        "tags": ["AI"],
        "summary": "Explain a clause in plain English",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["clause"],
                "properties": { "clause": { "type": "string" } }
              }
            }
          }
        },
        "responses": { "200": { "description": "Plain-English explanation HTML" } }
      }
    },
    "/ai/summarize": {
      "post": {
        "tags": ["AI"],
        "summary": "Summarize an agreement",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["content"],
                "properties": { "content": { "type": "string" } }
              }
            }
          }
        },
        "responses": { "200": { "description": "Summary HTML" } }
      }
    },
    "/ai/detect-risks": {
      "post": {
        "tags": ["AI"],
        "summary": "Detect risks in an agreement",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["content"],
                "properties": { "content": { "type": "string" } }
              }
            }
          }
        },
        "responses": { "200": { "description": "Risk analysis HTML with severity annotations" } }
      }
    },
    "/ai/history": {
      "get": {
        "tags": ["AI"],
        "summary": "AI usage history",
        "responses": { "200": { "description": "Paginated list of AI calls" } }
      }
    },
    "/webhooks": {
      "get": {
        "tags": ["Webhooks"],
        "summary": "List webhooks",
        "responses": { "200": { "description": "Webhook list" } }
      },
      "post": {
        "tags": ["Webhooks"],
        "summary": "Create a webhook",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["name","url","events"],
                "properties": {
                  "name":   { "type": "string" },
                  "url":    { "type": "string", "format": "uri" },
                  "events": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": ["agreement.sent","agreement.viewed","agreement.signed","agreement.completed","agreement.voided","agreement.expired","recipient.signed","recipient.declined"]
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Webhook created — secret shown once",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean" },
                    "webhook": { "$ref": "#/components/schemas/Webhook" },
                    "secret":  { "type": "string", "description": "HMAC signing secret — store this, it is only shown once" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/webhooks/{id}": {
      "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }],
      "delete": {
        "tags": ["Webhooks"],
        "summary": "Delete a webhook",
        "responses": { "200": { "description": "Deleted" } }
      }
    },
    "/users/profile": {
      "get": {
        "tags": ["Users"],
        "summary": "Get current user profile",
        "responses": {
          "200": {
            "description": "User profile",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": { "success": { "type": "boolean" }, "user": { "$ref": "#/components/schemas/User" } }
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": ["Users"],
        "summary": "Update current user profile",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "firstName": { "type": "string" },
                  "lastName":  { "type": "string" }
                }
              }
            }
          }
        },
        "responses": { "200": { "description": "Updated" } }
      }
    },
    "/users": {
      "get": {
        "tags": ["Users"],
        "summary": "List org members (org admin)",
        "responses": { "200": { "description": "User list" } }
      }
    },
    "/users/invite": {
      "post": {
        "tags": ["Users"],
        "summary": "Invite a team member (org admin)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["email","firstName","lastName"],
                "properties": {
                  "email":     { "type": "string", "format": "email" },
                  "firstName": { "type": "string" },
                  "lastName":  { "type": "string" },
                  "role":      { "type": "string", "enum": ["org_admin","manager","member"] }
                }
              }
            }
          }
        },
        "responses": { "200": { "description": "Invitation sent" } }
      }
    },
    "/notifications": {
      "get": {
        "tags": ["Notifications"],
        "summary": "List notifications",
        "parameters": [
          { "name": "unread", "in": "query", "schema": { "type": "boolean" } }
        ],
        "responses": { "200": { "description": "Notification list" } }
      }
    }
  }
}
