openapi: 3.0.3
info:
  title: SOAT Webhooks API
  version: 1.0.0
  description: API for managing webhooks for project events
  contact:
    name: SOAT Team
    url: https://github.com/ttoss/soat
servers:
  - url: '{baseUrl}'
    description: Base URL of your SOAT deployment (e.g. https://your-soat.com or http://localhost:5047)
    variables:
      baseUrl:
        description: The base URL of your SOAT deployment
        default: http://localhost:5047
tags:
  - name: Webhooks
    description: Manage webhooks
security:
  - bearerAuth: []
paths:
  /api/v1/projects/{project_id}/webhooks:
    get:
      description: Lists all webhooks configured for the specified project
      tags:
        - Webhooks
      summary: List webhooks for a project
      operationId: listWebhooks
      parameters:
        - name: project_id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: A list of webhooks
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Webhook'
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
    post:
      description: Creates a new webhook for the specified project
      tags:
        - Webhooks
      summary: Create a webhook
      operationId: createWebhook
      parameters:
        - name: project_id
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateWebhookRequest'
      responses:
        '201':
          description: Webhook created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookWithSecret'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden

  /api/v1/projects/{project_id}/webhooks/{webhook_id}:
    get:
      description: Retrieves the details of a specific webhook
      tags:
        - Webhooks
      summary: Get a webhook
      operationId: getWebhook
      parameters:
        - name: project_id
          in: path
          required: true
          schema:
            type: string
        - name: webhook_id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Webhook details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Webhook'
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Webhook not found
    put:
      description: Updates an existing webhook's configuration
      tags:
        - Webhooks
      summary: Update a webhook
      operationId: updateWebhook
      parameters:
        - name: project_id
          in: path
          required: true
          schema:
            type: string
        - name: webhook_id
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateWebhookRequest'
      responses:
        '200':
          description: Webhook updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Webhook'
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Webhook not found
    delete:
      description: Deletes a webhook and stops all event deliveries
      tags:
        - Webhooks
      summary: Delete a webhook
      operationId: deleteWebhook
      parameters:
        - name: project_id
          in: path
          required: true
          schema:
            type: string
        - name: webhook_id
          in: path
          required: true
          schema:
            type: string
      responses:
        '204':
          description: Webhook deleted
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Webhook not found

  /api/v1/projects/{project_id}/webhooks/{webhook_id}/deliveries:
    get:
      description: Lists all event deliveries for a specific webhook
      tags:
        - Webhooks
      summary: List deliveries for a webhook
      operationId: listWebhookDeliveries
      parameters:
        - name: project_id
          in: path
          required: true
          schema:
            type: string
        - name: webhook_id
          in: path
          required: true
          schema:
            type: string
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            default: 50
        - name: offset
          in: query
          required: false
          schema:
            type: integer
            default: 0
      responses:
        '200':
          description: A list of deliveries
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeliveryListResponse'
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Webhook not found

  /api/v1/projects/{project_id}/webhooks/{webhook_id}/deliveries/{delivery_id}:
    get:
      description: Retrieves the details of a specific webhook delivery
      tags:
        - Webhooks
      summary: Get a delivery
      operationId: getWebhookDelivery
      parameters:
        - name: project_id
          in: path
          required: true
          schema:
            type: string
        - name: webhook_id
          in: path
          required: true
          schema:
            type: string
        - name: delivery_id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Delivery details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Delivery'
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Delivery not found

  /api/v1/projects/{project_id}/webhooks/{webhook_id}/rotate-secret:
    post:
      description: Rotates the secret key for the specified webhook
      tags:
        - Webhooks
      summary: Rotate webhook secret
      operationId: rotateWebhookSecret
      parameters:
        - name: project_id
          in: path
          required: true
          schema:
            type: string
        - name: webhook_id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Secret rotated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookWithSecret'
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Webhook not found

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: JWT token or sk_ api key
  schemas:
    Webhook:
      type: object
      properties:
        id:
          type: string
        project_id:
          type: string
        policy_id:
          type: string
          nullable: true
        name:
          type: string
        description:
          type: string
          nullable: true
        url:
          type: string
        events:
          type: array
          items:
            type: string
        active:
          type: boolean
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time

    WebhookWithSecret:
      allOf:
        - $ref: '#/components/schemas/Webhook'
        - type: object
          properties:
            secret:
              type: string

    CreateWebhookRequest:
      type: object
      required:
        - name
        - url
        - events
      properties:
        name:
          type: string
        description:
          type: string
        url:
          type: string
        events:
          type: array
          items:
            type: string
        policy_id:
          type: string

    UpdateWebhookRequest:
      type: object
      properties:
        name:
          type: string
        description:
          type: string
        url:
          type: string
        events:
          type: array
          items:
            type: string
        active:
          type: boolean
        policy_id:
          type: string
          nullable: true

    Delivery:
      type: object
      properties:
        id:
          type: string
        event_type:
          type: string
        payload:
          type: object
        status:
          type: string
          enum:
            - pending
            - success
            - failed
        status_code:
          type: integer
          nullable: true
        attempts:
          type: integer
        last_attempt_at:
          type: string
          format: date-time
          nullable: true
        response_body:
          type: string
          nullable: true
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time

    DeliveryListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Delivery'
        total:
          type: integer
        limit:
          type: integer
        offset:
          type: integer
