> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flovoo.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a webhook subscription

> The response carries `secret` once and never again. Verify each delivery by computing `HMAC-SHA256("{t}.{raw body}", secret)` and comparing it to the `v1` value in `X-Flovo-Signature` — reject if `t` is more than 5 minutes old. Failed deliveries are retried 6 times with exponential backoff; 12 consecutive failures disable the endpoint.



## OpenAPI

````yaml /api-reference/openapi.json post /v1/webhooks
openapi: 3.0.0
info:
  title: Flovoo API
  description: |-
    Authenticate with an API key created from **Connectors → API**:

    ```
    Authorization: Bearer flv_...
    ```

    The organization is derived from the key, so no request carries an
    organization id.
  version: '1.0'
  contact: {}
servers: []
security: []
tags: []
paths:
  /v1/webhooks:
    post:
      tags:
        - Webhooks
      summary: Create a webhook subscription
      description: >-
        The response carries `secret` once and never again. Verify each delivery
        by computing `HMAC-SHA256("{t}.{raw body}", secret)` and comparing it to
        the `v1` value in `X-Flovo-Signature` — reject if `t` is more than 5
        minutes old. Failed deliveries are retried 6 times with exponential
        backoff; 12 consecutive failures disable the endpoint.
      operationId: PublicWebhooksController_create
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PublicCreateWebhookDoc'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicCreatedWebhookDoc'
        '400':
          description: >-
            The request failed validation. Every failing field is listed in
            `details`, not just the first.
          content:
            application/json:
              example:
                error:
                  type: invalid_request_error
                  code: validation_failed
                  message: The request failed validation.
                  details:
                    - param: phone
                      code: invalid_string
                      message: Invalid phone number format
                  requestId: req_01J8X4M2N9P3Q5R7
        '401':
          description: The key is missing, unknown, or revoked.
          content:
            application/json:
              examples:
                missing:
                  summary: No Authorization header
                  value:
                    error:
                      type: authentication_error
                      code: missing_api_key
                      message: No API key was provided.
                      requestId: req_01J8X4M2N9P3Q5R7
                invalid:
                  summary: Unknown key
                  value:
                    error:
                      type: authentication_error
                      code: invalid_api_key
                      message: The API key provided is not valid.
                      requestId: req_01J8X4M2N9P3Q5R7
                revoked:
                  summary: Revoked key
                  value:
                    error:
                      type: authentication_error
                      code: revoked_api_key
                      message: This API key has been revoked.
                      requestId: req_01J8X4M2N9P3Q5R7
        '403':
          description: The key is valid but lacks the route's scope.
          content:
            application/json:
              example:
                error:
                  type: permission_error
                  code: insufficient_scope
                  message: >-
                    This API key does not have the required scope:
                    contacts.create.
                  requestId: req_01J8X4M2N9P3Q5R7
        '429':
          description: Rate limit exceeded. `Retry-After` gives the seconds to wait.
          content:
            application/json:
              example:
                error:
                  type: rate_limit_error
                  code: rate_limit_exceeded
                  message: >-
                    Rate limit of 300 requests per minute exceeded. Retry in
                    23s.
                  requestId: req_01J8X4M2N9P3Q5R7
        '500':
          description: >-
            An error on our side. The original exception is never returned;
            quote `requestId` to support.
          content:
            application/json:
              example:
                error:
                  type: api_error
                  code: internal_error
                  message: An unexpected error occurred.
                  requestId: req_01J8X4M2N9P3Q5R7
      security:
        - api-key: []
components:
  schemas:
    PublicCreateWebhookDoc:
      type: object
      properties:
        url:
          type: string
          format: uri
        events:
          type: array
          minItems: 1
          items:
            type: string
            enum:
              - message.created
              - message.updated
              - contact.created
              - contact.updated
              - contact.deleted
              - template.status.updated
              - template.quality.updated
              - template.category.updated
              - template.created
              - template.deleted
              - channel.status.updated
              - channel.deleted
              - waba.violation.detected
              - waba.restrictions.updated
              - broadcast.completed
              - broadcast.failed
              - broadcast.deleted
            x-enumNames:
              - MESSAGE_CREATED
              - MESSAGE_UPDATED
              - CONTACT_CREATED
              - CONTACT_UPDATED
              - CONTACT_DELETED
              - TEMPLATE_STATUS_UPDATED
              - TEMPLATE_QUALITY_UPDATED
              - TEMPLATE_CATEGORY_UPDATED
              - TEMPLATE_CREATED
              - TEMPLATE_DELETED
              - CHANNEL_STATUS_UPDATED
              - CHANNEL_DELETED
              - WABA_VIOLATION_DETECTED
              - WABA_RESTRICTIONS_UPDATED
              - BROADCAST_COMPLETED
              - BROADCAST_FAILED
              - BROADCAST_DELETED
      required:
        - url
        - events
    PublicCreatedWebhookDoc:
      type: object
      properties:
        id:
          type: string
          format: uuid
        url:
          type: string
          format: uri
        events:
          type: array
          items:
            type: string
        isActive:
          type: boolean
        lastDeliveryAt:
          type: string
          format: date-time
          nullable: true
        createdAt:
          type: string
          format: date-time
        secret:
          description: Signing secret. Shown once — store it now.
          type: string
      required:
        - id
        - url
        - events
        - isActive
        - lastDeliveryAt
        - createdAt
        - secret
  securitySchemes:
    api-key:
      scheme: bearer
      bearerFormat: JWT
      type: http
      description: Your API key, e.g. flv_9f2a8c1e…

````