{
  "swagger": "2.0",
  "info": {
    "title": "Integrations service",
    "version": "0.1507.0",
    "description": "Send your API key as a bearer token: `Authorization: Bearer <api key>`."
  },
  "consumes": [
    "application/json"
  ],
  "produces": [
    "application/json"
  ],
  "securityDefinitions": {
    "ApiKey": {
      "type": "apiKey",
      "in": "header",
      "name": "Authorization",
      "description": "Your API key as a bearer token: `Authorization: Bearer <api key>`."
    }
  },
  "security": [
    {
      "ApiKey": []
    }
  ],
  "paths": {
    "/scout/v2/integrations/slack-oauth/init-webhook": {
      "get": {
        "operationId": "IntegrationsService_generateSlackWebhookLink",
        "summary": "Generate Slack webhook link",
        "tags": [
          "Integrations Service"
        ],
        "description": "Generates link to request permissions for Slack bot to join workspaces and use a webhook.",
        "parameters": [
          {
            "name": "workspace",
            "in": "query",
            "type": "string",
            "format": "rid",
            "x-alias": "WorkspaceRid",
            "required": false,
            "description": "The (Nominal) workspace for which the link is valid. If not provided, will use the default workspace for the user's organization, if the default workspace for the organization is configured."
          },
          {
            "name": "isGovSlack",
            "in": "query",
            "type": "boolean",
            "required": false,
            "description": "If true, the link will be generated for a GovSlack workspace. This is required for GovSlack workspaces."
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/GenerateSlackWebhookResponse"
            },
            "x-example": {
              "url": "<url>"
            }
          }
        }
      }
    },
    "/scout/v2/integrations/slack-oauth/redirect": {
      "get": {
        "operationId": "IntegrationsService_createSlackWebhook",
        "summary": "Create Slack webhook",
        "tags": [
          "Integrations Service"
        ],
        "description": "Creates a new Slack integration. Called internally after Slack authorization.",
        "parameters": [
          {
            "name": "code",
            "in": "query",
            "type": "string",
            "required": true,
            "description": "Temporary authorization code issued by Slack."
          },
          {
            "name": "state",
            "in": "query",
            "type": "string",
            "required": true
          }
        ],
        "responses": {
          "204": {
            "description": "No content."
          }
        }
      }
    },
    "/scout/v2/integrations": {
      "post": {
        "operationId": "IntegrationsService_createIntegration",
        "summary": "Create integration",
        "tags": [
          "Integrations Service"
        ],
        "description": "Creates a new integration.",
        "parameters": [
          {
            "name": "createIntegrationRequest",
            "in": "body",
            "schema": {
              "$ref": "#/definitions/CreateIntegrationRequest"
            },
            "required": true,
            "x-example": {
              "name": "<name>",
              "createIntegrationDetails": {
                "type": "createSimpleWebhookDetails",
                "createSimpleWebhookDetails": {
                  "webhook": "<webhook>"
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/Integration"
            },
            "x-example": {
              "rid": "<integration rid>",
              "name": "<name>",
              "description": "<description>",
              "integrationDetails": {
                "type": "slackWebhookIntegration",
                "slackWebhookIntegration": {
                  "teamName": "<team name>",
                  "channel": "<channel>",
                  "channelId": "<channel id>",
                  "slackInstance": "COMMERCIAL"
                }
              },
              "createdAt": "2026-01-01T00:00:00Z",
              "createdBy": "<created by>",
              "isArchived": true
            }
          }
        }
      }
    },
    "/scout/v2/integrations/internal/secure-webhook": {
      "post": {
        "operationId": "IntegrationsService_createSecureWebhookIntegration",
        "summary": "Create secure webhook integration",
        "tags": [
          "Integrations Service"
        ],
        "description": "Creates a new webhook integration with HMAC signing. Returns the integration and the server-generated signing key. The signing key is only returned once — store it securely.",
        "parameters": [
          {
            "name": "request",
            "in": "body",
            "schema": {
              "$ref": "#/definitions/CreateSecureWebhookIntegrationRequest"
            },
            "required": true,
            "x-example": {
              "name": "<name>",
              "integration": {
                "url": "<url>",
                "deliveryConfig": {
                  "defaultRequestTimeoutSeconds": 1,
                  "defaultMaxRetries": 1,
                  "defaultRetryIntervalSeconds": 1,
                  "defaultExponentialBackoff": true,
                  "defaultMaxRetryIntervalSeconds": 1,
                  "defaultDeliveryTimeoutSeconds": 1
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/CreateSecureWebhookIntegrationResponse"
            },
            "x-example": {
              "integration": {
                "rid": "<integration rid>",
                "name": "<name>",
                "description": "<description>",
                "integrationDetails": {
                  "type": "slackWebhookIntegration",
                  "slackWebhookIntegration": {
                    "teamName": "<team name>",
                    "channel": "<channel>",
                    "channelId": "<channel id>",
                    "slackInstance": "COMMERCIAL"
                  }
                },
                "createdAt": "2026-01-01T00:00:00Z",
                "createdBy": "<created by>",
                "isArchived": true
              },
              "signingKey": "<signing key>"
            }
          }
        }
      }
    },
    "/scout/v2/integrations/internal/secure-webhook/{integrationRid}": {
      "post": {
        "operationId": "IntegrationsService_sendSecureWebhookMessage",
        "summary": "Send secure webhook message",
        "tags": [
          "Integrations Service"
        ],
        "description": "Sends a message to a secure webhook integration with HMAC-SHA256 signature. Implements retry logic with exponential backoff based on merged delivery configuration. Request configuration overrides take precedence over integration's stored configuration.",
        "parameters": [
          {
            "name": "integrationRid",
            "in": "path",
            "type": "string",
            "format": "rid",
            "x-alias": "IntegrationRid",
            "required": true
          },
          {
            "name": "request",
            "in": "body",
            "schema": {
              "$ref": "#/definitions/SendSecureWebhookMessageRequest"
            },
            "required": true,
            "x-example": {
              "payload": "<payload>"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/SendSecureWebhookMessageResponse"
            },
            "x-example": {}
          }
        }
      }
    },
    "/scout/v2/integrations/{integrationRid}": {
      "delete": {
        "operationId": "IntegrationsService_deleteIntegration",
        "summary": "Delete integration",
        "tags": [
          "Integrations Service"
        ],
        "description": "Deletes an integration by archiving.",
        "parameters": [
          {
            "name": "integrationRid",
            "in": "path",
            "type": "string",
            "format": "rid",
            "x-alias": "IntegrationRid",
            "required": true
          }
        ],
        "responses": {
          "204": {
            "description": "No content."
          }
        }
      },
      "put": {
        "operationId": "IntegrationsService_updateIntegrationMetadata",
        "summary": "Update integration metadata",
        "tags": [
          "Integrations Service"
        ],
        "description": "Updates the metadata of an integration.",
        "parameters": [
          {
            "name": "integrationRid",
            "in": "path",
            "type": "string",
            "format": "rid",
            "x-alias": "IntegrationRid",
            "required": true
          },
          {
            "name": "request",
            "in": "body",
            "schema": {
              "$ref": "#/definitions/UpdateIntegrationRequest"
            },
            "required": true,
            "x-example": {
              "name": "<name>",
              "description": "<description>"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/Integration"
            },
            "x-example": {
              "rid": "<integration rid>",
              "name": "<name>",
              "description": "<description>",
              "integrationDetails": {
                "type": "slackWebhookIntegration",
                "slackWebhookIntegration": {
                  "teamName": "<team name>",
                  "channel": "<channel>",
                  "channelId": "<channel id>",
                  "slackInstance": "COMMERCIAL"
                }
              },
              "createdAt": "2026-01-01T00:00:00Z",
              "createdBy": "<created by>",
              "isArchived": true
            }
          }
        }
      },
      "get": {
        "operationId": "IntegrationsService_getIntegration",
        "summary": "Get integration",
        "tags": [
          "Integrations Service"
        ],
        "description": "Retrieves an integration with the specified integration RID.",
        "parameters": [
          {
            "name": "integrationRid",
            "in": "path",
            "type": "string",
            "format": "rid",
            "x-alias": "IntegrationRid",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/Integration"
            },
            "x-example": {
              "rid": "<integration rid>",
              "name": "<name>",
              "description": "<description>",
              "integrationDetails": {
                "type": "slackWebhookIntegration",
                "slackWebhookIntegration": {
                  "teamName": "<team name>",
                  "channel": "<channel>",
                  "channelId": "<channel id>",
                  "slackInstance": "COMMERCIAL"
                }
              },
              "createdAt": "2026-01-01T00:00:00Z",
              "createdBy": "<created by>",
              "isArchived": true
            }
          }
        }
      }
    },
    "/scout/v2/integrations/{integrationRid}/details": {
      "put": {
        "operationId": "IntegrationsService_updateIntegrationDetails",
        "summary": "Update integration details",
        "tags": [
          "Integrations Service"
        ],
        "description": "Updates the integration details for an integration. Intended to allow changing webhooks or rotating API keys.",
        "parameters": [
          {
            "name": "integrationRid",
            "in": "path",
            "type": "string",
            "format": "rid",
            "x-alias": "IntegrationRid",
            "required": true
          },
          {
            "name": "request",
            "in": "body",
            "schema": {
              "$ref": "#/definitions/UpdateIntegrationDetailsRequest"
            },
            "required": true,
            "x-example": {
              "updateIntegrationDetails": {
                "type": "simpleWebhook",
                "simpleWebhook": {
                  "webhook": "<webhook>"
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/Integration"
            },
            "x-example": {
              "rid": "<integration rid>",
              "name": "<name>",
              "description": "<description>",
              "integrationDetails": {
                "type": "slackWebhookIntegration",
                "slackWebhookIntegration": {
                  "teamName": "<team name>",
                  "channel": "<channel>",
                  "channelId": "<channel id>",
                  "slackInstance": "COMMERCIAL"
                }
              },
              "createdAt": "2026-01-01T00:00:00Z",
              "createdBy": "<created by>",
              "isArchived": true
            }
          }
        }
      }
    },
    "/scout/v2/integrations/list": {
      "get": {
        "operationId": "IntegrationsService_listIntegrations",
        "summary": "List integrations",
        "tags": [
          "Integrations Service"
        ],
        "description": "Lists all integrations. Archived integrations are not included.",
        "parameters": [
          {
            "name": "workspaces",
            "in": "query",
            "type": "array",
            "items": {
              "type": "string",
              "format": "rid",
              "x-alias": "WorkspaceRid"
            },
            "collectionFormat": "multi",
            "required": false,
            "description": "If supplied, will return only the integrations within the supplied workspaces. If empty will return all integrations for workspaces that the user is permitted to see."
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "type": "array",
              "items": {
                "$ref": "#/definitions/Integration"
              }
            },
            "x-example": [
              {
                "rid": "<integration rid>",
                "name": "<name>",
                "description": "<description>",
                "integrationDetails": {
                  "type": "slackWebhookIntegration",
                  "slackWebhookIntegration": {
                    "teamName": "<team name>",
                    "channel": "<channel>",
                    "channelId": "<channel id>",
                    "slackInstance": "COMMERCIAL"
                  }
                },
                "createdAt": "2026-01-01T00:00:00Z",
                "createdBy": "<created by>",
                "isArchived": true
              }
            ]
          }
        }
      }
    },
    "/scout/v2/integrations/send-message": {
      "post": {
        "operationId": "IntegrationsService_sendMessage",
        "summary": "Send message",
        "tags": [
          "Integrations Service"
        ],
        "description": "Sends a string message to the specified integration from a checklist execution.",
        "parameters": [
          {
            "name": "request",
            "in": "body",
            "schema": {
              "$ref": "#/definitions/SendMessageRequest"
            },
            "required": true,
            "x-example": {
              "message": "<message>",
              "integrationRid": "<integration rid>"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No content."
          }
        }
      }
    },
    "/scout/v2/integrations/internal/{integrationRid}/rotate-signing-key": {
      "post": {
        "operationId": "IntegrationsService_rotateSecureWebhookIntegrationSigningKey",
        "summary": "Rotate secure webhook integration signing key",
        "tags": [
          "Integrations Service"
        ],
        "description": "Rotates the HMAC signing key for a webhook integration. The old key is immediately invalidated and a new key is generated and returned. This is the only way to retrieve the signing key after initial creation.",
        "parameters": [
          {
            "name": "integrationRid",
            "in": "path",
            "type": "string",
            "format": "rid",
            "x-alias": "IntegrationRid",
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/RotateWebhookSigningKeyResponse"
            },
            "x-example": {
              "signingKey": "<signing key>"
            }
          }
        }
      }
    }
  },
  "definitions": {
    "Priority": {
      "type": "string",
      "enum": [
        "P0",
        "P1",
        "P2",
        "P3",
        "P4"
      ]
    },
    "CreateIntegrationDetails": {
      "type": "object",
      "x-union": true,
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "createSimpleWebhookDetails",
            "createOpsgenieIntegrationDetails",
            "createTeamsWebhookIntegrationDetails",
            "createPagerDutyIntegrationDetails"
          ]
        },
        "createSimpleWebhookDetails": {
          "$ref": "#/definitions/CreateSimpleWebhookDetails"
        },
        "createOpsgenieIntegrationDetails": {
          "$ref": "#/definitions/CreateOpsgenieIntegrationDetails"
        },
        "createTeamsWebhookIntegrationDetails": {
          "$ref": "#/definitions/CreateTeamsWebhookIntegrationDetails"
        },
        "createPagerDutyIntegrationDetails": {
          "$ref": "#/definitions/CreatePagerDutyIntegrationDetails"
        }
      },
      "required": [
        "type"
      ],
      "description": "Set `type` to the name of one of the other fields, and set only that field.",
      "example": {
        "type": "createSimpleWebhookDetails",
        "createSimpleWebhookDetails": {
          "webhook": "string",
          "secret": "string",
          "contentType": "APPLICATION_JSON",
          "timeoutSeconds": 1,
          "customHeaders": {
            "key": "string"
          }
        }
      }
    },
    "CreateIntegrationRequest": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "description": {
          "type": "string"
        },
        "createIntegrationDetails": {
          "$ref": "#/definitions/CreateIntegrationDetails"
        },
        "workspace": {
          "type": "string",
          "format": "rid",
          "x-alias": "WorkspaceRid",
          "description": "The workspace in which to create the integration. If not provided, the integration will be created in the default workspace for the user's organization, if the default workspace for the organization is configured."
        }
      },
      "required": [
        "name",
        "createIntegrationDetails"
      ],
      "example": {
        "name": "<name>",
        "createIntegrationDetails": {
          "type": "createSimpleWebhookDetails",
          "createSimpleWebhookDetails": {
            "webhook": "<webhook>"
          }
        }
      }
    },
    "CreateOpsgenieIntegrationDetails": {
      "type": "object",
      "properties": {
        "apiKey": {
          "type": "string"
        },
        "region": {
          "$ref": "#/definitions/OpsgenieRegion"
        }
      },
      "required": [
        "apiKey",
        "region"
      ]
    },
    "CreatePagerDutyIntegrationDetails": {
      "type": "object",
      "properties": {
        "routingKey": {
          "type": "string"
        }
      },
      "required": [
        "routingKey"
      ]
    },
    "CreateSecureWebhookIntegrationRequest": {
      "description": "Configuration for creating an advanced webhook integration. Signing key is generated by the server.",
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "description": {
          "type": "string"
        },
        "workspace": {
          "type": "string",
          "format": "rid",
          "x-alias": "WorkspaceRid",
          "description": "The workspace in which to create the integration. If not provided, the integration will be created in the default workspace for the user's organization, if the default workspace for the organization is configured."
        },
        "integration": {
          "$ref": "#/definitions/SecureWebhookIntegration"
        }
      },
      "required": [
        "name",
        "integration"
      ],
      "example": {
        "name": "<name>",
        "integration": {
          "url": "<url>",
          "deliveryConfig": {
            "defaultRequestTimeoutSeconds": 1,
            "defaultMaxRetries": 1,
            "defaultRetryIntervalSeconds": 1,
            "defaultExponentialBackoff": true,
            "defaultMaxRetryIntervalSeconds": 1,
            "defaultDeliveryTimeoutSeconds": 1
          }
        }
      }
    },
    "CreateSecureWebhookIntegrationResponse": {
      "description": "Response returned when creating a webhook integration. Contains the full integration object and the server-generated HMAC signing key. The signing key is only returned at creation time — store it securely.",
      "type": "object",
      "properties": {
        "integration": {
          "$ref": "#/definitions/Integration"
        },
        "signingKey": {
          "type": "string",
          "description": "Server-generated HMAC-SHA256 signing key (256-bit, base64-encoded). Store this securely in your secrets manager (e.g., AWS Secrets Manager, HashiCorp Vault). This key cannot be retrieved again - if you lose it, use rotateSecureWebhookIntegrationSigningKey to generate a new one."
        }
      },
      "required": [
        "integration",
        "signingKey"
      ]
    },
    "CreateSimpleWebhookDetails": {
      "type": "object",
      "properties": {
        "webhook": {
          "type": "string",
          "description": "Webhook URL (must be HTTPS in production)"
        },
        "secret": {
          "type": "string",
          "description": "Optional secret for HMAC-SHA256 signing (recommended)"
        },
        "contentType": {
          "allOf": [
            {
              "$ref": "#/definitions/WebhookContentType"
            }
          ],
          "description": "Content-Type for requests (default: application/json)"
        },
        "timeoutSeconds": {
          "type": "integer",
          "format": "int32",
          "description": "HTTP request timeout in seconds (default: 30, max: 120)"
        },
        "customHeaders": {
          "type": "object",
          "additionalProperties": {
            "type": "string"
          },
          "description": "Additional headers to include in all requests. Do not put API keys, tokens, or other secrets in custom headers."
        }
      },
      "required": [
        "webhook"
      ]
    },
    "CreateTeamsWebhookIntegrationDetails": {
      "type": "object",
      "properties": {
        "webhook": {
          "type": "string"
        }
      },
      "required": [
        "webhook"
      ]
    },
    "GenerateSlackWebhookResponse": {
      "type": "object",
      "properties": {
        "url": {
          "type": "string"
        }
      },
      "required": [
        "url"
      ]
    },
    "Integration": {
      "description": "Configuration details used to connect to an external service.",
      "type": "object",
      "properties": {
        "rid": {
          "type": "string",
          "format": "rid",
          "x-alias": "IntegrationRid"
        },
        "name": {
          "type": "string"
        },
        "description": {
          "type": "string"
        },
        "integrationDetails": {
          "$ref": "#/definitions/IntegrationDetails"
        },
        "createdAt": {
          "type": "string",
          "format": "date-time"
        },
        "createdBy": {
          "type": "string",
          "format": "rid"
        },
        "isArchived": {
          "type": "boolean"
        }
      },
      "required": [
        "rid",
        "name",
        "integrationDetails",
        "createdAt",
        "createdBy",
        "isArchived"
      ]
    },
    "IntegrationDetails": {
      "type": "object",
      "x-union": true,
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "slackWebhookIntegration",
            "opsgenieIntegration",
            "simpleWebhookIntegration",
            "secureWebhookIntegration",
            "teamsWebhookIntegration",
            "pagerDutyIntegration"
          ]
        },
        "slackWebhookIntegration": {
          "$ref": "#/definitions/SlackWebhookIntegration"
        },
        "opsgenieIntegration": {
          "$ref": "#/definitions/OpsgenieIntegration"
        },
        "simpleWebhookIntegration": {
          "$ref": "#/definitions/SimpleWebhookIntegration"
        },
        "secureWebhookIntegration": {
          "$ref": "#/definitions/SecureWebhookIntegration"
        },
        "teamsWebhookIntegration": {
          "$ref": "#/definitions/TeamsWebhookIntegration"
        },
        "pagerDutyIntegration": {
          "$ref": "#/definitions/PagerDutyIntegration"
        }
      },
      "required": [
        "type"
      ],
      "description": "Set `type` to the name of one of the other fields, and set only that field.",
      "example": {
        "type": "slackWebhookIntegration",
        "slackWebhookIntegration": {
          "teamName": "string",
          "channel": "string",
          "channelId": "string",
          "slackInstance": "COMMERCIAL"
        }
      }
    },
    "OpsgenieIntegration": {
      "type": "object",
      "properties": {
        "region": {
          "$ref": "#/definitions/OpsgenieRegion"
        }
      },
      "required": [
        "region"
      ]
    },
    "OpsgenieRegion": {
      "description": "Opsgenie region for the account linked to the provided API key.",
      "type": "string",
      "enum": [
        "US",
        "EU"
      ]
    },
    "PagerDutyIntegration": {
      "type": "object",
      "properties": {}
    },
    "RotateWebhookSigningKeyResponse": {
      "description": "Response when rotating a webhook integration's signing key. This is the only way to retrieve the signing key after initial creation.",
      "type": "object",
      "properties": {
        "signingKey": {
          "type": "string",
          "description": "New HMAC-SHA256 signing key (256-bit, base64-encoded). The old key is immediately invalidated. Store this securely - update your application configuration with the new key before the next webhook delivery."
        }
      },
      "required": [
        "signingKey"
      ]
    },
    "SecureWebhookIntegration": {
      "description": "Advanced webhook integration with HMAC signing, custom headers, and configurable defaults.\n\nServer-side validation enforces:\n- URL must use HTTPS protocol\n- customHeaders blocklist (see customHeaders field documentation)",
      "type": "object",
      "properties": {
        "url": {
          "type": "string",
          "description": "Webhook URL (must be HTTPS)"
        },
        "customHeaders": {
          "type": "object",
          "additionalProperties": {
            "type": "string"
          },
          "description": "Additional HTTP headers to include in all webhook requests. Do not put API keys, tokens, or other secrets in custom headers. Server-side validation rejects security-sensitive headers to prevent credential leakage: Authorization, Cookie, X-API-Key, X-Auth-Token, Proxy-Authorization, and any header starting with X-Nominal-. Validation returns clear error messages for blocked headers."
        },
        "deliveryConfig": {
          "allOf": [
            {
              "$ref": "#/definitions/WebhookDeliveryConfig"
            }
          ],
          "description": "Retry and timeout configuration for webhook delivery attempts"
        }
      },
      "required": [
        "url",
        "deliveryConfig"
      ]
    },
    "SendMessageRequest": {
      "type": "object",
      "properties": {
        "title": {
          "type": "string",
          "description": "Optional title for the message. 130 characters max."
        },
        "message": {
          "type": "string"
        },
        "tags": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "20 tags max, 50 characters max each. Tags are used to filter messages in Opsgenie. For other integrations, tags are ignored."
        },
        "opsGenieAlias": {
          "type": "string",
          "description": "Alias to use for the Opsgenie alert deduplication. 512 characters max."
        },
        "integrationRid": {
          "type": "string",
          "format": "rid",
          "x-alias": "IntegrationRid"
        },
        "priority": {
          "$ref": "#/definitions/Priority"
        }
      },
      "required": [
        "message",
        "integrationRid"
      ],
      "example": {
        "message": "<message>",
        "integrationRid": "<integration rid>"
      }
    },
    "SendSecureWebhookMessageRequest": {
      "description": "Request to send a message via secure webhook with optional per-request overrides. Request overrides take precedence over integration's stored configuration.",
      "type": "object",
      "properties": {
        "payload": {
          "type": "string",
          "description": "JSON payload to send. Will be signed with HMAC-SHA256 using the integration's signing key. Validated before signing to ensure well-formed JSON."
        },
        "customHeaders": {
          "type": "object",
          "additionalProperties": {
            "type": "string"
          },
          "description": "Optional custom headers to override integration's stored customHeaders for this request. Must not include blocked headers (Authorization, Cookie, X-API-Key, X-Auth-Token, Proxy-Authorization, X-Nominal-*). Merged with integration headers, request overrides take precedence."
        },
        "deliveryConfig": {
          "allOf": [
            {
              "$ref": "#/definitions/WebhookDeliveryConfig"
            }
          ],
          "description": "Optional delivery configuration to override integration's stored deliveryConfig for this request. Merged with integration config, request overrides take precedence. Cross-field constraints (e.g., maxRetryInterval >= retryInterval) validated on merged result."
        }
      },
      "required": [
        "payload"
      ],
      "example": {
        "payload": "<payload>"
      }
    },
    "SendSecureWebhookMessageResponse": {
      "description": "Response indicating successful webhook delivery. Errors are thrown as exceptions rather than encoded in response.",
      "type": "object",
      "properties": {}
    },
    "SimpleWebhookIntegration": {
      "type": "object",
      "properties": {
        "hmacSecretRid": {
          "type": "string",
          "format": "rid",
          "description": "Optional RID of secret containing HMAC-SHA256 signing key"
        },
        "contentType": {
          "allOf": [
            {
              "$ref": "#/definitions/WebhookContentType"
            }
          ],
          "description": "Content-Type for requests (default: application/json)"
        },
        "timeoutSeconds": {
          "type": "integer",
          "format": "int32",
          "description": "HTTP request timeout in seconds (default: 30, max: 120)"
        },
        "customHeaders": {
          "type": "object",
          "additionalProperties": {
            "type": "string"
          },
          "description": "Additional headers to include in all requests. Do not put API keys, tokens, or other secrets in custom headers."
        }
      }
    },
    "SlackInstanceType": {
      "type": "string",
      "enum": [
        "COMMERCIAL",
        "GOV"
      ]
    },
    "SlackWebhookIntegration": {
      "type": "object",
      "properties": {
        "teamName": {
          "type": "string"
        },
        "channel": {
          "type": "string"
        },
        "channelId": {
          "type": "string"
        },
        "slackInstance": {
          "$ref": "#/definitions/SlackInstanceType"
        }
      },
      "required": [
        "teamName",
        "channel",
        "channelId"
      ]
    },
    "TeamsWebhookIntegration": {
      "type": "object",
      "properties": {}
    },
    "UpdateIntegrationDetails": {
      "type": "object",
      "x-union": true,
      "properties": {
        "type": {
          "type": "string",
          "enum": [
            "simpleWebhook",
            "secureWebhookIntegration",
            "opsgenieIntegration",
            "teamsWebhook",
            "pagerDuty"
          ]
        },
        "simpleWebhook": {
          "$ref": "#/definitions/UpdateSimpleWebhookDetails"
        },
        "secureWebhookIntegration": {
          "$ref": "#/definitions/UpdateSecureWebhookIntegrationDetails"
        },
        "opsgenieIntegration": {
          "$ref": "#/definitions/UpdateOpsgenieIntegrationDetails"
        },
        "teamsWebhook": {
          "$ref": "#/definitions/UpdateTeamsWebhookIntegrationDetails"
        },
        "pagerDuty": {
          "$ref": "#/definitions/UpdatePagerDutyIntegrationDetails"
        }
      },
      "required": [
        "type"
      ],
      "description": "Set `type` to the name of one of the other fields, and set only that field.",
      "example": {
        "type": "simpleWebhook",
        "simpleWebhook": {
          "webhook": "string",
          "secret": "string",
          "contentType": "APPLICATION_JSON",
          "timeoutSeconds": 1,
          "customHeaders": {
            "key": "string"
          }
        }
      }
    },
    "UpdateIntegrationDetailsRequest": {
      "type": "object",
      "properties": {
        "updateIntegrationDetails": {
          "allOf": [
            {
              "$ref": "#/definitions/UpdateIntegrationDetails"
            }
          ],
          "description": "Includes the information needed to rotate the integration-specific secrets. Examples include unsecured webhook URL or API keys."
        }
      },
      "required": [
        "updateIntegrationDetails"
      ],
      "example": {
        "updateIntegrationDetails": {
          "type": "simpleWebhook",
          "simpleWebhook": {
            "webhook": "<webhook>"
          }
        }
      }
    },
    "UpdateIntegrationRequest": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "description": {
          "type": "string"
        }
      },
      "example": {
        "name": "<name>",
        "description": "<description>"
      }
    },
    "UpdateOpsgenieIntegrationDetails": {
      "type": "object",
      "properties": {
        "apiKey": {
          "type": "string"
        },
        "region": {
          "$ref": "#/definitions/OpsgenieRegion"
        }
      },
      "required": [
        "apiKey",
        "region"
      ]
    },
    "UpdatePagerDutyIntegrationDetails": {
      "type": "object",
      "properties": {
        "routingKey": {
          "type": "string"
        }
      },
      "required": [
        "routingKey"
      ]
    },
    "UpdateSecureWebhookIntegrationDetails": {
      "description": "Configuration for updating an advanced webhook integration. This is a full replacement update - all fields must be provided. Optional retry/timeout fields not provided will be reset to server defaults. Note: To rotate the signing key, use the rotateSecureWebhookIntegrationSigningKey endpoint instead.",
      "type": "object",
      "properties": {
        "url": {
          "type": "string",
          "description": "Webhook URL (must be HTTPS)"
        },
        "customHeaders": {
          "type": "object",
          "additionalProperties": {
            "type": "string"
          },
          "description": "Additional HTTP headers to include in all webhook requests. Do not put API keys, tokens, or other secrets in custom headers. Server-side validation rejects security-sensitive headers to prevent credential leakage: Authorization, Cookie, X-API-Key, X-Auth-Token, Proxy-Authorization, and any header starting with X-Nominal-. Validation returns clear error messages for blocked headers."
        },
        "deliveryConfig": {
          "allOf": [
            {
              "$ref": "#/definitions/WebhookDeliveryConfig"
            }
          ],
          "description": "Retry and timeout configuration for webhook delivery attempts"
        }
      },
      "required": [
        "url",
        "deliveryConfig"
      ]
    },
    "UpdateSimpleWebhookDetails": {
      "type": "object",
      "properties": {
        "webhook": {
          "type": "string",
          "description": "Webhook URL (must be HTTPS in production)"
        },
        "secret": {
          "type": "string",
          "description": "Optional secret for HMAC-SHA256 signing"
        },
        "contentType": {
          "allOf": [
            {
              "$ref": "#/definitions/WebhookContentType"
            }
          ],
          "description": "Content-Type for requests"
        },
        "timeoutSeconds": {
          "type": "integer",
          "format": "int32",
          "description": "HTTP request timeout in seconds"
        },
        "customHeaders": {
          "type": "object",
          "additionalProperties": {
            "type": "string"
          },
          "description": "Additional headers to include in all requests. Do not put API keys, tokens, or other secrets in custom headers."
        }
      },
      "required": [
        "webhook"
      ]
    },
    "UpdateTeamsWebhookIntegrationDetails": {
      "type": "object",
      "properties": {
        "webhook": {
          "type": "string"
        }
      },
      "required": [
        "webhook"
      ]
    },
    "WebhookContentType": {
      "description": "Content-Type for webhook requests",
      "type": "string",
      "enum": [
        "APPLICATION_JSON",
        "APPLICATION_X_WWW_FORM_URLENCODED"
      ],
      "x-enum-descriptions": {
        "APPLICATION_JSON": "application/json",
        "APPLICATION_X_WWW_FORM_URLENCODED": "application/x-www-form-urlencoded"
      }
    },
    "WebhookDeliveryConfig": {
      "description": "Retry parameters serve as integration-level defaults that can be overridden at runtime.\n\nServer-side validation enforces:\n- defaultRequestTimeoutSeconds maximum of 120\n- defaultMaxRetryIntervalSeconds must be >= defaultRetryIntervalSeconds when both are provided",
      "type": "object",
      "properties": {
        "defaultRequestTimeoutSeconds": {
          "type": "integer",
          "format": "int32",
          "description": "Default HTTP request timeout in seconds (server default 10, range 5-120)"
        },
        "defaultMaxRetries": {
          "type": "integer",
          "format": "int32",
          "description": "Default maximum delivery attempts before failing (server default 3, range 0-10)"
        },
        "defaultRetryIntervalSeconds": {
          "type": "integer",
          "format": "int32",
          "description": "Default initial interval between retry attempts in seconds (server default 15, range 5-300)"
        },
        "defaultExponentialBackoff": {
          "type": "boolean",
          "description": "Whether to apply exponential backoff to retry intervals (server default true)"
        },
        "defaultMaxRetryIntervalSeconds": {
          "type": "integer",
          "format": "int32",
          "description": "Default maximum interval between retries when using exponential backoff in seconds (server default 300, range 5-3600)"
        },
        "defaultDeliveryTimeoutSeconds": {
          "type": "integer",
          "format": "int32",
          "description": "Default overall delivery timeout in seconds before giving up (server default 600, range 10-86400)"
        }
      }
    }
  },
  "tags": [
    {
      "name": "Integrations Service",
      "x-displayName": "Integrations service",
      "description": "Service for managing integrations with external services.",
      "x-errors": [
        {
          "status": 400,
          "errorCode": "INVALID_ARGUMENT",
          "errorName": "Scout:SlackIntegrationNotAvailable"
        },
        {
          "status": 404,
          "errorCode": "NOT_FOUND",
          "errorName": "Scout:IntegrationsNotFound"
        },
        {
          "status": 404,
          "errorCode": "NOT_FOUND",
          "errorName": "Scout:IntegrationNotFound"
        },
        {
          "status": 404,
          "errorCode": "NOT_FOUND",
          "errorName": "Scout:IntegrationTokenNotFound"
        },
        {
          "status": 400,
          "errorCode": "INVALID_ARGUMENT",
          "errorName": "Scout:UnsupportedOperationForIntegration"
        },
        {
          "status": 400,
          "errorCode": "INVALID_ARGUMENT",
          "errorName": "Scout:NotImplemented"
        },
        {
          "status": 400,
          "errorCode": "INVALID_ARGUMENT",
          "errorName": "Scout:InvalidWebhookUrl"
        },
        {
          "status": 400,
          "errorCode": "INVALID_ARGUMENT",
          "errorName": "Scout:InvalidWebhookHeaders"
        },
        {
          "status": 400,
          "errorCode": "INVALID_ARGUMENT",
          "errorName": "Scout:InvalidDeliveryConfig"
        }
      ]
    }
  ]
}
