# POST /api/webhooks > Webhooks - Add New Webhook Creates a webhook subscription and mints its signing secret. The secret is returned in this response and in no other response, ever. Store it now: no endpoint can show it again. If it is lost, rotate it with a PUT that sets rotate_secret to true. Every delivery is a JSON POST carrying the header X-Rise-Signature: t=,v1= . Verify it by recomputing the HMAC over the exact bytes you received, comparing in constant time, and rejecting a t outside your own tolerance window - that is what makes a captured delivery unreplayable. The target URL is validated exactly as you send it, so percent-encoded characters and multi-parameter query strings are preserved and accepted - https://hooks.example.com/rise?env=production&team=ops%2Feu is a valid target and is stored byte for byte. It is checked against the SSRF policy: it must be a well formed absolute URL, only http and https are accepted, the host is resolved, and the request is refused when any resolved address is loopback, link-local or cloud metadata (169.254.0.0/16), an RFC1918 private range (10/8, 172.16/12, 192.168/16), carrier-grade NAT, multicast, broadcast, or an IPv6 equivalent. The same check runs again immediately before every delivery, redirects are never followed, and TLS certificate verification is always enforced. Delivery is asynchronous. A matching event is written to the delivery queue while the CRM operation that produced it returns immediately, and the queued deliveries are sent by the RISE cron job - so a slow or unreachable receiver can never slow down or break the CRM. A failed delivery is retried with exponential backoff over the next few cron runs; every attempt, successful or not, appears in the delivery log of this webhook. If deliveries are queued but nothing ever arrives, check that the RISE cron job is configured and running. - **Endpoint:** `POST /api/webhooks` - **Group:** Webhooks - **Since:** v1.0.0 - **Defined in:** `RestApi/Controllers/WebhooksController.php` ## Headers | Field | Type | Description | | --- | --- | --- | | `authtoken` | String | Authentication token, generated from admin area | ## Parameters | Field | Type | Required | Description | | --- | --- | --- | --- | | `name` | String | yes | Mandatory Human readable name, up to 191 characters | | `url` | String | yes | Mandatory Target URL, http or https, public host, up to 500 characters | | `events` | String[] | yes | Mandatory Event names to subscribe to. Accepts an array or a comma separated string. Use * for everything or .* for one resource. See GET /api/webhooks/events | | `headers` | Object | no | Optional Extra request headers to send, up to 20. A name may use letters, digits, hyphens and underscores and must start with a letter or a digit; a value must be printable ASCII of at most 255 characters. Transport and signature headers cannot be overridden | | `active` | Number | no | Optional 1 to start delivering immediately, 0 to create it disabled Default: `1`. | | `timeout` | Number | no | Optional Per attempt timeout in seconds, 1 to 30 Default: `10`. | | `retry_count` | Number | no | Optional Extra attempts after a failed one, 0 to 3 Default: `1`. | | `created_by` | Number | no | Optional User ID to credit the record to, validated against the users table | ## Request example ```bash curl -X POST "https://yoursite.com/index.php/api/webhooks" \ -H "authtoken: YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "...", "url": "...", "events": "..." }' ``` ## Responses ### Success - Success-Response: ```json HTTP/1.1 201 Created { "status": 200, "messages": { "success": "Record saved" }, "id": 3, "secret": "whsec_4f3a00000000000000000000000000000000000000000000000000000000009c1", "secret_notice": "Store this secret now. It is shown once and cannot be retrieved again.", "signature_header": "X-Rise-Signature", "data": { "id": 3, "name": "Ops sync", "url": "https://hooks.example.com/rise", "events": ["invoices.created", "tickets.*"], "active": 1, "has_secret": true } } ``` ### Error - Validation-Error: ```json HTTP/1.1 400 Bad Request { "status": false, "messages": { "url": "URL rejected: the host resolves to 127.0.0.1 (loopback, link-local or otherwise reserved address)", "events": "Unknown events: invoice_created. See GET /api/webhooks/events for the catalogue." } } ``` --- Part of the [REST API for RISE CRM](https://risecrm.themesic.com/apiguide/) documentation. Full page: https://risecrm.themesic.com/apiguide/webhooks/create-webhook/