Skip to content

Set Up Webhooks

This guide walks you through creating, configuring, and testing webhook subscriptions using the Quinyx Webhooks API. You will learn how to register a webhook endpoint, enable event types, authenticate deliveries, and verify that your integration receives event notifications successfully.


1. Create a subscription

To start receiving webhook events, you first need to create a subscription. In this example, we will register a webhook protected with Basic Authentication.

Use the Webhooks API:

curl -X POST "https://api.eu.quinyx.com/events/v3/webhooks" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '
    {
      "description": "My first webhook",
      "enabled": false,
      "events": [
        "scheduling.shifts.updated.v1"
      ],
      "url": "https://acme-corporation.com/webhooks/quinyx",
      "authorization": {
        "type": "BASIC",
        "basicAuthParameters": {
          "username": "webhook_user",
          "password": "SuperSecurePassword!"
        }
      }
    }
  '

Note: Sensitive fields such as password are returned only at creation time and will not be exposed again.

Response

{
  "id": "83c5aafd-e3b5-4d67-8292-4bbc22fdec8c",
  "description": "My first webhook",
  "enabled": false,
  "events": [
    "scheduling.shifts.updated.v1",
  ],
  "url": "https://acme-corporation.com/webhooks/quinyx",
  "authorization": {
    "type": "BASIC",
    "basicAuthParameters": {
      "username": "webhook_user",
      "password": "SuperSecurePassword!"
    }
  },
  "created": "2025-09-25T13:52:00",
  "updated": "2025-09-25T13:52:00"
}

2. Implement a Webhook Handler

Next, create an HTTP endpoint capable of receiving POST requests from Quinyx. Below is a Python example using Flask:

from flask import Flask, request, abort
import base64
import json

app = Flask(__name__)

# Credentials that Quinyx will use when delivering events
EXPECTED_USERNAME = "webhook-user"
EXPECTED_PASSWORD = "supersecret123"


# Encode credentials for comparison
def expected_basic_auth_header():
    token = f"{EXPECTED_USERNAME}:{EXPECTED_PASSWORD}".encode("utf-8")
    return "Basic " + base64.b64encode(token).decode("utf-8")


@app.route("/webhooks/quinyx", methods=["POST"])
def webhook_handler():
    # 1. Validate Basic Auth header
    auth_header = request.headers.get("Authorization")
    if auth_header != expected_basic_auth_header():
        abort(401)

    # 2. Validate content type
    if request.content_type != "application/cloudevent+json":
        abort(415)  # Unsupported Media Type

    # 3. Parse JSON payload
    try:
        event = request.get_json()
    except Exception:
        abort(400)

    # 4. Log event
    print("Received Quinyx event:")
    print(json.dumps(event, indent=2))

    # 5. Acknowledge successful processing
    return "", 200


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8080)

Your handler must:

  • Validate the Authorization header
  • Validate the Content-Type header
  • Parse and process the event
  • Return a 2xx response within ~5 seconds
  • Handle duplicate deliveries safely

3. Enable the webhook

With the handler running, you can now activate the subscription.

curl -X PATCH "https://api.eu.quinyx.com/events/v3/webhooks/83c5aafd-e3b5-4d67-8292-4bbc22fdec8c" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <ACCESS_TOKEN>" \
  -d '{"enabled": true}'

Response

{
  "id": "83c5aafd-e3b5-4d67-8292-4bbc22fdec8c",
  "description": "My first webhook",
  "enabled": true,
  "events": [
    "scheduling.shifts.updated.v1",
  ],
  "url": "https://acme-corporation.com/webhooks/quinyx",
  "authorization": {
    "type": "BASIC"
  },
  "created": "2025-07-14T14:18:41",
  "updated": "2025-07-14T14:18:41"
}

4. Test the integration

To test the integration, Quinyx provides a special event type that can be triggered any time.

curl -X POST "https://api.eu.quinyx.com/events/v3/webhooks/83c5aafd-e3b5-4d67-8292-4bbc22fdec8c" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

If everything is configured correctly, your Python server will print something like:

$ python3 ./webhooks.py
 * Serving Flask app 'webhooks'
 * Debug mode: off
 * Running on all addresses (0.0.0.0)
 * Running on http://127.0.0.1:8080
Press CTRL+C to quit
Received Quinyx event:
{
  "specversion": "1.0",
  "type": "events.webhooks.ping.v1",
  "source": "api.eu.quinyx.com",
  "datacontenttype": "application/json",
  "id": "2b0b3a75-a015-4391-8ecc-4e02aa33f714",
  "time": "2025-11-27T12:00:00Z",
  "data": {
    "ping": "pong"
  }
}
127.0.0.1 - - [28/Nov/2025 01:04:10] "POST /webhooks/quinyx HTTP/1.1" 200 -

This confirms that:

  • The webhook subscription is active
  • Authentication is working
  • Your handler is receiving and parsing webhook deliveries

Next Steps

✅ You are now ready to start receiving real production events.

We recommend:

  • Implementing idempotency so you can handle more than once delivery
  • Offloading heavy processing to background workers
  • Monitoring for deprecated event types