{
  "openapi": "3.1.0",
  "info": {
    "title": "Data Curation API",
    "description": "Transform unstructured content into AI-ready structured data. Supports text extraction, chunking, embedding generation, and PII handling.",
    "version": "0.1.0"
  },
  "paths": {
    "/health": {
      "get": {
        "tags": [
          "health"
        ],
        "summary": "Health Check",
        "description": "Lightweight liveness probe. No authentication required.",
        "operationId": "HealthCheck",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "type": "object",
                  "title": "Response Healthcheck"
                }
              }
            }
          }
        }
      }
    },
    "/health/details": {
      "get": {
        "tags": [
          "health"
        ],
        "summary": "Health Check Details",
        "description": "Authenticated endpoint returning detailed application and system stats including uptime, memory, CPU, disk, and AWS session status.",
        "operationId": "HealthCheckDetails",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "type": "object",
                  "title": "Response Healthcheckdetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "HTTPBearer": []
          }
        ]
      }
    },
    "/presign": {
      "post": {
        "tags": [
          "pipeline"
        ],
        "summary": "Generate Presigned URLs",
        "description": "Entrypoint for ad hoc data curation pipeline. Generate presigned S3 URLs to upload a file and retrieve job results.",
        "operationId": "Presign",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/SubmitOptions"
                  },
                  {
                    "type": "null"
                  }
                ],
                "title": "Body"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PresignResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error in submit options"
          },
          "500": {
            "description": "Failed to generate presigned URLs"
          },
          "503": {
            "description": "Pipeline endpoints are not available"
          }
        },
        "security": [
          {
            "HTTPBearer": []
          }
        ]
      }
    },
    "/status/{job_id}": {
      "get": {
        "tags": [
          "pipeline"
        ],
        "summary": "Get Job Status",
        "description": "Retrieve the status of a data curation job by job ID.",
        "operationId": "GetStatus",
        "security": [
          {
            "HTTPBearer": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Job Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StatusResponse"
                }
              }
            }
          },
          "404": {
            "description": "Job not found"
          },
          "500": {
            "description": "Error getting status"
          },
          "503": {
            "description": "Pipeline endpoints are not available"
          }
        }
      }
    },
    "/models": {
      "get": {
        "tags": [
          "pipeline"
        ],
        "summary": "Get Supported Embedding Models",
        "description": "Retrieve list of supported embedding models with their valid configuration settings.",
        "operationId": "GetModels",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmbeddingsResponse"
                }
              }
            }
          },
          "503": {
            "description": "Pipeline endpoints are not available"
          }
        },
        "security": [
          {
            "HTTPBearer": []
          }
        ]
      }
    },
    "/config/options": {
      "get": {
        "tags": [
          "config"
        ],
        "summary": "Get Tenant Configuration",
        "description": "Retrieve the complete configuration for the tenant including defaults, rules, and metadata.",
        "operationId": "GetConfig",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConfigResponse"
                }
              }
            }
          },
          "404": {
            "description": "Configuration not found for this tenant",
            "content": {
              "application/json": {
                "example": {
                  "error": "not_found",
                  "message": "Configuration not found for environment. Use POST /config/options to initialize."
                }
              }
            }
          },
          "500": {
            "description": "Corrupted configuration or storage error",
            "content": {
              "application/json": {
                "example": {
                  "error": "corrupted_config",
                  "message": "Configuration document is missing required fields"
                }
              }
            }
          },
          "503": {
            "description": "Config endpoints disabled or S3 service unavailable (throttling/timeouts)",
            "content": {
              "application/json": {
                "examples": {
                  "endpoints_disabled": {
                    "summary": "Endpoints disabled",
                    "value": {
                      "error": "service_unavailable",
                      "message": "Config endpoints are not available"
                    }
                  },
                  "s3_throttled": {
                    "summary": "S3 throttling/timeout",
                    "value": {
                      "error": "service_unavailable",
                      "message": "Storage service temporarily unavailable, please retry"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "HTTPBearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "config"
        ],
        "summary": "Initialize Tenant Configuration",
        "description": "Initialize a new tenant configuration with system defaults. Creates the config document in S3 with empty rules array and metadata.",
        "operationId": "InitializeConfig",
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConfigResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation failure \u2014 e.g. the configuration exceeds the maximum allowed size, or specifies a non-whitelisted image embedding model.",
            "content": {
              "application/json": {
                "example": {
                  "error": "validation_error",
                  "message": "Config size (51201 bytes) exceeds maximum allowed size (51200 bytes)."
                }
              }
            }
          },
          "409": {
            "description": "Configuration already exists for this tenant",
            "content": {
              "application/json": {
                "example": {
                  "error": "conflict",
                  "message": "Configuration already exists for this tenant."
                }
              }
            }
          },
          "500": {
            "description": "Storage error or internal server error",
            "content": {
              "application/json": {
                "example": {
                  "error": "storage_error",
                  "message": "Failed to create configuration"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable (endpoints disabled or storage temporarily unavailable)",
            "content": {
              "application/json": {
                "example": {
                  "error": "service_unavailable",
                  "message": "Config endpoints are not available"
                }
              }
            }
          }
        },
        "security": [
          {
            "HTTPBearer": []
          }
        ]
      }
    },
    "/config/options/defaults": {
      "get": {
        "tags": [
          "config"
        ],
        "summary": "Get Tenant Configuration Defaults",
        "description": "Retrieve only the defaults section of the tenant configuration.",
        "operationId": "GetConfigDefaults",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConfigResponse"
                }
              }
            }
          },
          "404": {
            "description": "Configuration not found for this tenant",
            "content": {
              "application/json": {
                "example": {
                  "error": "not_found",
                  "message": "Configuration not found for environment. Use POST /config/options to initialize."
                }
              }
            }
          },
          "500": {
            "description": "Corrupted configuration or storage error",
            "content": {
              "application/json": {
                "example": {
                  "error": "corrupted_config",
                  "message": "Configuration document is missing required 'defaults' field"
                }
              }
            }
          },
          "503": {
            "description": "Config endpoints disabled or S3 service unavailable (throttling/timeouts)",
            "content": {
              "application/json": {
                "examples": {
                  "endpoints_disabled": {
                    "summary": "Endpoints disabled",
                    "value": {
                      "error": "service_unavailable",
                      "message": "Config endpoints are not available"
                    }
                  },
                  "s3_throttled": {
                    "summary": "S3 throttling/timeout",
                    "value": {
                      "error": "service_unavailable",
                      "message": "Storage service temporarily unavailable, please retry"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "HTTPBearer": []
          }
        ]
      },
      "put": {
        "tags": [
          "config"
        ],
        "summary": "Update Tenant Configuration Defaults",
        "description": "Replace the entire defaults object with new values. The rules array is preserved unchanged.",
        "operationId": "UpdateConfigDefaults",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubmitOptions"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConfigResponse"
                }
              }
            }
          },
          "400": {
            "description": "Request body validation failure or config size exceeded",
            "content": {
              "application/json": {
                "examples": {
                  "validation_error": {
                    "summary": "Validation error",
                    "value": {
                      "message": "Input should be a valid integer"
                    }
                  },
                  "size_exceeded": {
                    "summary": "Config size exceeds 50KB limit",
                    "value": {
                      "error": "validation_error",
                      "message": "Config size (51201 bytes) exceeds maximum allowed size (51200 bytes)."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Configuration not found for environment",
            "content": {
              "application/json": {
                "example": {
                  "error": "not_found",
                  "message": "Configuration not found for environment. Use POST /config/options to initialize."
                }
              }
            }
          },
          "500": {
            "description": "Storage error or internal server error",
            "content": {
              "application/json": {
                "example": {
                  "error": "storage_error",
                  "message": "Failed to update defaults"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable (storage temporarily unavailable)",
            "content": {
              "application/json": {
                "example": {
                  "error": "service_unavailable",
                  "message": "Storage service temporarily unavailable, please retry"
                }
              }
            }
          }
        },
        "security": [
          {
            "HTTPBearer": []
          }
        ]
      },
      "delete": {
        "tags": [
          "config"
        ],
        "summary": "Reset Tenant Configuration Defaults",
        "description": "Reset defaults to system defaults. Removes tenant customizations while preserving the rules array.",
        "operationId": "ResetConfigDefaults",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConfigResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation failure \u2014 e.g. the configuration exceeds the maximum allowed size, or specifies a non-whitelisted image embedding model.",
            "content": {
              "application/json": {
                "example": {
                  "error": "validation_error",
                  "message": "Config size (51201 bytes) exceeds maximum allowed size (51200 bytes)."
                }
              }
            }
          },
          "404": {
            "description": "Configuration not found for environment",
            "content": {
              "application/json": {
                "example": {
                  "error": "not_found",
                  "message": "Configuration not found for environment. Use POST /config/options to initialize."
                }
              }
            }
          },
          "500": {
            "description": "Storage error or internal server error",
            "content": {
              "application/json": {
                "example": {
                  "error": "storage_error",
                  "message": "Failed to reset defaults"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable (storage temporarily unavailable)",
            "content": {
              "application/json": {
                "example": {
                  "error": "service_unavailable",
                  "message": "Storage service temporarily unavailable, please retry"
                }
              }
            }
          }
        },
        "security": [
          {
            "HTTPBearer": []
          }
        ]
      }
    },
    "/config/options/rules": {
      "get": {
        "tags": [
          "config"
        ],
        "summary": "Get Configuration Rules",
        "description": "Retrieve the rules collection for the tenant configuration. Returns empty array if no rules configured.",
        "operationId": "GetConfigRules",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConfigResponse"
                }
              }
            }
          },
          "404": {
            "description": "Configuration not found for this tenant",
            "content": {
              "application/json": {
                "example": {
                  "error": "not_found",
                  "message": "Configuration not found for environment. Use POST /config/options to initialize."
                }
              }
            }
          },
          "500": {
            "description": "Corrupted configuration or storage error",
            "content": {
              "application/json": {
                "example": {
                  "error": "corrupted_config",
                  "message": "Configuration document is missing required 'rules' field"
                }
              }
            }
          },
          "503": {
            "description": "Config endpoints disabled or S3 service unavailable (throttling/timeouts)",
            "content": {
              "application/json": {
                "examples": {
                  "endpoints_disabled": {
                    "summary": "Endpoints disabled",
                    "value": {
                      "error": "service_unavailable",
                      "message": "Config endpoints are not available"
                    }
                  },
                  "s3_throttled": {
                    "summary": "S3 throttling/timeout",
                    "value": {
                      "error": "service_unavailable",
                      "message": "Storage service temporarily unavailable, please retry"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "HTTPBearer": []
          }
        ]
      },
      "post": {
        "tags": [
          "config"
        ],
        "summary": "Create Configuration Rule",
        "description": "Add a new rule to the rules array. Server generates a UUID for rule_id. Returns 409 if a rule with identical conditions already exists.",
        "operationId": "CreateConfigRule",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RuleInput"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RuleCreateResponse"
                }
              }
            }
          },
          "400": {
            "description": "Request body validation failure, config validation failure, or config size exceeded",
            "content": {
              "application/json": {
                "examples": {
                  "request_validation": {
                    "summary": "Pydantic request validation error",
                    "value": {
                      "message": "Input should be a valid integer"
                    }
                  },
                  "config_validation": {
                    "summary": "SubmitOptions config validation error",
                    "value": {
                      "error": "validation_error",
                      "message": "Rule config validation failed",
                      "details": [
                        {
                          "type": "int_parsing",
                          "loc": [
                            "chunk_size"
                          ],
                          "msg": "Input should be a valid integer",
                          "input": "not-a-number"
                        }
                      ]
                    }
                  },
                  "size_exceeded": {
                    "summary": "Config size exceeds 50KB limit",
                    "value": {
                      "error": "validation_error",
                      "message": "Config size (51201 bytes) exceeds maximum allowed size (51200 bytes)."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Configuration not found for environment",
            "content": {
              "application/json": {
                "example": {
                  "error": "not_found",
                  "message": "Configuration not found for environment. Use POST /config/options to initialize."
                }
              }
            }
          },
          "409": {
            "description": "Rule with identical conditions already exists",
            "content": {
              "application/json": {
                "example": {
                  "error": "conflict",
                  "message": "A rule with identical conditions already exists."
                }
              }
            }
          },
          "500": {
            "description": "Storage error or internal server error",
            "content": {
              "application/json": {
                "example": {
                  "error": "storage_error",
                  "message": "Failed to create rule"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable (storage temporarily unavailable)",
            "content": {
              "application/json": {
                "example": {
                  "error": "service_unavailable",
                  "message": "Storage service temporarily unavailable, please retry"
                }
              }
            }
          }
        },
        "security": [
          {
            "HTTPBearer": []
          }
        ]
      }
    },
    "/config/options/rules/{rule_id}": {
      "put": {
        "tags": [
          "config"
        ],
        "summary": "Update Configuration Rule",
        "description": "Replace the rule object at the specified rule_id with new values.",
        "operationId": "UpdateConfigRule",
        "security": [
          {
            "HTTPBearer": []
          }
        ],
        "parameters": [
          {
            "name": "rule_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "title": "Rule Id"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RuleInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RuleCreateResponse"
                }
              }
            }
          },
          "400": {
            "description": "Request body validation failure, config validation failure, or config size exceeded",
            "content": {
              "application/json": {
                "examples": {
                  "config_validation": {
                    "summary": "SubmitOptions config validation error",
                    "value": {
                      "error": "validation_error",
                      "message": "Rule config validation failed",
                      "details": [
                        {
                          "type": "int_parsing",
                          "loc": [
                            "chunk_size"
                          ],
                          "msg": "Input should be a valid integer",
                          "input": "not-a-number"
                        }
                      ]
                    }
                  },
                  "size_exceeded": {
                    "summary": "Config size exceeds 50KB limit",
                    "value": {
                      "error": "validation_error",
                      "message": "Config size (51201 bytes) exceeds maximum allowed size (51200 bytes)."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Configuration or rule not found",
            "content": {
              "application/json": {
                "example": {
                  "error": "not_found",
                  "message": "Rule not found: <rule_id>"
                }
              }
            }
          },
          "409": {
            "description": "Rule with identical conditions already exists",
            "content": {
              "application/json": {
                "example": {
                  "error": "conflict",
                  "message": "A rule with identical conditions already exists.",
                  "existingRuleId": "<existing_rule_id>"
                }
              }
            }
          },
          "500": {
            "description": "Storage error or internal server error",
            "content": {
              "application/json": {
                "example": {
                  "error": "storage_error",
                  "message": "Failed to update rule"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable (storage temporarily unavailable)",
            "content": {
              "application/json": {
                "example": {
                  "error": "service_unavailable",
                  "message": "Storage service temporarily unavailable, please retry"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "config"
        ],
        "summary": "Delete Configuration Rule",
        "description": "Remove the rule with the specified rule_id from the rules array.",
        "operationId": "DeleteConfigRule",
        "security": [
          {
            "HTTPBearer": []
          }
        ],
        "parameters": [
          {
            "name": "rule_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "title": "Rule Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConfigResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation failure \u2014 e.g. the configuration exceeds the maximum allowed size, or specifies a non-whitelisted image embedding model.",
            "content": {
              "application/json": {
                "example": {
                  "error": "validation_error",
                  "message": "Config size (51201 bytes) exceeds maximum allowed size (51200 bytes)."
                }
              }
            }
          },
          "404": {
            "description": "Configuration or rule not found",
            "content": {
              "application/json": {
                "example": {
                  "error": "not_found",
                  "message": "Rule not found: <rule_id>"
                }
              }
            }
          },
          "500": {
            "description": "Storage error or internal server error",
            "content": {
              "application/json": {
                "example": {
                  "error": "storage_error",
                  "message": "Failed to delete rule"
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable (storage temporarily unavailable)",
            "content": {
              "application/json": {
                "example": {
                  "error": "service_unavailable",
                  "message": "Storage service temporarily unavailable, please retry"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "config"
        ],
        "summary": "Get Configuration Rule",
        "description": "Retrieve a single configuration rule by its UUID.",
        "operationId": "GetConfigRule",
        "security": [
          {
            "HTTPBearer": []
          }
        ],
        "parameters": [
          {
            "name": "rule_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Rule Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SingleRuleResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid rule ID format",
            "content": {
              "application/json": {
                "example": {
                  "error": "invalid_rule_id",
                  "message": "Invalid rule ID format: must be a valid UUID"
                }
              }
            }
          },
          "404": {
            "description": "Configuration or rule not found",
            "content": {
              "application/json": {
                "examples": {
                  "config_not_found": {
                    "value": {
                      "error": "not_found",
                      "message": "Configuration not found for environment. Use POST /config/options to initialize."
                    }
                  },
                  "rule_not_found": {
                    "value": {
                      "error": "rule_not_found",
                      "message": "Rule not found with id: 550e8400-e29b-41d4-a716-446655440001"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Corrupted configuration or storage error",
            "content": {
              "application/json": {
                "example": {
                  "error": "corrupted_config",
                  "message": "Configuration document is missing required 'rules' field"
                }
              }
            }
          },
          "503": {
            "description": "Config endpoints disabled or S3 service unavailable (throttling/timeouts)",
            "content": {
              "application/json": {
                "examples": {
                  "endpoints_disabled": {
                    "summary": "Endpoints disabled",
                    "value": {
                      "error": "service_unavailable",
                      "message": "Config endpoints are not available"
                    }
                  },
                  "s3_throttled": {
                    "summary": "S3 throttling/timeout",
                    "value": {
                      "error": "service_unavailable",
                      "message": "Storage service temporarily unavailable, please retry"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/config/options/rules/test": {
      "post": {
        "tags": [
          "config"
        ],
        "summary": "Test Rule Matching",
        "description": "Test document properties against tenant rules (dry run). Evaluates the given properties and returns which rule would match, along with the effective merged configuration. No state is modified.",
        "operationId": "TestRuleMatching",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": true,
                "type": "object",
                "title": "Body"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MatchResponse"
                }
              }
            }
          },
          "404": {
            "description": "Configuration not found for environment",
            "content": {
              "application/json": {
                "example": {
                  "error": "not_found",
                  "message": "Configuration not found for environment. Use POST /config/options to initialize."
                }
              }
            }
          },
          "500": {
            "description": "Internal server error (invalid stored configuration)",
            "content": {
              "application/json": {
                "example": {
                  "error": "storage_error",
                  "message": "Error loading configuration. It contains invalid data and may be malformed. Please delete and recreate it."
                }
              }
            }
          },
          "503": {
            "description": "Service unavailable (storage temporarily unavailable)",
            "content": {
              "application/json": {
                "example": {
                  "error": "service_unavailable",
                  "message": "Storage service temporarily unavailable, please retry"
                }
              }
            }
          }
        },
        "security": [
          {
            "HTTPBearer": []
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "ConfigResponse": {
        "properties": {
          "environmentId": {
            "type": "string",
            "format": "uuid",
            "title": "Environmentid",
            "description": "Environment UUID"
          },
          "effectiveConfig": {
            "additionalProperties": true,
            "type": "object",
            "title": "Effectiveconfig",
            "description": "Environment configuration (may contain defaults, rules, or both depending on endpoint)"
          },
          "lastModified": {
            "type": "string",
            "title": "Lastmodified",
            "description": "ISO-8601 timestamp of last modification"
          },
          "modifiedBy": {
            "type": "string",
            "title": "Modifiedby",
            "description": "User/service that last modified the config"
          },
          "message": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Message",
            "description": "Optional informational message (e.g., warnings about ignored configuration changes)"
          }
        },
        "type": "object",
        "required": [
          "environmentId",
          "effectiveConfig",
          "lastModified",
          "modifiedBy"
        ],
        "title": "ConfigResponse",
        "description": "Response model for config operations.\n\nReturned by all config endpoints (POST, GET, PUT, DELETE) to provide\na consistent response structure with metadata."
      },
      "EmbeddingModelInfo": {
        "properties": {
          "name": {
            "type": "string",
            "title": "Name"
          },
          "max_chunk_size": {
            "type": "integer",
            "title": "Max Chunk Size"
          },
          "supported_precisions": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Supported Precisions"
          },
          "supported_output_dimensions": {
            "items": {
              "type": "integer"
            },
            "type": "array",
            "title": "Supported Output Dimensions"
          },
          "supported_input_type": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Supported Input Type"
          }
        },
        "type": "object",
        "required": [
          "name",
          "max_chunk_size",
          "supported_precisions",
          "supported_output_dimensions",
          "supported_input_type"
        ],
        "title": "EmbeddingModelInfo",
        "description": "Information about a single embedding model."
      },
      "EmbeddingsResponse": {
        "properties": {
          "models": {
            "items": {
              "$ref": "#/components/schemas/EmbeddingModelInfo"
            },
            "type": "array",
            "title": "Models"
          }
        },
        "type": "object",
        "required": [
          "models"
        ],
        "title": "EmbeddingsResponse",
        "description": "Response model for embeddings endpoint."
      },
      "ImageConfig": {
        "properties": {
          "extract_tables": {
            "type": "boolean",
            "title": "Extract Tables",
            "default": false
          }
        },
        "additionalProperties": false,
        "type": "object",
        "title": "ImageConfig",
        "description": "Image processing configuration for OCR table detection.\n\n``extract_tables`` enables AWS Textract table detection."
      },
      "MatchResponse": {
        "properties": {
          "environmentId": {
            "type": "string",
            "format": "uuid",
            "title": "Environmentid",
            "description": "Environment UUID"
          },
          "effectiveConfig": {
            "additionalProperties": true,
            "type": "object",
            "title": "Effectiveconfig",
            "description": "Final merged config (system + environment + first matched rule)"
          },
          "environmentDefaults": {
            "additionalProperties": true,
            "type": "object",
            "title": "Environmentdefaults",
            "description": "Environment-configured defaults from S3"
          },
          "matchedRule": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/MatchedRuleInfo"
              },
              {
                "type": "null"
              }
            ],
            "description": "First rule that matched, or null"
          },
          "additionalMatches": {
            "items": {
              "$ref": "#/components/schemas/MatchedRuleInfo"
            },
            "type": "array",
            "title": "Additionalmatches",
            "description": "Other rules that also matched (overlap warning)"
          },
          "warning": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Warning",
            "description": "Warning message if multiple rules matched"
          }
        },
        "type": "object",
        "required": [
          "environmentId",
          "effectiveConfig",
          "environmentDefaults"
        ],
        "title": "MatchResponse",
        "description": "Response model for POST /config/options/rules/test."
      },
      "MatchedRuleInfo": {
        "properties": {
          "ruleId": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Ruleid",
            "description": "Rule UUID"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "Human-readable rule name"
          },
          "conditions": {
            "items": {
              "additionalProperties": {
                "type": "string"
              },
              "type": "object"
            },
            "type": "array",
            "title": "Conditions",
            "description": "Conditions that matched"
          },
          "config": {
            "additionalProperties": true,
            "type": "object",
            "title": "Config",
            "description": "Rule's config overrides"
          }
        },
        "type": "object",
        "required": [
          "conditions",
          "config"
        ],
        "title": "MatchedRuleInfo",
        "description": "Information about a matched rule in a test/dry-run response."
      },
      "PresignResponse": {
        "properties": {
          "job_id": {
            "type": "string",
            "title": "Job Id"
          },
          "put_url": {
            "type": "string",
            "title": "Put Url"
          },
          "get_url": {
            "type": "string",
            "title": "Get Url"
          },
          "options": {
            "additionalProperties": true,
            "type": "object",
            "title": "Options"
          }
        },
        "type": "object",
        "required": [
          "job_id",
          "put_url",
          "get_url",
          "options"
        ],
        "title": "PresignResponse",
        "description": "Response model for presign endpoint."
      },
      "RuleCondition": {
        "properties": {
          "field": {
            "type": "string",
            "maxLength": 255,
            "minLength": 1,
            "pattern": "^[a-zA-Z][a-zA-Z0-9_]*$",
            "title": "Field",
            "description": "Field name to match (alphanumeric + underscore, must start with letter)"
          },
          "value": {
            "type": "string",
            "maxLength": 1000,
            "minLength": 1,
            "title": "Value",
            "description": "Value to match (exact equality)"
          }
        },
        "type": "object",
        "required": [
          "field",
          "value"
        ],
        "title": "RuleCondition",
        "description": "Single condition in a rule's conditions array.\n\nValidates field name pattern to prevent injection attacks.\nField must start with letter, contain only alphanumeric + underscore.\n\nExamples:\n    >>> RuleCondition(field=\"documentType\", value=\"invoice\")\n    RuleCondition(field='documentType', value='invoice')\n\n    >>> RuleCondition(field=\"123invalid\", value=\"test\")  # doctest: +SKIP\n    ValidationError: field must match pattern ^[a-zA-Z][a-zA-Z0-9_]*$"
      },
      "RuleCreateResponse": {
        "properties": {
          "environmentId": {
            "type": "string",
            "format": "uuid",
            "title": "Environmentid",
            "description": "Environment UUID"
          },
          "effectiveConfig": {
            "additionalProperties": true,
            "type": "object",
            "title": "Effectiveconfig",
            "description": "Environment configuration (may contain defaults, rules, or both depending on endpoint)"
          },
          "lastModified": {
            "type": "string",
            "title": "Lastmodified",
            "description": "ISO-8601 timestamp of last modification"
          },
          "modifiedBy": {
            "type": "string",
            "title": "Modifiedby",
            "description": "User/service that last modified the config"
          },
          "message": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Message",
            "description": "Optional informational message (e.g., warnings about ignored configuration changes)"
          },
          "ruleId": {
            "type": "string",
            "format": "uuid",
            "title": "Ruleid",
            "description": "Generated UUID for the created rule"
          }
        },
        "type": "object",
        "required": [
          "environmentId",
          "effectiveConfig",
          "lastModified",
          "modifiedBy",
          "ruleId"
        ],
        "title": "RuleCreateResponse",
        "description": "Response model for rule creation (extends ConfigResponse).\n\nAdds ruleId field to standard ConfigResponse for rule creation endpoint."
      },
      "RuleInput": {
        "properties": {
          "name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 100
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "Optional user-friendly name for the rule"
          },
          "conditions": {
            "items": {
              "$ref": "#/components/schemas/RuleCondition"
            },
            "type": "array",
            "maxItems": 1,
            "minItems": 1,
            "title": "Conditions",
            "description": "Conditions that trigger this rule (currently limited to 1)"
          },
          "config": {
            "additionalProperties": true,
            "type": "object",
            "title": "Config",
            "description": "Configuration overrides to apply when conditions match"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "conditions",
          "config"
        ],
        "title": "RuleInput",
        "description": "Request model for creating a rule.\n\nValidates rule structure with exactly 1 condition (for CIN-12944).\nFuture stories can expand to multiple conditions (AND logic)."
      },
      "SingleRuleResponse": {
        "properties": {
          "environmentId": {
            "type": "string",
            "format": "uuid",
            "title": "Environmentid",
            "description": "Environment UUID"
          },
          "rule": {
            "additionalProperties": true,
            "type": "object",
            "title": "Rule",
            "description": "Single rule object (rule_id, name?, conditions: list, config: dict)"
          },
          "lastModified": {
            "type": "string",
            "title": "Lastmodified",
            "description": "ISO-8601 timestamp of last modification"
          },
          "modifiedBy": {
            "type": "string",
            "title": "Modifiedby",
            "description": "User/service that last modified the config"
          }
        },
        "type": "object",
        "required": [
          "environmentId",
          "rule",
          "lastModified",
          "modifiedBy"
        ],
        "title": "SingleRuleResponse",
        "description": "Response envelope for single rule endpoint.\n\nUsed by:\n- GET /config/options/rules/{rule_id}\n\nDistinct from ConfigResponse because single rule uses 'rule' field\ninstead of 'effectiveConfig' field."
      },
      "StatusResponse": {
        "properties": {
          "jobId": {
            "type": "string",
            "title": "Jobid"
          },
          "status": {
            "type": "string",
            "title": "Status"
          }
        },
        "type": "object",
        "required": [
          "jobId",
          "status"
        ],
        "title": "StatusResponse",
        "description": "Response model for status endpoint."
      },
      "SubmitChunkingOptions": {
        "properties": {
          "strategy": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "context",
                  "fixed"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Strategy"
          },
          "chunk_size": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Chunk Size"
          },
          "location_reporting": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "single",
                  "merged"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Location Reporting"
          }
        },
        "type": "object",
        "title": "SubmitChunkingOptions",
        "description": "User-submitted chunking options (excludes system-only fields)."
      },
      "SubmitEmbeddingOptions": {
        "properties": {
          "model": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Model"
          },
          "precision": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "float32",
                  "int8"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Precision"
          }
        },
        "type": "object",
        "title": "SubmitEmbeddingOptions",
        "description": "User-submitted embedding options (excludes system-only fields)."
      },
      "SubmitNormalizationOptions": {
        "properties": {
          "quotations": {
            "type": "boolean",
            "title": "Quotations",
            "default": false
          },
          "dashes": {
            "type": "boolean",
            "title": "Dashes",
            "default": false
          }
        },
        "type": "object",
        "title": "SubmitNormalizationOptions",
        "description": "User-submitted normalization options."
      },
      "SubmitOptions": {
        "properties": {
          "normalization": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SubmitNormalizationOptions"
              },
              {
                "type": "boolean",
                "const": true
              },
              {
                "type": "null"
              }
            ],
            "title": "Normalization"
          },
          "pii": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SubmitPIIOptions"
              },
              {
                "type": "boolean",
                "const": false
              },
              {
                "type": "null"
              }
            ],
            "title": "Pii"
          },
          "chunking": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SubmitChunkingOptions"
              },
              {
                "type": "boolean",
                "enum": [
                  true,
                  false
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Chunking"
          },
          "embedding": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SubmitEmbeddingOptions"
              },
              {
                "type": "boolean",
                "enum": [
                  true,
                  false
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Embedding"
          },
          "json_schema": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "FULL",
                  "MDAST",
                  "PIPELINE"
                ]
              },
              {
                "type": "boolean",
                "const": false
              },
              {
                "type": "null"
              }
            ],
            "title": "Json Schema"
          },
          "image": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ImageConfig"
              },
              {
                "type": "null"
              }
            ]
          },
          "image_embedding": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Image Embedding (Alpha)",
            "description": "\ud83d\udea7 **ALPHA** \u2013 experimental, subject to change. Generate embeddings for images."
          },
          "image_embedding_model": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Image Embedding Model (Alpha)",
            "description": "\ud83d\udea7 **ALPHA** \u2013 experimental, subject to change. Model to use for image embeddings."
          }
        },
        "additionalProperties": true,
        "type": "object",
        "title": "SubmitOptions",
        "description": "Validated user-submitted pipeline options.\n\nRepresents the user's input after normalization, legacy key mapping,\nand basic type/value validation. Does not include system-only fields\n(max_chunk_size or max_chunks_per_request).\n\nCan be used directly as a FastAPI request body model (accepts raw API\ninput with extra fields) or via ``from_dict()`` for dict-based parsing."
      },
      "SubmitPIIOptions": {
        "properties": {
          "mode": {
            "type": "string",
            "enum": [
              "detection",
              "redaction"
            ],
            "title": "Mode"
          },
          "entity_redaction": {
            "type": "boolean",
            "title": "Entity Redaction",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "mode"
        ],
        "title": "SubmitPIIOptions",
        "description": "User-submitted PII options."
      }
    },
    "securitySchemes": {
      "HTTPBearer": {
        "type": "http",
        "scheme": "bearer"
      }
    }
  },
  "tags": [
    {
      "name": "health",
      "description": "Health check and service status endpoints"
    },
    {
      "name": "pipeline",
      "description": "Document processing endpoints for ad-hoc data curation pipeline. Generate presigned S3 URLs for file upload and retrieve job status."
    },
    {
      "name": "config",
      "description": "Configuration management endpoints for Content Lake integration. Manage tenant-wide processing defaults and source-specific override rules."
    }
  ],
  "externalDocs": {
    "description": "Account Setup & Getting Started",
    "url": "https://hyland.github.io/ContentIntelligence-Docs/KnowledgeEnrichment/Overview/Getting%20Started"
  },
  "servers": [
    {
      "url": "/latest/api/data-curation"
    }
  ]
}