{
  "openapi": "3.1.0",
  "info": {
    "title": "Subscriptions — Quality Control scopes",
    "version": "v1"
  },
  "servers": [
    {
      "url": "https://api.snapdocs.com",
      "description": "Production"
    },
    {
      "url": "https://api.cs-demo0.snpd.io",
      "description": "Demo"
    },
    {
      "url": "https://api.cx-int0.snpd.io",
      "description": "Integrator"
    }
  ],
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer"
      }
    },
    "schemas": {
      "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",
              "null"
            ],
            "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."
          }
        }
      },
      "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"
          }
        }
      },
      "new_subscription": {
        "type": "object",
        "required": [
          "webhook_url"
        ],
        "properties": {
          "description": {
            "type": "string",
            "example": "QC 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 QC events you want to be notified about.",
            "items": {
              "type": "string",
              "example": [
                "loan_data_requested"
              ],
              "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",
                "required": [
                  "token_url",
                  "client_id",
                  "client_secret",
                  "grant_type"
                ],
                "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."
                  }
                }
              },
              {
                "type": "object",
                "description": "Basic Authentication configuration",
                "required": [
                  "username",
                  "password"
                ],
                "properties": {
                  "username": {
                    "type": "string",
                    "description": "Basic auth username"
                  },
                  "password": {
                    "type": "string",
                    "description": "Basic auth password"
                  }
                }
              }
            ]
          }
        }
      },
      "new_subscription_event": {
        "type": "object",
        "required": [
          "events"
        ],
        "properties": {
          "events": {
            "type": "array",
            "description": "List of QC events you want to be notified about.",
            "items": {
              "type": "string",
              "example": [
                "loan_data_requested"
              ],
              "enum": [
                "loan_data_requested",
                "documents_requested",
                "report_status_updated",
                "classified_documents_updated"
              ]
            }
          }
        }
      },
      "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": "QC 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 QC events you want to be notified about.",
            "items": {
              "type": "string",
              "example": [
                "loan_data_requested"
              ],
              "enum": [
                "loan_data_requested",
                "documents_requested",
                "report_status_updated",
                "classified_documents_updated"
              ]
            }
          },
          "auth_type": {
            "type": [
              "string",
              "null"
            ],
            "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).",
            "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"
                  }
                }
              },
              {
                "type": "null"
              }
            ]
          }
        }
      }
    }
  },
  "security": [
    {
      "BearerAuth": []
    }
  ],
  "paths": {
    "/api/v1/subscriptions/{id}/events": {
      "post": {
        "summary": "Add events to a subscription",
        "tags": [
          "Subscriptions"
        ],
        "description": "Use this endpoint to update events on a QC webhook subscription. Requires the `cqc:write:subscriptions` scope.",
        "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."
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/new_subscription_event"
              }
            }
          }
        },
        "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",
                      "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",
                      "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"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete events from a subscription",
        "tags": [
          "Subscriptions"
        ],
        "description": "Use this endpoint to remove events from a QC webhook subscription. If the call is successful, return a 200 successful status code. Requires the `cqc:write:subscriptions` scope.",
        "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": "loan_data_requested,report_status_updated",
              "description": "Comma-separated names of events to remove from the subscription. When omitted, all events are removed."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "successful"
          },
          "401": {
            "description": "Unauthorized. The Authorization header was missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "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."
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/subscriptions": {
      "get": {
        "summary": "Get all the subscriptions",
        "tags": [
          "Subscriptions"
        ],
        "description": "Use this endpoint to retrieve all the QC webhook subscriptions your company is subscribing to. Requires the `cqc:read:subscriptions` scope.",
        "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",
                      "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 QC webhook subscription. Requires the `cqc:write:subscriptions` scope.",
        "operationId": "CreateSubscription",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/new_subscription"
              }
            }
          }
        },
        "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",
                      "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",
                      "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"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/subscriptions/{id}": {
      "delete": {
        "summary": "Delete a subscription",
        "tags": [
          "Subscriptions"
        ],
        "description": "Use this endpoint to remove a QC webhook subscription. If the call is successful, return a 200 successful status code. Requires the `cqc:write:subscriptions` scope.",
        "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",
                      "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",
                      "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"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}