Configuring webhooks through the API
Authentication
Section titled “Authentication”The vendors API authenticates with a Bearer token, provided by the Ciklik team. Every request must carry two headers:
Authorization: Bearer <token>Accept: application/jsonThe Accept: application/json header is required. Without it, the server does not recognise the request as an API call: an authentication or validation error then comes back as an HTML redirect, not as a JSON response your code can interpret.
The API is limited to 100 requests per minute and per IP address, not per token: if several integrations go out through the same network address (the same server, the same outbound proxy), they share this quota. Beyond that, the response is a 429 code whose body is not JSON.
On a PrestaShop site, a token is created automatically when the payment module is configured. If you are integrating without a token, ask the Ciklik team for one.
Declaring a receiving URL
Section titled “Declaring a receiving URL”POST https://app.ciklik.co/api/v3/webhooks| Field | Type | Required | Description |
|---|---|---|---|
hook_url | string (URL) | Yes | Receiving URL, syntactically valid |
event_type | string | Yes | Event key, see the event catalogue |
curl -X POST https://app.ciklik.co/api/v3/webhooks \ -H "Authorization: Bearer <token>" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{"hook_url": "https://boutique.example.com/webhooks/ciklik", "event_type": "updated_subscription"}'{ "data": { "id": 1, "host": "boutique.example.com", "name": "Boutique Exemple", "paymentMethods": ["stripe"], "webhooks": { "updated_subscription": "https://boutique.example.com/webhooks/ciklik" }, "metadata": null }}{ "message": "The selected event type is invalid.", "errors": { "event_type": [ "The selected event type is invalid." ] }}Three things to know before integrating:
- a second call on the same
event_typereplaces the previous URL, without warning; - the new URL takes effect within one minute at most;
updated_change_choicesis not accepted by this endpoint: this key is not part of the validated list and returns a 422. It can only be enabled by the Ciklik team.
Removing a receiving URL
Section titled “Removing a receiving URL”DELETE https://app.ciklik.co/api/v3/webhookscurl -X DELETE https://app.ciklik.co/api/v3/webhooks \ -H "Authorization: Bearer <token>" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d '{"event_type": "updated_subscription"}'The response has the same shape as for a declaration: the full webhooks object, without the key you just removed.
Knowing which URLs are declared
Section titled “Knowing which URLs are declared”The POST and DELETE responses already carry the full webhooks object: this is the reliable way to know the state of your configuration after each call. A GET /webhooks endpoint also exists, but its use is discouraged and its result is not guaranteed.
Response codes
Section titled “Response codes”| Code | Meaning | What to do |
|---|---|---|
| 200 | Request processed | - |
| 401 | Authentication required: token missing or invalid | Check the Authorization header |
| 422 | Invalid parameter or unknown event key | Check hook_url and event_type |
| 429 | Per-IP quota exceeded (plain-text body, no JSON) | Space out your calls, stay under 100 requests per minute |
The OpenAPI contract
Section titled “The OpenAPI contract”The /openapi/ciklik-webhooks.yaml file formally describes the whole system: the 18 event keys under webhooks, the three configuration operations described on this page, every object schema used in the payloads, and one complete real example per event key.
Three practical uses:
- load it into an API client (Postman, Insomnia, Bruno) to get the requests ready immediately;
- generate types (TypeScript, PHP) from the contract instead of writing them by hand;
- hand it to a coding assistant so it writes your receiving endpoint directly from the schemas and examples.
See also: Understanding a webhook delivery for the full delivery contract, and Best practices and troubleshooting to secure your receiving URL.