{
  "openapi": "3.0.1",
  "info": {
    "title": "QC API",
    "version": "v1"
  },
  "paths": {
    "/subscriptions": {
      "get": {
        "summary": "Get all the subscriptions",
        "tags": [
          "Subscriptions"
        ],
        "description": "Use this endpoint to retrieve all the subscriptions your company is subscribing to.",
        "operationId": "GetSubscriptions",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "successful",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/get_subscriptions_response"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized. The Authorization header was missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "properties": {
                        "length": {
                          "type": "integer"
                        }
                      },
                      "items": {
                        "type": "object",
                        "properties": {
                          "status": {
                            "type": "string",
                            "example": "401"
                          },
                          "title": {
                            "type": "string",
                            "example": "Unauthorized"
                          },
                          "detail": {
                            "type": "string",
                            "example": "Authorization is invalid"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create a subscription",
        "tags": [
          "Subscriptions"
        ],
        "description": "Use this endpoint to set up a webhook subscription.",
        "operationId": "CreateSubscription",
        "parameters": [],
        "responses": {
          "201": {
            "description": "successful",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/subscription"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized. The Authorization header was missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "properties": {
                        "length": {
                          "type": "integer"
                        }
                      },
                      "items": {
                        "type": "object",
                        "properties": {
                          "status": {
                            "type": "string",
                            "example": "401"
                          },
                          "title": {
                            "type": "string",
                            "example": "Unauthorized"
                          },
                          "detail": {
                            "type": "string",
                            "example": "Authorization is invalid"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "Invalid attribute(s)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "properties": {
                        "length": {
                          "type": "integer"
                        }
                      },
                      "items": {
                        "type": "object",
                        "properties": {
                          "status": {
                            "type": "string",
                            "example": "422"
                          },
                          "pointer": {
                            "type": "string",
                            "example": "/webhook_url"
                          },
                          "title": {
                            "type": "string",
                            "example": "Missing Attribute"
                          },
                          "detail": {
                            "type": "string",
                            "example": "Webhook URL can't be blank"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/new_subscription"
              }
            }
          }
        }
      }
    },
    "/subscriptions/{id}": {
      "delete": {
        "summary": "Delete a subscription",
        "tags": [
          "Subscriptions"
        ],
        "description": "Use this endpoint to remove a subscription. If the call is successful, return a 200 successful status code.",
        "operationId": "DeleteSubscription",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "70c35b16-08c8-4e0a-beee-32a02812aa07",
              "description": "The unique identifier for this subscription."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "successful"
          },
          "401": {
            "description": "Unauthorized. The Authorization header was missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "properties": {
                        "length": {
                          "type": "integer"
                        }
                      },
                      "items": {
                        "type": "object",
                        "properties": {
                          "status": {
                            "type": "string",
                            "example": "401"
                          },
                          "title": {
                            "type": "string",
                            "example": "Unauthorized"
                          },
                          "detail": {
                            "type": "string",
                            "example": "Authorization is invalid"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "not found"
          },
          "422": {
            "description": "Invalid Attribute",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "properties": {
                        "length": {
                          "type": "integer"
                        }
                      },
                      "items": {
                        "type": "object",
                        "properties": {
                          "status": {
                            "type": "string",
                            "example": "422"
                          },
                          "pointer": {
                            "type": "string",
                            "example": "/id"
                          },
                          "title": {
                            "type": "string",
                            "example": "Invalid Attribute"
                          },
                          "detail": {
                            "type": "string",
                            "example": "id is invalid"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {}
            }
          }
        }
      }
    },
    "/subscriptions/{id}/events": {
      "post": {
        "summary": "Add events to a subscription",
        "tags": [
          "Subscriptions"
        ],
        "description": "Use this endpoint to update events on a webhook subscription.",
        "operationId": "AddSubscriptionEvents",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "70c35b16-08c8-4e0a-beee-32a02812aa07",
              "description": "The unique identifier for this subscription."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "successful",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/subscription"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized. The Authorization header was missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "properties": {
                        "length": {
                          "type": "integer"
                        }
                      },
                      "items": {
                        "type": "object",
                        "properties": {
                          "status": {
                            "type": "string",
                            "example": "401"
                          },
                          "title": {
                            "type": "string",
                            "example": "Unauthorized"
                          },
                          "detail": {
                            "type": "string",
                            "example": "Authorization is invalid"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "subscription not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "status": {
                            "type": "string",
                            "example": "404"
                          },
                          "title": {
                            "type": "string",
                            "example": "Not found"
                          },
                          "detail": {
                            "type": "string",
                            "example": "Unable to find subscription."
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "Invalid attribute(s)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "properties": {
                        "length": {
                          "type": "integer"
                        }
                      },
                      "items": {
                        "type": "object",
                        "properties": {
                          "status": {
                            "type": "string",
                            "example": "422"
                          },
                          "pointer": {
                            "type": "string",
                            "example": "/events"
                          },
                          "title": {
                            "type": "string",
                            "example": "Invalid Attribute"
                          },
                          "detail": {
                            "type": "string",
                            "example": "must be an array"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/new_subscription_event"
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete events from a subscription",
        "tags": [
          "Subscriptions"
        ],
        "description": "Use this endpoint to remove a events from a subscription. If the call is successful, return a 200 successful status code.",
        "operationId": "DeleteSubscriptionEvents",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "70c35b16-08c8-4e0a-beee-32a02812aa07",
              "description": "The unique identifier for this subscription."
            }
          },
          {
            "name": "name",
            "in": "query",
            "schema": {
              "type": "string",
              "example": "closing.completed,closing.canceled",
              "description": "Name of events to be deleted."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "successful"
          },
          "401": {
            "description": "Unauthorized. The Authorization header was missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "properties": {
                        "length": {
                          "type": "integer"
                        }
                      },
                      "items": {
                        "type": "object",
                        "properties": {
                          "status": {
                            "type": "string",
                            "example": "401"
                          },
                          "title": {
                            "type": "string",
                            "example": "Unauthorized"
                          },
                          "detail": {
                            "type": "string",
                            "example": "Authorization is invalid"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "subscription not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "status": {
                            "type": "string",
                            "example": "404"
                          },
                          "title": {
                            "type": "string",
                            "example": "Not found"
                          },
                          "detail": {
                            "type": "string",
                            "example": "Unable to find subscription."
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "invalid events",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "status": {
                            "type": "string",
                            "example": "422"
                          },
                          "title": {
                            "type": "string",
                            "example": "Invalid events"
                          },
                          "detail": {
                            "type": "string",
                            "example": "Invalid events."
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {}
            }
          }
        }
      }
    },
    "/qc/packages/{uuid}/documents/upload-url": {
      "parameters": [
        {
          "name": "uuid",
          "in": "path",
          "description": "Package UUID",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "filename",
          "in": "query",
          "description": "Upload file name",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "summary": "Get presigned upload URL",
        "tags": [
          "Packages"
        ],
        "operationId": "GetPresignedUploadUrl",
        "description": "Use this endpoint to get a presigned URL to upload documents to review. Use this URL to upload documents via the upload documents endpoint (POST /packages/{uuid}/documents). The URL expires after 10 minutes.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Presigned URL retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "url": {
                      "type": "string",
                      "description": "Presigned URL for uploading documents. The URL expires after 10 minutes."
                    }
                  },
                  "required": [
                    "url"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Missing required parameter",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "detail": {
                            "type": "string"
                          },
                          "status": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden - insufficient scope",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "detail": {
                            "type": "string"
                          },
                          "status": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  },
                  "example": {
                    "errors": [
                      {
                        "detail": "Insufficient scope",
                        "status": 403
                      }
                    ]
                  }
                }
              }
            }
          },
          "404": {
            "description": "Package not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "detail": {
                            "type": "string"
                          },
                          "status": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "detail": {
                            "type": "string"
                          },
                          "status": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/qc/packages/{uuid}/documents": {
      "parameters": [
        {
          "name": "uuid",
          "in": "path",
          "description": "Package UUID",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "summary": "Download classified signed documents",
        "tags": [
          "Packages"
        ],
        "description": "Use this endpoint to retrieve each classified documents. Snapdocs QC will split out\neach document in the signed package (e.g., Closing Disclosure, Note, and Mortgage are now\nseparate documents) for you to index into your LOS directory.\n\n**Document types:** To download classified signed closing documents,\nuse the 'funding' document type.\n\n| Document type | What it returns | Customer type |\n|---|---|---|\n| **funding** | Classified signed closing documents | Lender using Post-Close QC |\n| **imported** | Origination documents uploaded into Upload Documents endpoint | N/A |\n| **pre_close** | Classified pre-close documents (e.g., appraisal waiver disclosure, title report) | Lender using Pre-Close QC |\n| **title** | Classified signed closing documents | Title company using Notary Connect & Title QC |\n| **trailing** | Classified trailing documents (e.g., recorded documents, final title policy) | Lender using Trailing Documents |\n",
        "parameters": [
          {
            "name": "report_type",
            "in": "query",
            "required": false,
            "description": "Document type",
            "schema": {
              "type": "string",
              "enum": [
                "funding",
                "imported",
                "pre_close",
                "title",
                "trailing"
              ],
              "default": "funding"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Documents returned",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "integer",
                        "description": "A unique identifier for the document"
                      },
                      "display_name": {
                        "type": "string",
                        "description": "The display name for the document (\"Mortgage or Deed of Trust\")"
                      },
                      "internal_name": {
                        "type": "string",
                        "description": "The internal name for the document (\"deed_of_trust\")"
                      },
                      "unclassified": {
                        "type": "boolean",
                        "description": "If true, this is an unclassified document"
                      },
                      "url": {
                        "type": "string",
                        "format": "url",
                        "description": "A URL from which the document can be fetched"
                      },
                      "deleted": {
                        "type": "boolean",
                        "description": "If true, this document is no longer active"
                      },
                      "created_at": {
                        "type": "string",
                        "format": "date-time",
                        "description": "When the classified document was created, in ISO 8601 format"
                      }
                    },
                    "required": [
                      "id",
                      "display_name",
                      "internal_name",
                      "unclassified",
                      "url",
                      "created_at"
                    ]
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden - insufficient scope",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "detail": {
                            "type": "string"
                          },
                          "status": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  },
                  "example": {
                    "errors": [
                      {
                        "detail": "Insufficient scope",
                        "status": 403
                      }
                    ]
                  }
                }
              }
            }
          },
          "404": {
            "description": "Package not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "detail": {
                            "type": "string"
                          },
                          "status": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "detail": {
                            "type": "string"
                          },
                          "status": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Upload documents to review",
        "tags": [
          "Packages"
        ],
        "operationId": "UploadDocuments",
        "description": "Use this endpoint to upload non-closing documents that are required for QC review. For\nexample, in a post-close review a post-closer will typically review non-closing documents\nsuch as the 1008 Transmittal, Appraisal, and Underwriting Decision. Each document must have\na presigned URL and internal_name. Upload as many documents in the documents object that\nare available for that closing. If there are multiple individual PDFs for a given document,\nyou can either upload each individual PDF to an individual URL or combine the PDFs and\nupload to a single URL.\n\n**Which internal_name values can I send?** Call\n[List document types](ref:ListDocumentTypes) — it returns every\naccepted value. Sending one that is not on that list returns `400`.\n\nGet each `url` from\n[Get presigned upload URL](ref:GetPresignedUploadUrl)\nand `PUT` the file to it before calling this endpoint.\n",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Documents validated and enqueued successfully"
          },
          "400": {
            "description": "Bad request - invalid document format",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "detail": {
                            "type": "string"
                          },
                          "status": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden - insufficient scope",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "detail": {
                            "type": "string"
                          },
                          "status": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  },
                  "example": {
                    "errors": [
                      {
                        "detail": "Insufficient scope",
                        "status": 403
                      }
                    ]
                  }
                }
              }
            }
          },
          "404": {
            "description": "Package not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "detail": {
                            "type": "string"
                          },
                          "status": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "detail": {
                            "type": "string"
                          },
                          "status": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "documents": {
                    "type": "array",
                    "description": "Array of documents that were uploaded via presigned URLs",
                    "items": {
                      "type": "object",
                      "properties": {
                        "url": {
                          "type": "string",
                          "description": "URL of the uploaded document (presigned URL or S3 path)"
                        },
                        "internal_name": {
                          "allOf": [
                            {
                              "$ref": "#/components/schemas/internalNames"
                            }
                          ],
                          "description": "What kind of document this is, so QC reviews it against the right requirements — e.g. `1008_transmittal`, `appraisal`, `credit_report`. Must be one of the values from [List document types](ref:ListDocumentTypes); anything else is rejected with 400."
                        }
                      },
                      "required": [
                        "url",
                        "internal_name"
                      ]
                    }
                  }
                },
                "required": [
                  "documents"
                ],
                "example": {
                  "documents": [
                    {
                      "url": "https://s3.amazonaws.com/bucket/1008.pdf?signature=abc123",
                      "internal_name": "1008_transmittal"
                    },
                    {
                      "url": "https://s3.amazonaws.com/bucket/appraisal.pdf?signature=def456",
                      "internal_name": "appraisal"
                    }
                  ]
                }
              }
            }
          },
          "required": true
        }
      }
    },
    "/qc/packages/{uuid}/loan-data": {
      "parameters": [
        {
          "name": "uuid",
          "in": "path",
          "description": "Package closing UUID",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "post": {
        "summary": "Upload loan data to review",
        "tags": [
          "Packages"
        ],
        "operationId": "UploadLoanData",
        "description": "Use this endpoint to upload loan data that is required for QC review. For example, in a\npost-close review a post-closer will typically review data on documents, such as the cash\nto close, homeowner insurance annual premium, and property type, to ensure they are\naccurate compared to the LOS. Upload as many data fields as are available for that closing\nand that are required as a part of the QC review.\n\n**Which fields can I send?** Call\n[List loan data fields](ref:ListLoanDataFields) — it returns every\naccepted key with its type and description. Sending a key that is not on that list returns\n`400` with the offending keys in `unpermitted_keys`.\n\nMost fields are flat key/value pairs; `borrowers`, `sellers` and `property` are structured,\nas in the example below.\n",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Loan data imported successfully"
          },
          "400": {
            "description": "Bad request - unpermitted keys",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "detail": {
                            "type": "string"
                          },
                          "status": {
                            "type": "integer"
                          },
                          "unpermitted_keys": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "Array of keys that are not allowed"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden - insufficient scope",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "detail": {
                            "type": "string"
                          },
                          "status": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  },
                  "example": {
                    "errors": [
                      {
                        "detail": "Insufficient scope",
                        "status": 403
                      }
                    ]
                  }
                }
              }
            }
          },
          "404": {
            "description": "Package not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "detail": {
                            "type": "string"
                          },
                          "status": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "detail": {
                            "type": "string"
                          },
                          "status": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "data": {
                    "type": "object",
                    "description": "Loan data for the closing, as key/value pairs. Keys must come from [List loan data fields](ref:ListLoanDataFields); anything else is rejected with 400 and the offending keys in `unpermitted_keys`. Send only the fields you have — none is individually required, and values are matched against the documents under review. `borrowers` and `sellers` are arrays of objects, `property` is an object; every other field is a scalar."
                  }
                },
                "required": [
                  "data"
                ],
                "example": {
                  "data": {
                    "application_date": "2026-03-09",
                    "appraised_value": 450000,
                    "cash_to_close": 12345.67,
                    "property": {
                      "street_address": "123 Main St",
                      "city": "Denver",
                      "state": "CO",
                      "zip": "80202"
                    },
                    "borrowers": [
                      {
                        "first_name": "Ada",
                        "last_name": "Lovelace"
                      }
                    ]
                  }
                }
              }
            }
          },
          "required": true
        }
      }
    },
    "/qc/packages": {
      "post": {
        "summary": "Create a new package",
        "tags": [
          "Packages"
        ],
        "description": "Creates a QC package and returns its `uuid`, which every other endpoint takes.\n\n**Pre-Close QC only.** Post-Close packages are created by Snapdocs from the closing\nitself, so a Post-Close integration never calls this endpoint. Pre-Close has no\nclosing yet, so you create the package here to start the review.\n\nReturns `403 Forbidden` if Pre-Close QC is not enabled for your company — contact\nyour Snapdocs Implementation Manager.\n",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Package information",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "Closing UUID"
                    },
                    "fileNumber": {
                      "type": "string",
                      "description": "The package's file number"
                    },
                    "signerName": {
                      "type": "string",
                      "description": "The signer's name"
                    },
                    "loanGuid": {
                      "type": "string",
                      "nullable": true,
                      "description": "The loan GUID in the LOS"
                    }
                  },
                  "required": [
                    "id"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Forbidden - insufficient scope",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "detail": {
                            "type": "string"
                          },
                          "status": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  },
                  "example": {
                    "errors": [
                      {
                        "detail": "Insufficient scope",
                        "status": 403
                      }
                    ]
                  }
                }
              }
            }
          },
          "404": {
            "description": "Package not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "detail": {
                            "type": "string"
                          },
                          "status": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "detail": {
                            "type": "string"
                          },
                          "status": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "fileNumber": {
                    "type": "string",
                    "description": "The package's file number"
                  },
                  "signerName": {
                    "type": "string",
                    "description": "The signer's name"
                  },
                  "loanGuid": {
                    "type": "string",
                    "description": "The loan GUID in the LOS"
                  }
                }
              }
            }
          },
          "required": true
        }
      }
    },
    "/qc/packages/{uuid}": {
      "parameters": [
        {
          "name": "uuid",
          "in": "path",
          "description": "Package closing UUID",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "summary": "Get package by UUID",
        "tags": [
          "Packages"
        ],
        "description": "Retrieves the data for a package by closing UUID",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Package information",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "Closing UUID"
                    },
                    "fileNumber": {
                      "type": "string",
                      "description": "The package's file number"
                    },
                    "signerName": {
                      "type": "string",
                      "description": "The signer's name"
                    },
                    "loanGuid": {
                      "type": "string",
                      "nullable": true,
                      "description": "The loan GUID in the LOS"
                    }
                  },
                  "required": [
                    "id"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Forbidden - insufficient scope",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "detail": {
                            "type": "string"
                          },
                          "status": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  },
                  "example": {
                    "errors": [
                      {
                        "detail": "Insufficient scope",
                        "status": 403
                      }
                    ]
                  }
                }
              }
            }
          },
          "404": {
            "description": "Package not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "detail": {
                            "type": "string"
                          },
                          "status": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "detail": {
                            "type": "string"
                          },
                          "status": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/loan-data-fields": {
      "get": {
        "summary": "List loan data fields",
        "tags": [
          "Reference"
        ],
        "operationId": "ListLoanDataFields",
        "description": "Every field\n[Upload loan data to review](ref:UploadLoanData)\naccepts, so you can map your LOS to the QC API without hard-coding the list.\n\nMost entries are simple key/value pairs. `borrowers`, `sellers` and `property`\nare structured: they carry a `fields` array describing their own sub-fields,\nmatching the shape you send in the upload request body.\n\nThe list changes as fields are added or deprecated — read it rather than\npinning a copy.\n",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Fields returned",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "key": {
                            "type": "string",
                            "description": "The key to send in the loan data object."
                          },
                          "description": {
                            "type": "string",
                            "description": "What the field means."
                          },
                          "type": {
                            "type": "string",
                            "description": "One of string, number, integer, boolean, date, time, object, array."
                          },
                          "fields": {
                            "type": "array",
                            "description": "Sub-fields, for structured entries only (borrowers, sellers, property).",
                            "items": {
                              "type": "object",
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "description": {
                                  "type": "string",
                                  "nullable": true
                                },
                                "type": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key",
                                "type"
                              ]
                            }
                          }
                        },
                        "required": [
                          "key",
                          "type"
                        ]
                      }
                    }
                  },
                  "example": {
                    "data": [
                      {
                        "key": "appraised_value",
                        "description": "The appraised value of the property.",
                        "type": "number"
                      },
                      {
                        "key": "application_date",
                        "description": "The date the borrower submitted the loan application.",
                        "type": "date"
                      },
                      {
                        "key": "property",
                        "description": "Closing property",
                        "type": "object",
                        "fields": [
                          {
                            "key": "street_address",
                            "description": "Street address.",
                            "type": "string"
                          }
                        ]
                      }
                    ]
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden - insufficient scope",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "detail": {
                            "type": "string"
                          },
                          "status": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/document-types": {
      "get": {
        "summary": "List document types",
        "tags": [
          "Reference"
        ],
        "operationId": "ListDocumentTypes",
        "description": "Every `internal_name`\n[Upload documents to review](ref:UploadDocuments)\naccepts. Send one of these values with each uploaded document so QC knows\nwhat it is looking at.\n\nThe list changes as document types are added — read it rather than\npinning a copy.\n",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Document types returned",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Accepted internal_name values, alphabetically."
                    }
                  },
                  "example": {
                    "data": [
                      "1008_transmittal",
                      "appraisal",
                      "closing_disclosure_approved",
                      "credit_report"
                    ]
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden - insufficient scope",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "detail": {
                            "type": "string"
                          },
                          "status": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/qc/packages/{uuid}/reports": {
      "parameters": [
        {
          "name": "uuid",
          "in": "path",
          "description": "Package closing UUID",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "type",
          "in": "query",
          "required": true,
          "description": "Review type (post_close, funding, or pre_close)",
          "schema": {
            "type": "string",
            "enum": [
              "post_close",
              "funding",
              "pre_close"
            ]
          }
        }
      ],
      "get": {
        "summary": "Download QC results and documents",
        "tags": [
          "Packages"
        ],
        "description": "Use this endpoint to retrieve the latest QC results for the closing and download individual classified documents to upload into your LOS.\n\n| Report Type | What it returns | Customer type |\n| --- | --- | --- |\n| funding | Funding QC report | Lender using Funding QC |\n| post-close | Post-Close QC report | Lender using Post-Close QC |\n| pre_close | Pre-Close QC report | Lender using Pre-Close QC |\n",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Pre-close report found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Report status"
                    },
                    "reportType": {
                      "type": "string",
                      "description": "Type of report"
                    },
                    "reportUrl": {
                      "type": "string",
                      "nullable": true,
                      "description": "URL to the report document if available"
                    }
                  },
                  "required": [
                    "status",
                    "reportType"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Bad request - missing or invalid type parameter",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "detail": {
                            "type": "string"
                          },
                          "status": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden - insufficient scope",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "detail": {
                            "type": "string"
                          },
                          "status": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  },
                  "example": {
                    "errors": [
                      {
                        "detail": "Insufficient scope",
                        "status": 403
                      }
                    ]
                  }
                }
              }
            }
          },
          "404": {
            "description": "Package or review not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "detail": {
                            "type": "string"
                          },
                          "status": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "detail": {
                            "type": "string"
                          },
                          "status": {
                            "type": "integer"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "tags": [
    {
      "name": "Packages"
    },
    {
      "name": "Subscriptions"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "servers": [
    {
      "url": "https://api.snapdocs.com/api/v1",
      "description": "Production"
    },
    {
      "url": "https://api.cs-demo0.snpd.io/api/v1",
      "description": "Demo"
    },
    {
      "url": "https://api.cx-int0.snpd.io/api/v1",
      "description": "Integrator"
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer"
      },
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer"
      }
    },
    "schemas": {
      "internalNames": {
        "type": "string",
        "enum": [
          "placeholder"
        ]
      },
      "subscription": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "example": "9dc4ba8e-7e95-4b8e-ad1e-e2ce51ec3618",
            "description": "A unique identifier for the webhook subscription."
          },
          "description": {
            "type": "string",
            "example": "Analytics webhook",
            "description": "A short note about what events this webhook is following."
          },
          "webhook_url": {
            "type": "string",
            "format": "uri",
            "example": "https://hook.example.com/",
            "description": "A secure https URL where the event data will be posted."
          },
          "hmac_key": {
            "type": "string",
            "example": "76637c4b-1879-42e1-8140-c555ccba2ab0",
            "description": "A hash-based message authentication code used for verifying both the data integrity and the authenticity of a webhook message via SHA256."
          },
          "events": {
            "type": "array",
            "description": "List of events you want to be notified about.",
            "items": {
              "type": "string",
              "example": [
                "borrower.esigning_available"
              ],
              "enum": [
                "loan_data_requested",
                "documents_requested",
                "report_status_updated",
                "classified_documents_updated"
              ]
            }
          },
          "auth_type": {
            "type": "string",
            "nullable": true,
            "enum": [
              "oauth2",
              "basic"
            ],
            "description": "Authentication method used when Snapdocs calls your webhook endpoint. If null, no Authorization header is sent. HMAC signature headers are always included for request verification regardless of auth_type."
          },
          "auth_config": {
            "description": "Sanitized authentication configuration (sensitive fields like passwords and secrets are excluded).",
            "nullable": true,
            "oneOf": [
              {
                "type": "object",
                "description": "OAuth2 configuration (without client_secret)",
                "properties": {
                  "token_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "The OAuth2 token endpoint URL"
                  },
                  "client_id": {
                    "type": "string",
                    "description": "OAuth2 client ID"
                  },
                  "scope": {
                    "type": "string",
                    "description": "OAuth2 scope(s)"
                  },
                  "client_auth_method": {
                    "type": "string",
                    "enum": [
                      "body",
                      "header"
                    ],
                    "description": "Method for sending client credentials"
                  },
                  "grant_type": {
                    "type": "string",
                    "enum": [
                      "client_credentials"
                    ],
                    "description": "OAuth2 grant type"
                  },
                  "audience": {
                    "type": "string",
                    "description": "Optional OAuth2 audience parameter"
                  },
                  "resource": {
                    "type": "string",
                    "description": "Optional OAuth2 resource parameter"
                  }
                }
              },
              {
                "type": "object",
                "description": "Basic Authentication configuration (without password)",
                "properties": {
                  "username": {
                    "type": "string",
                    "description": "Basic auth username"
                  }
                }
              }
            ]
          }
        }
      },
      "new_subscription": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string",
            "example": "Analytics webhook",
            "description": "A short note about what events this webhook is following."
          },
          "webhook_url": {
            "type": "string",
            "format": "uri",
            "example": "https://hook.example.com/",
            "description": "A secure https URL where the event data will be posted."
          },
          "events": {
            "type": "array",
            "description": "List of events you want to be notified about.",
            "items": {
              "type": "string",
              "example": [
                "borrower.esigning_available"
              ],
              "enum": [
                "loan_data_requested",
                "documents_requested",
                "report_status_updated",
                "classified_documents_updated"
              ]
            }
          },
          "auth_type": {
            "type": "string",
            "enum": [
              "oauth2",
              "basic"
            ],
            "description": "Optional authentication method for outgoing webhook requests. When specified, Snapdocs will authenticate to your webhook endpoint using the configured method (OAuth2 or Basic Auth). When omitted, no Authorization header is sent (you can still verify requests using the HMAC signature which is always provided)."
          },
          "auth_config": {
            "type": "object",
            "description": "Authentication configuration based on auth_type. Required when auth_type is specified.",
            "oneOf": [
              {
                "type": "object",
                "description": "OAuth2 configuration",
                "properties": {
                  "token_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "The OAuth2 token endpoint URL"
                  },
                  "client_id": {
                    "type": "string",
                    "description": "OAuth2 client ID"
                  },
                  "client_secret": {
                    "type": "string",
                    "description": "OAuth2 client secret"
                  },
                  "scope": {
                    "type": "string",
                    "description": "OAuth2 scope(s)"
                  },
                  "client_auth_method": {
                    "type": "string",
                    "enum": [
                      "body",
                      "header"
                    ],
                    "description": "Method for sending client credentials (body or header)"
                  },
                  "grant_type": {
                    "type": "string",
                    "enum": [
                      "client_credentials"
                    ],
                    "description": "OAuth2 grant type"
                  },
                  "audience": {
                    "type": "string",
                    "description": "Optional OAuth2 audience parameter. Used by some OAuth2 providers (e.g., Auth0) to identify the intended recipient of the token."
                  },
                  "resource": {
                    "type": "string",
                    "description": "Optional OAuth2 resource parameter. Used by some OAuth2 providers (e.g., Azure AD) to specify the target resource."
                  }
                },
                "required": [
                  "token_url",
                  "client_id",
                  "client_secret",
                  "grant_type"
                ]
              },
              {
                "type": "object",
                "description": "Basic Authentication configuration",
                "properties": {
                  "username": {
                    "type": "string",
                    "description": "Basic auth username"
                  },
                  "password": {
                    "type": "string",
                    "description": "Basic auth password"
                  }
                },
                "required": [
                  "username",
                  "password"
                ]
              }
            ]
          }
        },
        "required": [
          "webhook_url"
        ]
      },
      "new_subscription_event": {
        "type": "object",
        "properties": {
          "events": {
            "type": "array",
            "description": "List of events you want to be notified about.",
            "items": {
              "type": "string",
              "example": [
                "borrower.esigning_available"
              ],
              "enum": [
                "loan_data_requested",
                "documents_requested",
                "report_status_updated",
                "classified_documents_updated"
              ]
            }
          }
        },
        "required": [
          "events"
        ]
      },
      "get_subscriptions_response": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "description": "An array of webhook subscription details.",
            "items": {
              "$ref": "#/components/schemas/subscription"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/meta"
          }
        }
      },
      "meta": {
        "type": "object",
        "description": "The object storing metadata about the returned transaction status results.",
        "properties": {
          "current_page": {
            "type": "integer",
            "description": "The current page of the paginated results."
          },
          "next_page": {
            "type": "integer",
            "nullable": true,
            "description": "The next page number of the paginated results."
          },
          "page_size": {
            "type": "integer",
            "description": "The number of results per page."
          },
          "total_count": {
            "type": "integer",
            "description": "The total number of results."
          },
          "total_pages": {
            "type": "integer",
            "description": "The total number of pages of paginated results."
          }
        }
      }
    }
  }
}