{
  "info": {
    "title": "core/webhooks",
    "version": ""
  },
  "paths": {
    "/api/core/webhooks": {
      "get": {
        "tags": [
          "webhooks"
        ],
        "summary": "List webhooks",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookList"
                }
              }
            },
            "description": "OK Response"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        },
        "parameters": [
          {
            "in": "query",
            "name": "createdByUserId",
            "schema": {
              "type": "string"
            },
            "description": "Filter resources by user that created it"
          },
          {
            "in": "query",
            "name": "enabled",
            "schema": {
              "type": "boolean"
            },
            "description": "Filter resources by enabled true/false"
          },
          {
            "in": "query",
            "name": "eventTypes",
            "schema": {
              "type": "string",
              "example": "com.qlik.v1.app.created,com.qlik.v1.app.reload.finished"
            },
            "description": "Filter resources by event-type. Accepts a comma-separated list, and a webhook must subscribe to every listed event-type to match (AND semantics). A single webhook can subscribe to multiple event-types. Values must be event-types returned by `GET /core/webhooks/event-types`."
          },
          {
            "in": "query",
            "name": "level",
            "schema": {
              "type": "string",
              "example": "tenant"
            },
            "description": "Filter resources by the level the webhook operates at: `tenant` for all resources of the tenant, or `user` for only the resources accessible to the webhook owner."
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "number",
              "default": 20,
              "maximum": 100,
              "minimum": 1
            },
            "description": "Maximum number of webhooks to retrieve"
          },
          {
            "in": "query",
            "name": "name",
            "schema": {
              "type": "string"
            },
            "description": "Filter resources by name. The value is matched as a case-insensitive substring, not as a glob pattern, so `prod` matches `Production webhook`."
          },
          {
            "in": "query",
            "name": "next",
            "schema": {
              "type": "string"
            },
            "description": "Cursor to the next page"
          },
          {
            "in": "query",
            "name": "origins",
            "schema": {
              "enum": [
                "api",
                "automations",
                "management-console"
              ],
              "type": "string"
            },
            "description": "Filter resources by origin. The implementation also accepts a comma-separated list, in which case a webhook matches if its origin is any of the listed values (OR semantics)."
          },
          {
            "in": "query",
            "name": "ownerId",
            "schema": {
              "type": "string"
            },
            "description": "Filter resources by user that owns it, only applicable for user level webhooks"
          },
          {
            "in": "query",
            "name": "prev",
            "schema": {
              "type": "string"
            },
            "description": "Cursor to the previous page."
          },
          {
            "in": "query",
            "name": "sort",
            "schema": {
              "enum": [
                "name",
                "+name",
                "-name",
                "url",
                "+url",
                "-url",
                "createdAt",
                "+createdAt",
                "-createdAt",
                "updatedAt",
                "+updatedAt",
                "-updatedAt"
              ],
              "type": "string",
              "default": "-createdAt"
            },
            "description": "Field to sort by, prefix with -/+ to indicate order"
          },
          {
            "in": "query",
            "name": "updatedByUserId",
            "schema": {
              "type": "string"
            },
            "description": "Filter resources by user that last updated the webhook"
          },
          {
            "in": "query",
            "name": "url",
            "schema": {
              "type": "string"
            },
            "description": "Filter resources by URL. The value is matched as a case-insensitive substring, not as a glob pattern, so `example.com` matches `https://example.com/hook`."
          }
        ],
        "description": "Retrieves all webhook entries for a tenant that the user has access to. Users assigned the `TenantAdmin` role can retrieve all webhooks of the tenant; other users only retrieve the webhooks they own. Values of `encryptedHeaders` are never returned, only their header names.",
        "operationId": "listWebhookEntries",
        "x-qlik-visibility": "public",
        "x-qlik-stability": "stable",
        "x-qlik-deprecated": false,
        "x-qlik-replaces": [
          {
            "namespace": "",
            "uniqueIdentifier": "GET:/v1/webhooks"
          }
        ],
        "x-qlik-tier": {
          "tier": "1",
          "limit": 1000
        }
      },
      "post": {
        "tags": [
          "webhooks"
        ],
        "summary": "Create a new webhook",
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookResponse"
                }
              }
            },
            "description": "The webhook was created. The response contains the stored webhook, where `secret` is replaced by `secretKeyAdded` and `encryptedHeaders` is returned as a list of header names."
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "The request is not allowed, for example because the user lacks the required permissions, the target URL is forbidden, the event-type is not enabled for the tenant, or the user's 150-webhook quota is reached."
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        },
        "description": "Creates a new webhook. User must be assigned the `TenantAdmin` role to create `tenant` level webhooks. Each user can own up to 150 webhooks per tenant; creating a webhook beyond that quota is rejected with `403`.",
        "operationId": "createWebhook",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookPost"
              }
            }
          },
          "required": true
        },
        "x-qlik-visibility": "public",
        "x-qlik-stability": "stable",
        "x-qlik-deprecated": false,
        "x-qlik-replaces": [
          {
            "namespace": "",
            "uniqueIdentifier": "POST:/v1/webhooks"
          }
        ],
        "x-qlik-tier": {
          "tier": "2",
          "limit": 100
        }
      }
    },
    "/api/core/webhooks/{id}": {
      "get": {
        "tags": [
          "webhooks"
        ],
        "summary": "Get a webhook",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookResponse"
                }
              }
            },
            "description": "OK Response"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true,
            "description": "The webhook's unique identifier."
          }
        ],
        "description": "Returns details for a specific webhook.",
        "operationId": "getWebhook",
        "x-qlik-visibility": "public",
        "x-qlik-stability": "stable",
        "x-qlik-deprecated": false,
        "x-qlik-replaces": [
          {
            "namespace": "",
            "uniqueIdentifier": "GET:/v1/webhooks/{id}"
          }
        ],
        "x-qlik-tier": {
          "tier": "1",
          "limit": 1000
        }
      },
      "patch": {
        "tags": [
          "webhooks"
        ],
        "summary": "Update selected webhook properties",
        "responses": {
          "204": {
            "description": "No Content response."
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true,
            "description": "The webhook's unique identifier."
          }
        ],
        "description": "Updates one or more individual properties of a webhook using a JSON Patch document, leaving all other properties unchanged. The patch is applied to the stored webhook and the result is validated as a whole, so a patch that produces an invalid webhook is rejected. When `/url` is changed on a webhook that has encrypted headers, every existing encrypted header must also be replaced or removed in the same patch, otherwise the request is rejected with `400`. Changing read-only properties is rejected with `409`, and changing `/ownerId` requires permission to transfer ownership.",
        "operationId": "patchWebhook",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/WebhookPatch"
                }
              }
            }
          },
          "required": true
        },
        "x-qlik-visibility": "public",
        "x-qlik-stability": "stable",
        "x-qlik-deprecated": false,
        "x-qlik-replaces": [
          {
            "namespace": "",
            "uniqueIdentifier": "PATCH:/v1/webhooks/{id}"
          }
        ],
        "x-qlik-tier": {
          "tier": "2",
          "limit": 100
        }
      },
      "put": {
        "tags": [
          "webhooks"
        ],
        "summary": "Replace a webhook",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookResponse"
                }
              }
            },
            "description": "OK Response"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true,
            "description": "The webhook's unique identifier."
          }
        ],
        "description": "Replaces all writable properties of a webhook and returns the updated webhook. This is a full replacement: every writable property that is omitted from the request body is reset to its default, so omitting `secret`, `encryptedHeaders`, `headers` or `filter` clears them, and omitting `enabled` disables the webhook. Because `secret` is never returned and `encryptedHeaders` is returned as a list of header names, a `GET` response cannot be sent back unchanged as a `PUT` request body; re-send those values explicitly, and use `PATCH` to change individual properties. Read-only properties such as `id`, `createdAt`, `createdByUserId` and `origin` cannot be changed and are rejected with `409`.",
        "operationId": "updateWebhook",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookBase"
              }
            }
          },
          "required": true
        },
        "x-qlik-visibility": "public",
        "x-qlik-stability": "stable",
        "x-qlik-deprecated": false,
        "x-qlik-replaces": [
          {
            "namespace": "",
            "uniqueIdentifier": "PUT:/v1/webhooks/{id}"
          }
        ],
        "x-qlik-tier": {
          "tier": "2",
          "limit": 100
        }
      },
      "delete": {
        "tags": [
          "webhooks"
        ],
        "summary": "Delete a webhook",
        "responses": {
          "204": {
            "description": "No Content response."
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true,
            "description": "The webhook's unique identifier."
          }
        ],
        "description": "Deletes a specific webhook.",
        "operationId": "deleteWebhook",
        "x-qlik-visibility": "public",
        "x-qlik-stability": "stable",
        "x-qlik-deprecated": false,
        "x-qlik-replaces": [
          {
            "namespace": "",
            "uniqueIdentifier": "DELETE:/v1/webhooks/{id}"
          }
        ],
        "x-qlik-tier": {
          "tier": "2",
          "limit": 100
        }
      }
    },
    "/api/core/webhooks/{id}/deliveries": {
      "get": {
        "tags": [
          "deliveries"
        ],
        "summary": "Return deliveries for a webhook",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeliveryList"
                }
              }
            },
            "description": "OK Response"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true,
            "description": "The webhook's unique identifier."
          },
          {
            "in": "query",
            "name": "eventType",
            "schema": {
              "type": "string"
            },
            "description": "Filter resources by event-type"
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "number",
              "default": 20,
              "maximum": 100,
              "minimum": 1
            },
            "description": "Maximum number of deliveries to retrieve"
          },
          {
            "in": "query",
            "name": "next",
            "schema": {
              "type": "string"
            },
            "description": "Cursor to the next page"
          },
          {
            "in": "query",
            "name": "prev",
            "schema": {
              "type": "string"
            },
            "description": "Cursor to the previous page."
          },
          {
            "in": "query",
            "name": "sort",
            "schema": {
              "enum": [
                "status",
                "+status",
                "-status",
                "triggeredAt",
                "+triggeredAt",
                "-triggeredAt"
              ],
              "type": "string",
              "default": "-triggeredAt"
            },
            "description": "Field to sort by, prefix with -/+ to indicate order"
          },
          {
            "in": "query",
            "name": "status",
            "schema": {
              "enum": [
                "success",
                "fail"
              ],
              "type": "string"
            },
            "description": "Filter resources by status (success or fail)"
          }
        ],
        "description": "Returns deliveries for a specific webhook. Delivery history is stored for 1 week.",
        "operationId": "getWebhookDeliveryList",
        "x-qlik-visibility": "public",
        "x-qlik-stability": "stable",
        "x-qlik-deprecated": false,
        "x-qlik-replaces": [
          {
            "namespace": "",
            "uniqueIdentifier": "GET:/v1/webhooks/{id}/deliveries"
          }
        ],
        "x-qlik-tier": {
          "tier": "1",
          "limit": 1000
        }
      }
    },
    "/api/core/webhooks/{id}/deliveries/{deliveryId}": {
      "get": {
        "tags": [
          "deliveries"
        ],
        "summary": "Return details for specific delivery",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Delivery"
                }
              }
            },
            "description": "OK Response"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "deliveryId",
            "schema": {
              "type": "string"
            },
            "required": true,
            "description": "The delivery's unique identifier."
          },
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true,
            "description": "The webhook's unique identifier."
          }
        ],
        "description": "Returns details for a specific delivery.",
        "operationId": "getWebhookDelivery",
        "x-qlik-visibility": "public",
        "x-qlik-stability": "stable",
        "x-qlik-deprecated": false,
        "x-qlik-replaces": [
          {
            "namespace": "",
            "uniqueIdentifier": "GET:/v1/webhooks/{id}/deliveries/{deliveryId}"
          }
        ],
        "x-qlik-tier": {
          "tier": "1",
          "limit": 1000
        }
      }
    },
    "/api/core/webhooks/{id}/deliveries/{deliveryId}/actions/resend": {
      "post": {
        "tags": [
          "deliveries"
        ],
        "summary": "Resend delivery",
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Delivery"
                }
              }
            },
            "description": "A new delivery was created for the resend attempt. Check `status` to see whether the delivery itself succeeded or failed."
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "The request is not allowed, for example because the user lacks the required permissions or the event-type of the delivery is not enabled for the tenant."
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "deliveryId",
            "schema": {
              "type": "string"
            },
            "required": true,
            "description": "The delivery's unique identifier."
          },
          {
            "in": "path",
            "name": "id",
            "schema": {
              "type": "string"
            },
            "required": true,
            "description": "The webhook's unique identifier."
          }
        ],
        "description": "Resends the event payload of an existing delivery and returns the new delivery. The event payload is taken from the original delivery, but the webhook's current configuration (URL, headers, secret and certificate settings) is used to send it. The resend is attempted synchronously and a new delivery record is always created, so a `201` response can contain a delivery with status `fail`. A resend is subject to the same validation and failure handling as an automatic delivery, so a webhook that is no longer valid or that exceeds the delivery failure threshold can be disabled as a result.",
        "operationId": "resendDelivery",
        "x-qlik-visibility": "public",
        "x-qlik-stability": "stable",
        "x-qlik-deprecated": false,
        "x-qlik-replaces": [
          {
            "namespace": "",
            "uniqueIdentifier": "POST:/v1/webhooks/{id}/deliveries/{deliveryId}/actions/resend"
          }
        ],
        "x-qlik-tier": {
          "tier": "2",
          "limit": 100
        }
      }
    },
    "/api/core/webhooks/event-types": {
      "get": {
        "tags": [
          "webhooks"
        ],
        "summary": "List event-types",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventTypes"
                }
              }
            },
            "description": "OK Response"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        },
        "description": "Lists event-types that are possible to subscribe to.",
        "operationId": "listEventTypes",
        "x-qlik-visibility": "public",
        "x-qlik-stability": "stable",
        "x-qlik-deprecated": false,
        "x-qlik-replaces": [
          {
            "namespace": "",
            "uniqueIdentifier": "GET:/v1/webhooks/event-types"
          }
        ],
        "x-qlik-tier": {
          "tier": "1",
          "limit": 1000
        }
      }
    }
  },
  "openapi": "3.0.0",
  "components": {
    "responses": {
      "BadRequest": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        },
        "description": "Bad Request"
      },
      "Conflict": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        },
        "description": "Conflict"
      },
      "Forbidden": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        },
        "description": "Forbidden"
      },
      "InternalServerError": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        },
        "description": "Internal Server Error"
      },
      "NotFound": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        },
        "description": "Not found"
      },
      "ServiceUnavailable": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        },
        "description": "Service Unavailable"
      },
      "Unauthorized": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        },
        "description": "Unauthorized"
      }
    },
    "schemas": {
      "Delivery": {
        "type": "object",
        "readOnly": true,
        "required": [
          "id",
          "webhookId",
          "triggeredAt",
          "status",
          "eventType"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "The delivery's unique identifier"
          },
          "status": {
            "enum": [
              "success",
              "fail"
            ],
            "type": "string",
            "description": "The status of delivery"
          },
          "request": {
            "type": "object",
            "properties": {
              "url": {
                "type": "string",
                "description": "URL used for this delivery"
              },
              "body": {
                "type": "object",
                "description": "The sent body/payload of the delivery"
              },
              "headers": {
                "type": "object",
                "example": {
                  "headerName": "headerValue",
                  "encryptedHeadersName": "**OMITTED**"
                },
                "description": "Headers sent for this delivery, values of encryptedHeaders are omitted as such \"**OMITTED**\". Maximum combined size: 2048 bytes for non-encrypted headers + 2048 bytes for encrypted headers.",
                "additionalProperties": {
                  "type": "string"
                }
              }
            },
            "description": "The request that was sent to the webhook URL for this delivery."
          },
          "response": {
            "type": "object",
            "properties": {
              "body": {
                "type": "string",
                "description": "The received body of the delivery"
              },
              "headers": {
                "type": "object",
                "example": {
                  "headerName": "headerValue",
                  "encryptedHeadersName": "**OMITTED**"
                },
                "description": "Headers received for this delivery, values of encryptedHeaders are omitted as such \"**OMITTED**\". Maximum combined size: 2048 bytes for non-encrypted headers + 2048 bytes for encrypted headers.",
                "additionalProperties": {
                  "type": "string"
                }
              },
              "statusCode": {
                "type": "number",
                "description": "The HTTP status code of the response"
              }
            },
            "description": "The response that was received from the webhook URL for this delivery. Absent if no response was received."
          },
          "eventType": {
            "type": "string",
            "description": "The name of the triggering event-type"
          },
          "webhookId": {
            "type": "string",
            "description": "The unique webhook identifier that the delivery is for"
          },
          "triggeredAt": {
            "type": "string",
            "format": "date-time",
            "example": "2025-07-02T08:20:35.49Z",
            "description": "The UTC timestamp when the delivery was triggered"
          },
          "statusMessage": {
            "type": "string",
            "description": "The status message of the delivery"
          }
        }
      },
      "DeliveryList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Delivery"
            }
          },
          "links": {
            "properties": {
              "next": {
                "$ref": "#/components/schemas/Link"
              },
              "prev": {
                "$ref": "#/components/schemas/Link"
              },
              "self": {
                "$ref": "#/components/schemas/Link"
              }
            }
          }
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "code",
          "title"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "The unique code for the error"
          },
          "title": {
            "type": "string",
            "description": "A summary of what went wrong"
          },
          "detail": {
            "type": "string",
            "description": "May be used to provide additional details"
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Error"
            }
          },
          "traceId": {
            "type": "string",
            "description": "A way to trace the source of the error."
          }
        }
      },
      "EventType": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Name of the event type"
          },
          "title": {
            "type": "string",
            "description": "Title of the event type"
          },
          "levels": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Specifies which levels that are supported for this event type"
          },
          "category": {
            "type": "string",
            "description": "Category of the event type"
          },
          "description": {
            "type": "string",
            "description": "Description of the event type"
          },
          "allowedFilters": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FilterInfo"
            },
            "description": "The set of fields that can be used to filter this specific event type for webhook delivery. Different event types may support different filter paths."
          }
        }
      },
      "EventTypes": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EventType"
            }
          }
        }
      },
      "FilterInfo": {
        "type": "object",
        "required": [
          "path"
        ],
        "properties": {
          "path": {
            "type": "string",
            "example": "data.status",
            "description": "The field name or path that can be used as a filter"
          },
          "allowedValues": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "SUCCEEDED",
              "FAILED",
              "CANCELED",
              "EXCEEDED_LIMIT"
            ],
            "description": "Optional allowed values for this filter path. If omitted, the path is treated as free-form and clients are responsible for valid usage."
          }
        },
        "description": "Describes a single field that can be used as a filter."
      },
      "Link": {
        "required": [
          "href"
        ],
        "properties": {
          "href": {
            "type": "string",
            "description": "URL to a resource request"
          }
        }
      },
      "WebhookBase": {
        "type": "object",
        "required": [
          "name",
          "url"
        ],
        "properties": {
          "id": {
            "type": "string",
            "example": "68ed032e3e1327ad5b7db341",
            "readOnly": true,
            "description": "The webhook's unique identifier"
          },
          "url": {
            "type": "string",
            "example": "https://www.valid-url.com",
            "maxLength": 2048,
            "description": "Target URL for webhook HTTPS requests"
          },
          "name": {
            "type": "string",
            "example": "Apps-Webhook",
            "maxLength": 512,
            "description": "The name for the webhook"
          },
          "level": {
            "enum": [
              "tenant",
              "user"
            ],
            "type": "string",
            "default": "tenant",
            "description": "Defines at what level the webhook should operate: for all resources belonging to a tenant or restricted to only those accessible by the webhook-creator."
          },
          "filter": {
            "type": "string",
            "example": "id eq \"id123\" or spaceId eq \"spaceId123\" or spaceId eq \"spaceId456\" or topLevelResourceId eq \"id789\"",
            "description": "Filter that should match for a webhook to be triggered.\nSupported common attribute names are 'id', 'spaceId' and 'topLevelResourceId'. Individual event-types can support additional event-specific attributes, which cannot be combined with other event-types in the same webhook. For example \"com.qlik.v1.app.reload.finished\" supports \"data.status\" with the allowed values \"SUCCEEDED\", \"FAILED\", \"CANCELED\" and \"EXCEEDED_LIMIT\".\nThe authoritative set of filterable attributes and their allowed values for each event-type is returned in the `allowedFilters` property of `GET /core/webhooks/event-types`.\nSupported attribute operators are 'eq' and 'ne'.\nSupported logical operators are 'and' and 'or'.\nNote that attribute values must be valid JSON strings, hence they're enclosed with double quotes.\nFor more detailed information regarding the SCIM filter syntax (RFC7644) used please follow the link to external documentation.",
            "externalDocs": {
              "url": "https://datatracker.ietf.org/doc/html/rfc7644#section-3.4.2.2",
              "description": "More information about the SCIM filter syntax (RFC7644)"
            }
          },
          "secret": {
            "type": "string",
            "example": "ItsA32To64BitLongSecretForQlikSignature",
            "maxLength": 64,
            "minLength": 32,
            "description": "Shared secret used to sign the webhook delivery. Each delivery is sent with a `Qlik-Signature` header containing the hex-encoded HMAC-SHA256 of the raw request body, computed with this secret, so the receiver can verify that the payload is genuine and unmodified. The secret is stored encrypted and is never returned by the API; responses report only `secretKeyAdded`."
          },
          "enabled": {
            "type": "boolean",
            "default": false,
            "description": "Whether the webhook is active and sending requests"
          },
          "headers": {
            "type": "object",
            "example": {
              "headerName": "headerValue"
            },
            "description": "Additional headers in the post request (webhook delivery). Note: duplicate headers are not allowed and are case-insensitive. Maximum combined size: 2048 bytes (total of all header names and values).",
            "additionalProperties": {
              "type": "string"
            }
          },
          "ownerId": {
            "type": "string",
            "example": "6863a23242ecf6179670ee97",
            "description": "The id of the user that owns the webhook, only applicable for user level webhooks"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "example": "2025-07-02T08:20:35.49Z",
            "readOnly": true,
            "description": "The UTC timestamp when the webhook was created"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "example": "2025-07-08T16:39:34.829Z",
            "readOnly": true,
            "description": "The UTC timestamp when the webhook was last updated"
          },
          "eventTypes": {
            "type": "array",
            "items": {
              "type": "string",
              "example": "com.qlik.v1.app.created",
              "description": "Types of events for which the webhook should trigger. Retrieve available types from `/core/webhooks/event-types`."
            },
            "example": [
              "com.qlik.v1.reload.finished",
              "com.qlik.v1.app.created"
            ],
            "description": "Types of events for which the webhook should trigger. Retrieve available types from `/core/webhooks/event-types`."
          },
          "description": {
            "type": "string",
            "example": "this webhook provides a real time update of an action occurred by delivering an event through a post call",
            "maxLength": 1024,
            "description": "The reason for creating the webhook"
          },
          "disabledReason": {
            "type": "string",
            "example": "Disabled by user",
            "readOnly": true,
            "description": "The reason for the webhook to be disabled"
          },
          "createdByUserId": {
            "type": "string",
            "example": "6863a23242ecf6179670ee97",
            "readOnly": true,
            "description": "The id of the user that created the webhook"
          },
          "updatedByUserId": {
            "type": "string",
            "example": "6863a23242ecf6179670ee97",
            "readOnly": true,
            "description": "The id of the user that last updated the webhook"
          },
          "encryptedHeaders": {
            "type": "object",
            "example": {
              "headerName": "sensitiveHeaderValue"
            },
            "description": "Headers that are persisted encrypted and decrypted again to be sent as normal headers in the post request (webhook delivery). In requests they are supplied as name/value pairs, but responses return only the header names as a list of strings, because the values are never disclosed. If the URL changes, these headers must be re-entered. Note: duplicate headers are not allowed and are case-insensitive. Maximum combined size: 2048 bytes (total of all encrypted header names and values).",
            "additionalProperties": {
              "type": "string"
            }
          },
          "disabledReasonCode": {
            "type": "string",
            "example": "WEBHOOKS-104",
            "readOnly": true,
            "description": "The unique code for the reason"
          },
          "enableCloudEventDelivery": {
            "type": "boolean",
            "example": true,
            "description": "Whether this webhook delivers events as CloudEvents. On creation, the service determines the effective value from tenant feature flags and webhook origin; the supplied value is not authoritative. On PUT, omission is treated as false. When feature flags are enabled, the service may automatically enable this for exclusive Data Integration webhooks. Once enabled, it cannot be disabled; omitting it when replacing an enabled webhook therefore returns `403`."
          },
          "checkCertificateRevocation": {
            "type": "boolean",
            "default": false,
            "description": "If enabled the certificate chain of the configured URL will be checked for revocation before sending the webhook."
          }
        }
      },
      "WebhookList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WebhookResponse"
            }
          },
          "links": {
            "properties": {
              "next": {
                "$ref": "#/components/schemas/Link"
              },
              "prev": {
                "$ref": "#/components/schemas/Link"
              },
              "self": {
                "$ref": "#/components/schemas/Link"
              }
            }
          }
        }
      },
      "WebhookPatch": {
        "type": "object",
        "required": [
          "op",
          "path"
        ],
        "properties": {
          "op": {
            "enum": [
              "add",
              "remove",
              "replace"
            ],
            "type": "string",
            "description": "The operation to be performed"
          },
          "path": {
            "enum": [
              "/name",
              "/description",
              "/url",
              "/eventTypes",
              "/headers",
              "/enabled",
              "/secret",
              "/encryptedHeaders",
              "/enableCloudEventDelivery",
              "/filter",
              "/level",
              "/ownerId",
              "/checkCertificateRevocation"
            ],
            "type": "string",
            "example": "/description",
            "description": "The path of the webhook property to patch. Only writable properties can be patched; read-only properties such as `/id`, `/createdAt`, `/createdByUserId` and `/origin` are rejected. Individual members of `/headers` and `/encryptedHeaders` can also be addressed directly, for example `/encryptedHeaders/myHeader`."
          },
          "value": {
            "oneOf": [
              {
                "type": "boolean"
              },
              {
                "type": "integer"
              },
              {
                "type": "object"
              },
              {
                "type": "string"
              },
              {
                "type": "array"
              }
            ],
            "description": "The value to be used for this operation. The type must match the patched property, for example an array of event-type names for `/eventTypes` or an object of header name/value pairs for `/headers`. Not used by the `remove` operation."
          }
        },
        "description": "A JSON Patch document as defined in https://datatracker.ietf.org/doc/html/rfc6902"
      },
      "WebhookPost": {
        "allOf": [
          {
            "$ref": "#/components/schemas/WebhookBase"
          },
          {
            "type": "object",
            "properties": {
              "origin": {
                "enum": [
                  "api",
                  "automations",
                  "management-console"
                ],
                "type": "string",
                "default": "api",
                "description": "Indicates from where the webhook was created and its purpose"
              }
            }
          }
        ]
      },
      "WebhookResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/WebhookResponseBase"
          },
          {
            "type": "object",
            "properties": {
              "origin": {
                "enum": [
                  "api",
                  "automations",
                  "management-console"
                ],
                "type": "string",
                "default": "api",
                "readOnly": true,
                "description": "Indicates from where the webhook was created and its purpose"
              }
            }
          }
        ]
      },
      "WebhookResponseBase": {
        "type": "object",
        "required": [
          "name",
          "url"
        ],
        "properties": {
          "id": {
            "type": "string",
            "readOnly": true,
            "description": "The webhook's unique identifier"
          },
          "url": {
            "type": "string",
            "maxLength": 2048,
            "description": "Target URL for webhook HTTPS requests"
          },
          "name": {
            "type": "string",
            "maxLength": 512,
            "description": "The name for the webhook"
          },
          "level": {
            "enum": [
              "tenant",
              "user"
            ],
            "type": "string",
            "default": "tenant",
            "description": "Defines at what level the webhook should operate: for all resources belonging to a tenant or restricted to only those accessible by the webhook-creator."
          },
          "filter": {
            "type": "string",
            "example": "id eq \"id123\" or spaceId eq \"spaceId123\" or spaceId eq \"spaceId456\" or topLevelResourceId eq \"id789\"",
            "description": "Filter that should match for a webhook to be triggered.\nSupported common attribute names are 'id', 'spaceId' and 'topLevelResourceId'. Individual event-types can support additional event-specific attributes, which cannot be combined with other event-types in the same webhook. For example \"com.qlik.v1.app.reload.finished\" supports \"data.status\" with the allowed values \"SUCCEEDED\", \"FAILED\", \"CANCELED\" and \"EXCEEDED_LIMIT\".\nThe authoritative set of filterable attributes and their allowed values for each event-type is returned in the `allowedFilters` property of `GET /core/webhooks/event-types`.\nSupported attribute operators are 'eq' and 'ne'.\nSupported logical operators are 'and' and 'or'.\nNote that attribute values must be valid JSON strings, hence they're enclosed with double quotes.\nFor more detailed information regarding the SCIM filter syntax (RFC7644) used please follow the link to external documentation.",
            "externalDocs": {
              "url": "https://datatracker.ietf.org/doc/html/rfc7644#section-3.4.2.2",
              "description": "More information about the SCIM filter syntax (RFC7644)"
            }
          },
          "enabled": {
            "type": "boolean",
            "default": false,
            "description": "Whether the webhook is active and sending requests"
          },
          "headers": {
            "type": "object",
            "example": {
              "headerName": "headerValue"
            },
            "description": "Additional headers in the post request. Maximum combined size: 2048 bytes (total of all header names and values).",
            "additionalProperties": {
              "type": "string"
            }
          },
          "ownerId": {
            "type": "string",
            "description": "The id of the user that owns the webhook, only applicable for user level webhooks"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "example": "2025-07-02T08:20:35.49Z",
            "readOnly": true,
            "description": "The UTC timestamp when the webhook was created"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "example": "2025-07-02T08:20:35.49Z",
            "readOnly": true,
            "description": "The UTC timestamp when the webhook was last updated"
          },
          "eventTypes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Types of events for which the webhook should trigger. Retrieve available types from `/core/webhooks/event-types`."
          },
          "description": {
            "type": "string",
            "maxLength": 1024,
            "description": "The reason for creating the webhook"
          },
          "disabledReason": {
            "type": "string",
            "readOnly": true,
            "description": "The reason for the webhook to be disabled"
          },
          "secretKeyAdded": {
            "type": "boolean",
            "description": "Whether a signing secret is currently stored for this webhook. The secret itself is never returned."
          },
          "createdByUserId": {
            "type": "string",
            "readOnly": true,
            "description": "The id of the user that created the webhook"
          },
          "updatedByUserId": {
            "type": "string",
            "readOnly": true,
            "description": "The id of the user that last updated the webhook"
          },
          "encryptedHeaders": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "header1",
              "header2"
            ],
            "description": "Names of the encrypted headers that are sent with the post request. Only the header names are returned; the values are never disclosed. Maximum combined size: 2048 bytes (total of all encrypted header names and values)."
          },
          "disabledReasonCode": {
            "type": "string",
            "readOnly": true,
            "description": "The unique code for the reason"
          },
          "enableCloudEventDelivery": {
            "type": "boolean",
            "example": true,
            "description": "Whether this webhook delivers events as CloudEvents. Once enabled, it cannot be disabled."
          },
          "checkCertificateRevocation": {
            "type": "boolean",
            "default": false,
            "description": "If enabled the certificate chain of the configured URL will be checked for revocation before sending the webhook."
          }
        }
      }
    }
  },
  "servers": [
    {
      "url": "https://{tenant}.{region}.qlikcloud.com",
      "variables": {
        "region": {
          "default": "us",
          "description": "The region the tenant is hosted in"
        },
        "tenant": {
          "default": "your-tenant",
          "description": "Name of the tenant that will be called"
        }
      }
    }
  ]
}