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

# Ensure Webhook Endpoint

> Create or update a webhook endpoint by URL. This endpoint is designed for idempotent setup flows where applications need to safely create or reconcile a webhook endpoint. For existing endpoints, Clink does not return the stored plaintext signing secret unless the secret is rotated.



## OpenAPI

````yaml PUT /webhook/endpoints/ensure
openapi: 3.1.0
info:
  title: Clink API
  description: >-
    Official API documentation for Clink's payment processing platform. This API
    enables merchants to create and manage payment sessions, handle
    subscriptions, and process transactions.
  version: 1.0.0
servers:
  - url: https://uat-api.clinkbill.com/api/
security:
  - ApiKeyAuth: []
    timestamp: []
paths:
  /webhook/endpoints/ensure:
    put:
      summary: Ensure Webhook Endpoint
      description: >-
        Create or update a webhook endpoint by URL. This endpoint is designed
        for idempotent setup flows where applications need to safely create or
        reconcile a webhook endpoint. For existing endpoints, Clink does not
        return the stored plaintext signing secret unless the secret is rotated.
      operationId: ensureWebhookEndpoint
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookEndpointEnsureRequest'
            examples:
              example:
                value:
                  url: https://example.com/api/clink/webhook
                  events:
                    - session.complete
                    - order.succeeded
                  description: Created through the API
                  enabled: true
                  returnSigningSecret: true
                  rotateSecretIfUnavailable: true
                  rotateSecret: false
      responses:
        '200':
          description: Webhook endpoint ensured successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RWebhookEndpointEnsureResponse'
              examples:
                example:
                  value:
                    code: 200
                    msg: Success
                    data:
                      source: created
                      endpoint:
                        id: whk_xxxxx
                        url: https://example.com/api/clink/webhook
                        events:
                          - session.complete
                          - order.succeeded
                        enabled: true
                        signingSecret: whsec_xxxxx
                        maskedSigningSecret: whsec_...abcd
                        description: Created through the API
                        createdAt: 1782112780956
                        updatedAt: 1782112780956
                      signingSecretAvailable: true
                      signingSecretUnavailableReason: null
                      nextAction: null
            '*/*':
              schema:
                $ref: '#/components/schemas/RWebhookEndpointEnsureResponse'
        '400':
          description: >-
            Invalid URL, unsupported event name, duplicate URL, or invalid
            request body
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ClinkErrorResponse'
        '401':
          description: Missing or invalid API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ClinkErrorResponse'
components:
  schemas:
    WebhookEndpointEnsureRequest:
      type: object
      required:
        - url
        - events
      properties:
        url:
          type: string
          format: uri
          maxLength: 512
          description: HTTPS endpoint URL. Used as the idempotency key for this merchant.
          example: https://example.com/api/clink/webhook
        events:
          type: array
          minItems: 1
          description: Event names to subscribe to. Numeric event codes are not accepted.
          items:
            $ref: '#/components/schemas/WebhookEventName'
          example:
            - session.complete
            - order.succeeded
        description:
          type: string
          maxLength: 512
          description: Optional endpoint description.
          example: Created through the API
        enabled:
          type: boolean
          default: true
          description: Whether the endpoint is enabled.
        returnSigningSecret:
          type: boolean
          description: Whether the caller wants a plaintext signingSecret when available.
        rotateSecretIfUnavailable:
          type: boolean
          description: >-
            If true, rotate the existing secret when the stored secret cannot be
            returned as plaintext.
        rotateSecret:
          type: boolean
          description: If true, always rotate the signing secret for an existing endpoint.
    RWebhookEndpointEnsureResponse:
      type: object
      properties:
        code:
          type: integer
          description: Response status code, 200 when success
          format: int32
          example: 200
        msg:
          type: string
          description: Brief description of what happened, 'success' when happy case
          example: Success
        data:
          $ref: '#/components/schemas/WebhookEndpointEnsureResponse'
      description: Body of the response message
    ClinkErrorResponse:
      type: object
      properties:
        code:
          type: integer
          format: int32
          description: Error code returned by Clink.
        msg:
          type: string
          description: Error message.
        data:
          description: Additional error data, usually null.
    WebhookEventName:
      type: string
      description: >-
        Supported webhook event name. Public API requests use event names, not
        numeric event codes.
      enum:
        - order.created
        - order.succeeded
        - order.failed
        - refund.created
        - refund.succeeded
        - refund.failed
        - subscription.created
        - subscription.trialing
        - subscription.activated
        - subscription.incomplete_expired
        - subscription.past_due
        - subscription.cancelled
        - invoice.open
        - invoice.paid
        - invoice.void
        - order.next_action
        - subscription.updated.plan_changed
        - subscription.updated.plan_change_canceled
        - subscription.updated.renewed
        - subscription.updated.cancel_at_period_end_set
        - subscription.updated.cancel_at_period_end_revoked
        - session.complete
        - session.expired
        - dispute.created
        - dispute.updated
        - dispute.won
        - dispute.lost
        - dispute.closed
        - customer.verify
        - payment_method.added
        - payment_method.default_change
        - risk_rule.updated
        - agent_order.succeeded
        - agent_order.failed
        - agent_refund.succeeded
        - agent_refund.failed
        - agent_refund.approved
        - agent_refund.rejected
        - payment_method.update
        - purchase_instruction.created
        - purchase_instruction.activated
        - purchase_instruction.updated
        - purchase_instruction.cancelled
        - vic_device.binding_succeeded
    WebhookEndpointEnsureResponse:
      type: object
      properties:
        source:
          $ref: '#/components/schemas/WebhookEndpointEnsureSource'
        endpoint:
          $ref: '#/components/schemas/WebhookEndpointResponse'
        signingSecretAvailable:
          type: boolean
          description: >-
            Whether endpoint.signingSecret contains a plaintext signing secret
            in this response.
          example: true
        signingSecretUnavailableReason:
          type:
            - string
            - 'null'
          description: >-
            Reason the plaintext signing secret is unavailable. Null when not
            applicable.
          enum:
            - EXISTING_SECRET_NOT_RETURNABLE
            - null
          example: EXISTING_SECRET_NOT_RETURNABLE
        nextAction:
          type:
            - string
            - 'null'
          description: >-
            Suggested next action when the plaintext signing secret is
            unavailable. Null when not applicable.
          enum:
            - >-
              CALL_ROTATE_SECRET_OR_RETRY_ENSURE_WITH_ROTATE_SECRET_IF_UNAVAILABLE
            - null
          example: CALL_ROTATE_SECRET_OR_RETRY_ENSURE_WITH_ROTATE_SECRET_IF_UNAVAILABLE
    WebhookEndpointEnsureSource:
      type: string
      description: How the ensure request affected the endpoint.
      enum:
        - created
        - existing
        - updated
        - rotated
        - updated_rotated
    WebhookEndpointResponse:
      type: object
      properties:
        id:
          type: string
          description: Unique identifier of the webhook endpoint.
          example: whk_xxxxx
        url:
          type: string
          format: uri
          description: HTTPS URL that receives webhook events.
          example: https://example.com/api/clink/webhook
        events:
          type: array
          description: >-
            Event names subscribed by this endpoint. Responses always return
            event names.
          items:
            $ref: '#/components/schemas/WebhookEventName'
          example:
            - session.complete
            - order.succeeded
        enabled:
          type: boolean
          description: Whether this endpoint is active.
          example: true
        signingSecret:
          type:
            - string
            - 'null'
          description: >-
            Plaintext signing secret. Returned only when a secret is newly
            created or rotated; otherwise null.
          example: whsec_xxxxx
        maskedSigningSecret:
          type:
            - string
            - 'null'
          description: Masked signing secret for display.
          example: whsec_...abcd
        description:
          type:
            - string
            - 'null'
          description: Optional endpoint description.
          example: Created through the API
        createdAt:
          type:
            - integer
            - 'null'
          format: int64
          description: Creation time as a 13-digit Unix timestamp in milliseconds.
          example: 1782112780956
        updatedAt:
          type:
            - integer
            - 'null'
          format: int64
          description: Last update time as a 13-digit Unix timestamp in milliseconds.
          example: 1782113780956
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-KEY
      description: >-
        Your secret API key obtained from the Clink dashboard (Developers
        section)
    timestamp:
      type: apiKey
      in: header
      name: X-Timestamp
      description: >-
        Current timestamp in milliseconds since Unix epoch (required for request
        signing)

````